Python新手求助:实现带筛选与标签的分类特征交互式时间序列可视化
Python交互式时间序列图表实现方案
问题需求
我是Python新手,想做交互式图表,手里有时间序列数据,需要实现两个核心功能:
- 通过选择
SOURCE和ID,展示DATE与分类列CODE的对应关系,同时支持查看单个ID的全部数据; - 用柱状图时,柱子上方显示
CODE标签;用散点图时,每个点上显示CODE标签。
目前只会做简单静态图表,附上我的尝试代码和数据样例:
尝试代码1
import matplotlib.pyplot as plt ax = df.groupby(['DATE', 'CODE']).size().unstack().plot.bar() ax
尝试代码2
import pandas as pd import seaborn as sns p = sns.countplot(data=df, x='DATE', hue='CODE') p.legend(title='CODE', bbox_to_anchor=(1, 1), loc='upper left') for c in p.containers: # set the bar label p.bar_label(c, fmt='%.0f', label_type='edge')
数据样例
ID DATE CODE SOURCE 0 P04 2016-08-08 f m1 1 P04 2015-05-08 f m1 2 P04 2010-07-20 v m3 3 P04 2013-12-06 g m4 4 P08 2018-03-01 h m4
解决方案:用Dash+Plotly实现交互式图表
推荐用Dash和Plotly来做,这俩组合对新手友好,自带交互式控件,不用自己写复杂的交互逻辑。
步骤1:安装依赖库
先在命令行安装需要的包:
pip install pandas plotly dash
步骤2:完整代码实现
import pandas as pd from dash import Dash, dcc, html, Input, Output import plotly.express as px # 初始化数据(替换成你自己的真实数据) data = { 'ID': ['P04', 'P04', 'P04', 'P04', 'P08'], 'DATE': ['2016-08-08', '2015-05-08', '2010-07-20', '2013-12-06', '2018-03-01'], 'CODE': ['f', 'f', 'v', 'g', 'h'], 'SOURCE': ['m1', 'm1', 'm3', 'm4', 'm4'] } df = pd.DataFrame(data) # 把DATE转成日期格式,方便时间序列处理 df['DATE'] = pd.to_datetime(df['DATE']) # 创建Dash应用 app = Dash(__name__) # 设置页面布局:选择器+图表区域 app.layout = html.Div([ html.H3("时间序列交互式图表"), # SOURCE选择框 html.Div([ html.Label("选择SOURCE:"), dcc.Dropdown( id='source-select', options=[{'label': s, 'value': s} for s in df['SOURCE'].unique()] + [{'label': '全部', 'value': 'all'}], value='all' ) ], style={'width': '48%', 'display': 'inline-block', 'margin-right': '2%'}), # ID选择框 html.Div([ html.Label("选择ID:"), dcc.Dropdown( id='id-select', options=[{'label': i, 'value': i} for i in df['ID'].unique()] + [{'label': '全部', 'value': 'all'}], value='all' ) ], style={'width': '48%', 'display': 'inline-block'}), # 图表类型单选框 html.Div([ html.Label("选择图表类型:"), dcc.RadioItems( id='chart-type', options=[{'label': '柱状图', 'value': 'bar'}, {'label': '散点图', 'value': 'scatter'}], value='bar', inline=True ) ], style={'margin-top': '15px'}), # 图表展示区域 dcc.Graph(id='ts-chart', style={'margin-top': '15px'}) ]) # 核心回调:根据选择更新图表 @app.callback( Output('ts-chart', 'figure'), Input('source-select', 'value'), Input('id-select', 'value'), Input('chart-type', 'value') ) def update_chart(selected_source, selected_id, chart_type): # 筛选数据 filtered_data = df.copy() if selected_source != 'all': filtered_data = filtered_data[filtered_data['SOURCE'] == selected_source] if selected_id != 'all': filtered_data = filtered_data[filtered_data['ID'] == selected_id] # 生成柱状图 if chart_type == 'bar': # 按日期和CODE分组统计数量 grouped_data = filtered_data.groupby(['DATE', 'CODE']).size().reset_index(name='数量') fig = px.bar(grouped_data, x='DATE', y='数量', color='CODE', barmode='group', title='日期与CODE分布') # 给每个柱子添加CODE标签 for trace in fig.data: trace.text = trace.name trace.textposition = 'outside' # 生成散点图 else: fig = px.scatter(filtered_data, x='DATE', y='CODE', color='ID', title='日期与CODE对应关系') # 给每个点添加CODE标签 fig.update_traces(text=filtered_data['CODE'], textposition='top center') # 美化图表 fig.update_layout(xaxis_title='日期', yaxis_title='数量' if chart_type == 'bar' else 'CODE分类') return fig # 运行应用 if __name__ == '__main__': app.run_server(debug=True)
代码说明
- 交互式选择:页面上有三个控件,分别选
SOURCE、ID和图表类型,选完后图表自动更新; - 标签显示:柱状图的柱子上方会显示对应的
CODE,散点图的每个点上方也会显示CODE; - 数据筛选:支持查看单个
SOURCE/ID的数据,也能查看全部数据; - 运行方式:运行代码后,浏览器会自动打开
http://127.0.0.1:8050/,直接操作页面上的控件就行。
内容的提问来源于stack exchange,提问作者user14269252
相关产品推荐
相关产品推荐

