1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
| import dash from dash import dcc, html, Input, Output, State import dash_bootstrap_components as dbc import pandas as pd import plotly.express as px
app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP], suppress_callback_exceptions=True)
app.layout = dbc.Container([ dbc.Row([ dbc.Col([ html.H1("高级数据分析仪表板", className="text-center my-4"), html.Hr() ], width=12) ]), dbc.Row([ dbc.Col([ html.H4("数据控制面板"), html.Label("选择时间范围:"), dcc.DatePickerRange( id='date-range', start_date='2023-01-01', end_date='2023-04-10', display_format='YYYY-MM-DD' ), html.Label("选择指标:", className="mt-3"), dcc.Dropdown( id='metric-selector', options=[ {'label': '值A', 'value': 'value_a'}, {'label': '值B', 'value': 'value_b'} ], value=['value_a'], multi=True ), html.Label("图表类型:", className="mt-3"), dcc.RadioItems( id='chart-type', options=[ {'label': '折线图', 'value': 'line'}, {'label': '散点图', 'value': 'scatter'}, {'label': '柱状图', 'value': 'bar'} ], value='line' ), dbc.Button("更新图表", id='update-button', color="primary", className="mt-3 w-100") ], md=3), dbc.Col([ dcc.Loading( id="loading-1", type="default", children=[ dcc.Graph(id='main-chart'), html.Div(id='summary-stats', className="mt-3") ] ) ], md=9) ]), dcc.Store(id='filtered-data') ], fluid=True)
@app.callback( Output('filtered-data', 'data'), Input('update-button', 'n_clicks'), State('date-range', 'start_date'), State('date-range', 'end_date') ) def filter_data(n_clicks, start_date, end_date): if n_clicks is None: return dash.no_update filtered_df = data[ (data['date'] >= start_date) & (data['date'] <= end_date) ] return filtered_df.to_json(date_format='iso', orient='split')
@app.callback( [Output('main-chart', 'figure'), Output('summary-stats', 'children')], [Input('filtered-data', 'data'), Input('metric-selector', 'value'), Input('chart-type', 'value')] ) def update_chart(data_json, selected_metrics, chart_type): if not data_json: return {}, "" df = pd.read_json(data_json, orient='split') if chart_type == 'line': fig = px.line(df, x='date', y=selected_metrics, title='时间序列分析') elif chart_type == 'scatter': fig = px.scatter(df, x='date', y=selected_metrics[0], color='category', size='size', title='散点分布图') else: fig = px.bar(df, x='date', y=selected_metrics, title='柱状图分析') fig.update_layout( hovermode='x unified', showlegend=True, height=500 ) stats_html = [] for metric in selected_metrics: stats = df[metric].describe() stats_html.append(html.H5(f"{metric} 统计:")) stats_html.append(html.P(f"平均值: {stats['mean']:.2f}")) stats_html.append(html.P(f"标准差: {stats['std']:.2f}")) stats_html.append(html.Hr()) return fig, stats_html
if __name__ == '__main__': app.run_server(debug=True, port=8050)
|