如何在Plotly Dash仪表盘实现按用户输入切换卫星数据集?
解决Dash仪表盘切换卫星数据源的问题
问题说明
当前代码中试图通过图表内部按钮切换卫星,但无法将选择传递给Orbital()函数,需要调整布局和回调逻辑来实现Terra/Earth卫星数据源的切换。
修改方案
- 添加布局控件:在仪表盘顶部添加独立的切换按钮和存储组件,用于跟踪当前选中的卫星
- 新增按钮回调:处理按钮点击事件,更新存储的卫星名称
- 改造数据回调:让文本和图表更新逻辑依赖选中的卫星名称,动态创建
Orbital实例
完整修改代码
import datetime import dash from dash import dcc, html, callback_context import plotly from dash.dependencies import Input, Output, State from pyorbital.orbital import Orbital app = dash.Dash(__name__) app.layout = html.Div( html.Div([ html.H4('Satellite Live Feed'), # 添加卫星切换按钮组 html.Div([ dcc.Button('Terra', id='terra-btn', n_clicks=0, style={'marginRight': '10px'}), dcc.Button('Earth', id='earth-btn', n_clicks=0), ], style={'margin': '10px 0'}), # 存储当前选中的卫星名称 dcc.Store(id='selected-satellite', data='TERRA'), html.Div(id='live-update-text'), dcc.Graph(id='live-update-graph'), dcc.Interval( id='interval-component', interval=1*1000, # in milliseconds n_intervals=0 ) ]) ) # 回调:处理按钮点击,更新选中的卫星 @app.callback( Output('selected-satellite', 'data'), Input('terra-btn', 'n_clicks'), Input('earth-btn', 'n_clicks'), State('selected-satellite', 'data') ) def update_selected_sat(terra_clicks, earth_clicks, current_sat): ctx = callback_context if not ctx.triggered: return current_sat button_id = ctx.triggered[0]['prop_id'].split('.')[0] if button_id == 'terra-btn': return 'TERRA' elif button_id == 'earth-btn': return 'Earth' return current_sat # 回调:更新卫星实时数据文本 @app.callback( Output('live-update-text', 'children'), Input('interval-component', 'n_intervals'), Input('selected-satellite', 'data') ) def update_metrics(n, selected_sat): satellite = Orbital(selected_sat) lon, lat, alt = satellite.get_lonlatalt(datetime.datetime.now()) style = {'padding': '5px', 'fontSize': '16px', 'marginRight': '15px'} return [ html.Span('Longitude: {0:.2f}'.format(lon), style=style), html.Span('Latitude: {0:.2f}'.format(lat), style=style), html.Span('Altitude: {0:0.2f}'.format(alt), style=style) ] # 回调:更新实时图表 @app.callback( Output('live-update-graph', 'figure'), Input('interval-component', 'n_intervals'), Input('selected-satellite', 'data') ) def update_graph_live(n, selected_sat): satellite = Orbital(selected_sat) data = { 'time': [], 'Latitude': [], 'Longitude': [], 'Altitude': [] } # 收集历史数据 for i in range(180): time = datetime.datetime.now() - datetime.timedelta(seconds=i*20) lon, lat, alt = satellite.get_lonlatalt(time) data['Longitude'].append(lon) data['Latitude'].append(lat) data['Altitude'].append(alt) data['time'].append(time) # 创建子图 fig = plotly.tools.make_subplots(rows=2, cols=1, vertical_spacing=0.2) fig['layout']['margin'] = {'l': 30, 'r': 10, 'b': 30, 't': 10} fig['layout']['legend'] = {'x': 0, 'y': 1, 'xanchor': 'left'} # 添加高度变化轨迹 fig.append_trace({ 'x': data['time'], 'y': data['Altitude'], 'name': 'Altitude', 'mode': 'lines+markers', 'type': 'scatter' }, 1, 1) # 添加经纬度轨迹 fig.append_trace({ 'x': data['Longitude'], 'y': data['Latitude'], 'text': data['time'], 'name': 'Longitude vs Latitude', 'mode': 'lines+markers', 'type': 'scatter' }, 2, 1) # 设置时间轴样式 fig.update_layout( xaxis=dict( rangeselector=dict( buttons=list([ dict(count=1, label="1d", step="day", stepmode="backward") ]) ), type="date" ) ) return fig if __name__ == '__main__': app.run_server(debug=True)
修改说明
- 移除了原图表内部的
updatemenus(原按钮用于修改图表类型,与切换数据源无关) - 添加了
dcc.Store组件存储当前选中的卫星名称,避免全局变量无法动态更新的问题 - 新增按钮点击回调,通过
callback_context判断哪个按钮被触发,更新选中的卫星 - 原有数据回调新增
selected-satellite作为输入,动态创建对应卫星的Orbital实例,实现数据源切换
内容的提问来源于stack exchange,提问作者Cauder
相关产品推荐
相关产品推荐

