Plotly graph_objects添加图例或plotly express自定义柱宽问题咨询
问题背景
Plotly的两类绘图接口各有局限:
- 使用
graph_objects(go)接口绘制的柱状图支持设置单根柱子宽度,但无法自动生成省份分类的颜色图例 - 使用
plotly express(px)接口绘制的柱状图可自动生成省份分类颜色图例,但默认不支持自定义单根柱子的宽度
方案1:为go接口绘图添加颜色图例
原有go代码只创建了一个Bar trace,所以不会生成分类图例,只需把不同省份的柱子拆分为独立trace,每个trace对应一个省份、统一设置颜色和图例名称即可,修改后代码如下:
import plotly.graph_objects as go import pandas as pd df = pd.DataFrame({'PHA': [451, 149, 174, 128, 181, 175, 184, 545, 131, 106, 1780, 131, 344, 624, 236, 224, 178, 277, 141, 171, 164, 410], 'PHA_cum': [451, 600, 774, 902, 1083, 1258, 1442, 1987, 2118, 2224, 4004, 4135, 4479, 5103, 5339, 5563, 5741, 6018, 6159, 6330, 6494, 6904], 'trans_cost_cum': [0.14, 0.36, 0.6, 0.99, 1.4, 2.07, 2.76, 3.56, 4.01, 4.5, 5.05, 5.82, 5.97, 6.13, 6.33, 6.53, 6.65, 6.77, 6.9, 7.03, 7.45, 7.9], 'Province': ['East', 'East', 'East', 'East', 'East', 'Lapland', 'Lapland', 'Lapland', 'Oulu', 'Oulu', 'Oulu', 'Oulu', 'South', 'South', 'South', 'South', 'West', 'West', 'West', 'West', 'West', 'West'], }) col_list = {'South': 'rgb(222,203,228)', 'West': 'rgb(204,235,197)', 'East': 'rgb(255,255,204)', 'Oulu': 'rgb(179,205,227)', 'Lapland': 'rgb(254,217,166)'} fig = go.Figure() # 按省份分组创建独立trace,自动生成图例 for prov, group in df.groupby('Province'): fig.add_trace(go.Bar( x=group['PHA_cum'] - group['PHA']/2, y=group['trans_cost_cum'], width=group['PHA'], marker_color=col_list[prov], name=prov # 图例显示的省份名称 )) fig.show()
该方案既保留了单柱自定义宽度的能力,也会自动生成对应省份的颜色图例。
方案2:为px接口绘图设置自定义单柱宽度
px生成的图表底层仍然是go的trace结构,直接修改对应trace的width属性即可,修改后代码如下:
import plotly.express as px import pandas as pd df = pd.DataFrame({'PHA': [451, 149, 174, 128, 181, 175, 184, 545, 131, 106, 1780, 131, 344, 624, 236, 224, 178, 277, 141, 171, 164, 410], 'PHA_cum': [451, 600, 774, 902, 1083, 1258, 1442, 1987, 2118, 2224, 4004, 4135, 4479, 5103, 5339, 5563, 5741, 6018, 6159, 6330, 6494, 6904], 'trans_cost_cum': [0.14, 0.36, 0.6, 0.99, 1.4, 2.07, 2.76, 3.56, 4.01, 4.5, 5.05, 5.82, 5.97, 6.13, 6.33, 6.53, 6.65, 6.77, 6.9, 7.03, 7.45, 7.9], 'Province': ['East', 'East', 'East', 'East', 'East', 'Lapland', 'Lapland', 'Lapland', 'Oulu', 'Oulu', 'Oulu', 'Oulu', 'South', 'South', 'South', 'South', 'West', 'West', 'West', 'West', 'West', 'West'], }) fig = px.bar(df, x=df['PHA_cum']-df['PHA']/2, y=df['trans_cost_cum'], color="Province", color_discrete_sequence=px.colors.qualitative.Pastel1 ) # 手动修改所有柱子的宽度为对应PHA值 for i, bar in enumerate(fig.data): bar.width = df[df['Province'] == bar.name]['PHA'].values fig.show()
该方案既保留了px自动生成图例的便利性,也实现了单柱的自定义宽度设置。
内容的提问来源于stack exchange,提问作者Walter
相关产品推荐
相关产品推荐

