You need to enable JavaScript to run this app. Plotly Dash柱状图如何根据缩放区间动态调整数据聚合频率
优惠活动
大模型
产品
解决方案
定价
更多

Plotly Dash柱状图如何根据缩放区间动态调整数据聚合频率

Plotly Dash动态调整时间序列柱状图聚合频率实现方案

实现核心是利用Dash回调监听图表的缩放事件,根据当前可视区间的时间跨度动态调整数据聚合粒度,具体实现逻辑如下:

  • 提前保留原始日度数据,将日期列转换为datetime格式,不要提前做固定粒度的聚合
  • 在Dash布局中定义带唯一ID的dcc.Graph组件,用于渲染柱状图
  • 编写回调函数,以图表的relayoutData属性作为输入,图表的figure属性作为输出,回调内逻辑如下:
    1. 读取当前x轴的可视时间范围,无缩放操作时默认使用全量数据的时间范围
    2. 计算当前可视区间的总天数,根据天数匹配对应的聚合粒度:
      • 跨度大于3年:按季度聚合
      • 跨度1~3年:按月份聚合
      • 跨度1个月~1年:按周聚合
      • 跨度小于1个月:按原始日度展示
    3. 用Pandas的pd.Grouper按匹配的粒度对数据做分组聚合,复用原有指标计算逻辑生成新图表返回

完整示例代码如下:

import dash
from dash import dcc, html, Input, Output
import plotly.graph_objects as go
import pandas as pd

# 提前加载原始日度数据,将date列转为datetime格式
original_df = pd.read_csv('你的数据文件路径.csv', parse_dates=['date'])

app = dash.Dash(__name__)
app.layout = html.Div([
    dcc.Graph(id='dynamic-bar-chart')
])

@app.callback(
    Output('dynamic-bar-chart', 'figure'),
    Input('dynamic-bar-chart', 'relayoutData'),
    prevent_initial_call=False
)
def update_figure(relayout_data):
    df = original_df.copy()
    # 获取当前可视时间范围
    if relayout_data and 'xaxis.range[0]' in relayout_data:
        start_date = pd.to_datetime(relayout_data['xaxis.range[0]'])
        end_date = pd.to_datetime(relayout_data['xaxis.range[1]'])
        df = df[(df['date'] >= start_date) & (df['date'] <= end_date)]
    else:
        start_date = df['date'].min()
        end_date = df['date'].max()
    
    # 根据时间跨度确定聚合粒度
    day_diff = (end_date - start_date).days
    if day_diff > 3 * 365:
        freq = 'Q'
    elif day_diff > 365:
        freq = 'M'
    elif day_diff > 30:
        freq = 'W'
    else:
        freq = 'D'
    
    # 聚合数据,复用原有计算逻辑
    df_agg = df.dropna(subset=['date']).groupby(pd.Grouper(key='date', freq=freq))[
        ['positive', 'negative']].mean().reset_index()
    df_agg['pos_rate'] = 100 * df_agg['positive'] / (df_agg['positive'] + df_agg['negative'])
    df_agg['neg_rate'] = 100 * df_agg['negative'] / (df_agg['positive'] + df_agg['negative'])
    
    # 自定义颜色配置可自行修改
    colors = {'pos1':'#27ae60', 'neg1':'#c0392b'}
    fig = go.Figure()
    fig.add_trace(go.Bar(
        x=df_agg['date'],
        y=df_agg['pos_rate'],
        base=0,
        name='Positive',
        marker_color=colors['pos1']
    ))
    fig.add_trace(go.Bar(
        x=df_agg['date'],
        y=df_agg['neg_rate'],
        base=-df_agg['neg_rate'],
        name='Negative',
        marker_color=colors['neg1']
    ))
    fig.update_layout(barmode='relative', transition_duration=500)
    return fig

if __name__ == '__main__':
    app.run_server(debug=True)

优化提示

  • 可以根据实际业务需求调整不同时间跨度对应的聚合粒度
  • 若数据量极大,可提前缓存不同粒度的聚合结果,避免每次回调重复计算,提升交互响应速度

内容的提问来源于stack exchange,提问作者jiwooshim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.15 04:54:01