Plotly Python动态双Y轴分组柱状图实现问题:保留分组布局并根据列数自动切换单/双轴
Plotly Python动态双Y轴分组柱状图实现问题:保留分组布局并根据列数自动切换单/双轴
你好!我来帮你解决这个Plotly分组柱状图加动态双Y轴的问题~
你的初始实现与需求
首先看你最初的代码,已经实现了非常理想的分组并列柱状图:用两个数据框(ag和snd)的两列数据,生成了每个日期点对应4个不重叠的条形(每个地点各两种气体),布局清晰不拥挤。
你的核心需求是:
- 保留这个分组并列的布局(每个日期点的条形不重叠)
- 实现动态适配:当只选择1列数据时用单Y轴,选择多列(比如2列)时自动添加第二Y轴
你遇到的问题
你尝试给不同列分配y/y2轴,但结果是条形重叠了——这是因为offsetgroup的设置逻辑不对,导致同一地点的两种气体条形被挤到了同一个位置。
解决方案:修正offsetgroup逻辑+动态轴适配
下面是修正后的代码,关键调整了offsetgroup的生成规则,同时保留动态轴的逻辑:
import plotly.graph_objects as go import pandas as pd # 模拟你的数据框(实际使用时替换成你的ag和snd) dates = pd.date_range('2024-01-01', periods=3) ag = pd.DataFrame({ 'Date': dates, 'Municipality': ['Athens']*3, 'NO2 mug/m^3': [20, 25, 18], 'NO mug/m^3': [10, 12, 8] }) snd = pd.DataFrame({ 'Date': dates, 'Municipality': ['Thessaloniki']*3, 'NO2 mug/m^3': [15, 18, 16], 'NO mug/m^3': [8, 9, 7] }) # 可动态调整的列列表(比如改成['NO mug/m^3']就会自动切换单Y轴) cols = ['NO2 mug/m^3', 'NO mug/m^3'] dfs = [ag, snd] fig = go.Figure() for df in dfs: loc_name = df.Municipality.unique()[0] for col_idx, col in enumerate(cols): # 关键:给每个「地点-气体」组合分配唯一的offsetgroup # 这样每个条形都有独立的分组位置,不会重叠 offset_group = f"{loc_name}_{col}" # 动态分配Y轴:只有列数>1时,第二列才用y2轴 y_axis = "y" if col_idx == 0 else ("y2" if len(cols) > 1 else "y") fig.add_trace(go.Bar( x=df['Date'], y=df[col], name=f"{loc_name} - {col}", offsetgroup=offset_group, marker=dict(opacity=0.8), yaxis=y_axis )) # 动态布局设置 layout_args = { "barmode": "group", "xaxis": {"title": "Date"}, "legend_title": "Location - Gas" } if len(cols) == 1: # 单Y轴场景:只设置主Y轴 layout_args["yaxis"] = {"title": cols[0]} else: # 双Y轴场景:同时设置主、次Y轴 layout_args["yaxis"] = {"title": cols[0]} layout_args["yaxis2"] = { "title": cols[1], "overlaying": "y", "side": "right", "showgrid": False } fig.update_layout(**layout_args) fig.show()
关键修改说明
- offsetgroup的设置:用
{loc_name}_{col}作为每个条形的分组标识,确保每个「地点-气体」组合都有独立的位置,完美保留你最初的分组并列布局。 - 动态Y轴分配:只有当列数大于1时,才给第二列分配次Y轴,否则所有条形都用主Y轴,避免无效轴显示。
- 布局适配:根据列数自动切换单/双Y轴的布局配置,完全满足你想要的灵活性。
效果验证
- 当
cols只有1列时(比如['NO mug/m^3']):自动切换为单Y轴,每个日期点显示2个并列的条形(两个地点的NO数据)。 - 当
cols有2列时:双Y轴同时显示,每个日期点显示4个并列的条形(两个地点各两种气体),完全保留你最初的理想布局。
备注:内容来源于stack exchange,提问作者savvas pehlivanidis
相关产品推荐
相关产品推荐

