Plotly子图:如何为各子图添加独立图例并自定义柱状图尺寸
Plotly子图:独立图例配置与柱状图尺寸自定义
一、为每个子图添加对应独立图例
默认情况下Plotly会将所有图例集中显示,要实现每个子图绑定专属图例,需通过以下配置实现:
核心配置要点
- 为每个子图的所有trace设置相同的
legendgroup,用于关联到同一个图例组 - 在布局中定义多个独立图例,通过
xref/yref绑定到目标子图,调整x/y坐标控制图例位置 - 关闭全局统一图例,让每个trace仅显示对应组的图例
二、自定义柱状图尺寸
可以从两个层面调整:
- 单根柱子宽度:给Bar trace添加
marker={"width": 0.5}参数(数值范围0-1,越小柱子越窄) - 子图区域大小:在
make_subplots中通过column_widths和row_heights设置子图的宽高占比,比如column_widths=[0.6, 0.4]让第一列子图更宽
修改后的完整代码
import plotly.express as px import plotly.graph_objects as go from plotly.subplots import make_subplots # 调整子图宽高比例,影响柱状图显示区域 specs = [[{'type':'pie'}, {"type": "pie"}], [{"type": "bar"}, {"type": "bar"}]] fig = make_subplots( rows=2, cols=2, specs=specs, shared_yaxes=True, subplot_titles=['Pie Chart A', 'Pie Chart B', 'Bar Chart A', ''], column_widths=[0.5, 0.5], # 自定义列宽比例 row_heights=[0.5, 0.5] # 自定义行高比例 ) # 饼图1:绑定到图例组pie_1 df1 = df['Generation'].value_counts().reset_index(name='count') fig.add_trace(go.Pie( labels=df1['index'], values=df1['count'], hole=0.6, marker_colors=['#353837','#646665', '#8e9492'], textinfo='percent + value + label', textposition=['inside', 'inside','outside'], legendgroup="pie_1", # 绑定图例组 showlegend=True ), 1, 1) # 饼图2:绑定到图例组pie_2 df2 = df['Education_Level'].value_counts().reset_index(name='count') fig.add_trace(go.Pie( labels=df2['index'], values=df2['count'], hole=0.6, marker_colors=['#353837','#646665', '#8e9492','#acadac','#f0f2f0'], textinfo='percent + value + label', textposition=['inside', 'inside','inside','inside','outside'], legendgroup="pie_2", # 绑定图例组 showlegend=True ), 1, 2) df4 = df.groupby(['Generation'])['Education_Level'].value_counts().reset_index(name='count') df4['%'] = 100 * df4['count'] / df4.groupby(['Generation'])['count'].transform('sum') # 柱状图trace:统一绑定到图例组bar_1,同时自定义柱子宽度 trace1 = go.Bar( x=df4[df4['Generation']=='Millenials']['Education_Level'], y=df4[df4['Generation']=='Millenials']['count'], name='Millenials', text=['M, {}, {:.0%}'.format(v, p/100) for v,p in zip( df4[df4['Generation']=='Millenials']['count'], df4[df4['Generation']=='Millenials']['%'] )], textposition=['inside', 'inside', 'inside', 'inside', 'outside'], textfont_size=15, marker_color=['#455f66']*len(df4['Education_Level']), marker={"width": 0.4}, # 自定义柱子宽度 legendgroup="bar_1", # 绑定图例组 showlegend=True ) trace2 = go.Bar( x=df4[df4['Generation']=='Generation X']['Education_Level'], y=df4[df4['Generation']=='Generation X']['count'], name='Generation X', text=['GX, {}, {:.0%}'.format(v, p/100) for v,p in zip( df4[df4['Generation']=='Generation X']['count'], df4[df4['Generation']=='Generation X']['%'] )], textposition=['inside', 'inside', 'inside', 'outside', 'outside'], textfont_size=15, marker_color=['#7da8b3']*len(df4['Education_Level']), marker={"width": 0.4}, legendgroup="bar_1", showlegend=True ) trace3 = go.Bar( x=df4[df4['Generation']=='Boomers']['Education_Level'], y=df4[df4['Generation']=='Boomers']['count'], name='Boomers', text=['B, {}, {:.0%}'.format(v, p/100) for v,p in zip( df4[df4['Generation']=='Boomers']['count'], df4[df4['Generation']=='Boomers']['%'] )], textfont_size=15, textposition='outside', marker_color=['#9bd9e8']*len(df4['Education_Level']), marker={"width": 0.4}, legendgroup="bar_1", showlegend=True ) fig.append_trace(trace1,2,1) fig.append_trace(trace2,2,1) fig.append_trace(trace3,2,1) fig.update_annotations(font_size=12) fig.update_layout( height=650, width=850, showlegend=False, # 关闭全局图例 title=dict( text="<b> [Summary] </b> Highlevel Overview ", font=dict(family="Arial", size=20, color='#283747') ), # 定义三个独立图例,分别绑定到对应子图 legends=[ # 饼图1的图例 dict( legendgroup="pie_1", x=0.25, y=1.05, # 位置调整 xref="x1", yref="paper", orientation="h" ), # 饼图2的图例 dict( legendgroup="pie_2", x=0.75, y=1.05, xref="x2", yref="paper", orientation="h" ), # 柱状图的图例 dict( legendgroup="bar_1", x=0.5, y=-0.1, xref="paper", yref="paper", orientation="h" ) ] ) fig.show()
内容的提问来源于stack exchange,提问作者WF30
相关产品推荐
相关产品推荐

