官网

https://plotly.com/

基本介绍

一个基于js的能够用纯Python快速构建的web可视化应用框架。

三个主要部分

  1. 网页布局 2. callback 3. 可视化图

    应用案例

    时间关系,不一一展开讲,主要是将我做的案例记录下来,方便以后查询。

    场景需求:将中国近海的涡旋检测案例发布为web应用,主要涉及到mapbox地图的叠加,以及plotly的简单应用,和dash基本布局。

基本代码结构

  1. #主要依赖
  2. import plotly.express as px # (version 4.7.0)
  3. import plotly.graph_objects as go
  4. import dash # (version 1.12.0) pip install dash
  5. import dash_core_components as dcc
  6. import dash_html_components as html
  7. import dash_bootstrap_components as dbc
  8. from dash.dependencies import Input, Output,State
  9. import pandas as pd
  10. import numpy as np
  11. import xarray as xr
  12. from datetime import date
  13. from Predict import predict_app
  14. app = dash.Dash(__name__) # 设定基本主题,可以去bootstrapwatch下载
  15. #导入基本数据
  16. # 最上方横条
  17. PLOTLY_LOGO = "http://msdc.qdio.ac.cn/static/img/homepage/nav-logo.png"
  18. navbar = dbc.Navbar(
  19. [
  20. html.A(
  21. # Use row and col to control vertical alignment of logo / brand
  22. dbc.Row(
  23. [
  24. dbc.Col(html.Img(src=PLOTLY_LOGO, height="30px",),width=18),
  25. ],
  26. align="center",
  27. no_gutters=True,
  28. ),
  29. href="http://msdc.qdio.ac.cn",
  30. ),
  31. ],
  32. color="dark",
  33. dark=True,
  34. )
  35. # 文字说明部分
  36. jumbotron = dbc.Jumbotron(
  37. [
  38. html.H6("AI涡旋检测", className="display-4"),
  39. html.Hr(className="my-2"),
  40. html.P(
  41. "选择观测的时间, "
  42. "右图预览中国近海识别涡旋。",
  43. className="lead",
  44. ),
  45. html.P(
  46. "可以选择 "
  47. "算法结果或者深度学习AI结果。"
  48. ),
  49. html.P(dbc.Button("Contact us", color="primary",href="http://msdc.qdio.ac.cn",), className="lead"),
  50. ]
  51. )
  52. # 基本布局控件
  53. controls = dbc.Card(
  54. [
  55. dbc.FormGroup(
  56. [
  57. dbc.Label("选择时间:",style={'font-size': 15}),
  58. dcc.Slider(
  59. id = "time_slider",
  60. min=0,
  61. max=list(t.keys())[-2],# t的最后一天
  62. value=list(t.keys())[-2],
  63. included=False,
  64. ),
  65. html.Div(id='slider-output-container',style={'margin-left': 20,'font-size':11}),
  66. html.Hr(className="my-2"),
  67. ]
  68. ),
  69. dbc.FormGroup(
  70. [
  71. dbc.Label("选择涡旋检测算法:",style={'font-size': 15}),
  72. dcc.RadioItems(
  73. id= 'select_type',
  74. options=[
  75. {'label': '算法', 'value': 'ss'},
  76. {'label': '人工智能', 'value': 'ai'},
  77. ],
  78. value='ss',
  79. labelStyle={
  80. # 'display': 'inline-block',
  81. 'margin-right': '7px',
  82. 'font-size': 15
  83. },
  84. style={
  85. 'display': 'inline-block',
  86. 'margin-left': '17px',
  87. 'font-size': 15
  88. }
  89. ),
  90. html.Hr(className="my-2"),
  91. html.Div(id='summary-container1',style={'font-size': 11}),
  92. html.Div(id='summary-container2',style={'font-size': 11}),
  93. ]
  94. ),
  95. ],
  96. body=True,
  97. )
  98. # 汇总到app.layout
  99. app.layout = html.Div([
  100. navbar,
  101. #
  102. dbc.Row([
  103. dbc.Col([
  104. jumbotron,
  105. html.Div(""),
  106. html.P(''),
  107. controls,
  108. ],width={'size': 3,"offset": 1,"order":1},align='center'),
  109. dbc.Col([dcc.Graph(id='contourf', figure={},
  110. )
  111. ],lg={'size': 7, "offset": 1, 'order': 2,},align="center"),
  112. ]),
  113. ])
  114. # 将图与控件联系起来
  115. # 更新时间选择
  116. @app.callback(
  117. Output('slider-output-container', 'children'),
  118. [Input("time_slider", 'value')])
  119. def update_output(value):
  120. return "选择时间点为:{}".format(t[value]['label'])
  121. # 更新综述
  122. @app.callback(
  123. [Output('summary-container1', 'children'),Output('summary-container2', 'children')],
  124. [Input("time_slider", 'value'),Input(component_id='select_type', component_property='value')])
  125. def update_summary(value,type):
  126. if type == 'ai':
  127. method = '人工智能'
  128. else:
  129. method = "传统算法"
  130. return "右图预览的时间点为:{} ".format(t[value]['label']),"使用方法为:{}。".format(method)
  131. # 更新画图
  132. @app.callback(
  133. Output(component_id='contourf', component_property='figure'),
  134. [Input(component_id='select_type', component_property='value'),Input("time_slider", 'value')]
  135. )
  136. def update_contour(option_slctd,value):
  137. print(option_slctd)
  138. print(value)
  139. if option_slctd == 'ai':
  140. #AI预测以及结果
  141. pre_input = model_input[value,:,:]
  142. predict_value = predict_app(pre_input) # 168*168
  143. res_ai = zhuanhuan(lat,lon,predict_value)
  144. fig = px.scatter_mapbox(data_frame=res_ai,lon='lon',lat='lat',color='point',opacity=0.95,zoom=2.7,center={'lat':2.625,'lon':131.125})
  145. else:
  146. # 算法结果
  147. s_value = ground_truth[value,:,:]
  148. res_suanfa = zhuanhuan(lat,lon,s_value)
  149. fig = px.scatter_mapbox(data_frame=res_suanfa,lon='lon',lat='lat',color='point',opacity=0.95,zoom=2.7,center={'lat':2.625,'lon':131.125})
  150. fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0},
  151. hoverlabel=dict(
  152. font_size=12, # label font size
  153. font_family="Inter"
  154. ), # label font
  155. mapbox_style="satellite",#width =11000,
  156. coloraxis_showscale=False,
  157. height = 1100
  158. )
  159. return fig
  160. if __name__ == '__main__':
  161. app.run_server(debug=True,host = '0.0.0.0',port='2151')

呈现效果

Dash-poltly 简介与基础应用 - 图1

Dash主题文件cs下载网址

https://bootswatch.com/ ,下载完之后只要放到项目文件夹下的assets文件夹下即可。

注意事项

  1. 如果我们通过不同的 url去渲染不同的页面的话,会碰到一个问题,就是我们可能会率先定义了回调,而回掉中的组件暂时还没渲染到app.layout中,因此Dash会引发异常以警告我们可能做错了。在这种情况下,我们可以通过设置忽略该异常。即:app.config.suppress_callback_exceptions = True
  2. Dash Callback 默认在用户改变输入时就会刷新callback,如果出现一种情景需要用户全部改变输入状态后再刷新,那么需要将输入转为State,这样就不会立即触发刷新。

    帮助网址

    1. 官方文档 https://dash.plotly.com/
    2. 官方社区 https://community.plotly.com/
    3. Youtube 非常详细的博主教程:https://www.youtube.com/channel/UCqBFsuAz41sqWcFjZkqmJqQ
    4. dash bootstrap components帮助你创建更佳个性化漂亮的dash应用。http://dash-bootstrap-components.opensource.faculty.ai/