首页 > 解决方案 > Plotly:将日期滑块添加到具有多个 y 轴的分组条形图

问题描述

我正在寻找一种将日期滑块添加到具有多个 y 轴的分组条形图的方法。那可能吗?

这是我的代码示例:

tourist  = pd.DataFrame({'date': ['2009-01-01', '2009-01-02', '2009-01-03', '2009-01-04', '2009-01-05', '2009-01-01', '2009-01-02', '2009-01-03', '2009-01-04', '2009-01-05','2009-01-01', '2009-01-02', '2009-01-03', '2009-01-04', '2009-01-05'],
                   'state': ['A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B', 'C', 'C', 'C', 'C', 'C'],
                   'tourists': [100, 121, 235, 197, 390, 57, 49, 81, 73, 183, 351, 490, 618, 438, 557]})
tourist2 = pd.DataFrame(columns = ['date', 'state', 'tourists', 'growth_rate'], dtype= 'object')

for i in tourist.state.unique():
    temp = tourist[tourist.state == i].copy()
    temp['growth_rate'] = (temp['tourists'] - temp['tourists'].shift(1)) / temp['tourists'].shift(1)
    tourist2 = pd.concat([tourist2, temp])
    

fig = go.Figure(
    data=[go.Bar(x = tourist2.state, y = tourist2.tourists, yaxis='y', name = 'Total', offsetgroup=1),
          go.Bar(x = tourist2.state, y = tourist2.growth_rate, yaxis='y2', name = 'Percentage', offsetgroup=2)],
    layout={'yaxis': {'title': '<b>Primary</b> Total'},
            'yaxis2': {'title': '<b>Secondary</b> Percentage', 'overlaying': 'y', 'side': 'right'}}
)

# Change the bar mode
fig.update_layout(barmode='group')
fig.show()

图表的输出看起来像这样,其中包含所有 5 天的数据。我希望在图表下方添加日期滑块以过滤要按所选日期显示的数据,类似于animation_frame = 'date'在此处输入图像描述

标签: pythondatesliderplotly

解决方案


  • 你已经完成了所有的基础工作,需要为动画创建帧
  • 发现在轴上设置范围很重要
# create the frames for each date
frames = []
for d in tourist["date"].unique():
    t = tourist2.loc[tourist2["date"] == d]
    frames.append(
        go.Frame(
            name=d,
            data=[
                go.Bar(x=t.state, y=t.tourists, yaxis="y", name="Total", offsetgroup=1),
                go.Bar(x=t.state,y=t.growth_rate,yaxis="y2",name="Percentage",offsetgroup=2,),
            ],
        )
    )

# create the figure,  also set limits of axes
fig = go.Figure(
    data=frames[0].data,
    frames=frames,
    layout={
        "yaxis": {"title": "<b>Primary</b> Total", "range":[0,tourist2["tourists"].max()]},
        "yaxis2": {
            "title": "<b>Secondary</b> Percentage",
            "overlaying": "y",
            "side": "right",
            "range":[tourist2["growth_rate"].min(),tourist2["growth_rate"].max()]
        },
    },
)

# finally create the slider...
fig.update_layout(
    barmode="group",
    updatemenus=[{"buttons": [{"args": [None, {"frame": {"duration": 500, "redraw": True}}],
                               "label": "&#9654;",
                               "method": "animate",},],
                  "type": "buttons",}],
    sliders=[{"steps": [{"args": [[f.name],{"frame": {"duration": 0, "redraw": True},
                                            "mode": "immediate",},],
                         "label": f.name, "method": "animate",}
                        for f in frames ],
             }],
)

在此处输入图像描述


推荐阅读