如何在Plotly中为X轴元素添加两组100%堆叠柱状图并归一化Y轴?
问题描述
我用Python的Plotly生成了分组柱状图,目前已满足大部分需求,但最后需要将其改为100%堆叠样式,使Y轴最大值为1,所有柱状图对齐。请问在Plotly中如何实现该需求?
原生成图表代码:
fig = go.Figure() categories = grouped_values2['portfolio_category'].unique() category_colors = ["#0070C0", "#FFC000", "#AD1457", "#00A651", "#DB4437", "#6E3159", "#F4A000", "#00788C", "#5FB3C3"] for i, category in enumerate(categories): num1 = random.randint(0, 30) category_data = grouped_values2[grouped_values['portfolio_category'] == category] fig.add_trace( go.Bar( x=category_data['month'], y=category_data['importancia_realizado'], name=f'R - {category}', marker_color=category_colors[i], offsetgroup=0 ) ) fig.add_trace( go.Bar( x=category_data['month'], y=category_data['importancia_referencia'], name=f'P - {category}', marker_color=category_colors[i], offsetgroup=1 ) ) fig.update_layout( barmode='group', title='IMPORTÂNCIA PROJETADA (P) vs IMPORTANCIA REALIZADA', plot_bgcolor="rgba(0, 0, 0, 0)", xaxis_title='Mês', yaxis_title='Importância' ) fig.show()
对应数据:
month,month_number,portfolio_category,gmv_mtd,importancia_referencia,importancia_realizado Apr,4,CAT1,3242989.05,0.230,0.188 Apr,4,CAT2,3490670.33,0.190,0.202 Apr,4,CAT3,2970437.35,0.170,0.172 Apr,4,CAT4,6310704.34,0.160,0.365 Apr,4,CAT5,1046692.36,0.120,0.610 Apr,4,CAT6,216612.53,0.130,0.130 Jun,6,CAT1,4449799.95,0.210,0.274 Jun,6,CAT2,5209480.79,0.240,0.321 Jun,6,CAT3,2478664.66,0.160,0.153 Jun,6,CAT4,1318476.99,0.130,0.810 Jun,6,CAT5,2349817.17,0.130,0.145 Jun,6,CAT6,425692.50,0.130,0.260 May,5,CAT1,4057372.58,0.210,0.284 May,5,CAT2,3504235.05,0.250,0.245 May,5,CAT3,2863510.23,0.170,0.201 May,5,CAT4,900040.46,0.130,0.630 May,5,CAT5,2564349.59,0.130,0.180 May,5,CAT6,385128.35,0.120,0.270
解决方案
要实现100%堆叠的分组柱状图,核心是调整Plotly的柱状图模式和归一化规则,关键修改如下:
- 将
barmode从group改为stack,同时添加barnorm='percent'参数,让每个分组内的柱状图按百分比堆叠,总和自动为100%(对应Y轴数值1)。 - 修正原代码中数据筛选的变量名错误(
grouped_values改为grouped_values2),移除无用的random.randint代码。 - 显式设置Y轴范围为
[0, 1],确保所有柱状图高度对齐统一。
修改后的完整代码:
import plotly.graph_objects as go import pandas as pd from io import StringIO # 加载并整理数据 data = """month,month_number,portfolio_category,gmv_mtd,importancia_referencia,importancia_realizado Apr,4,CAT1,3242989.05,0.230,0.188 Apr,4,CAT2,3490670.33,0.190,0.202 Apr,4,CAT3,2970437.35,0.170,0.172 Apr,4,CAT4,6310704.34,0.160,0.365 Apr,4,CAT5,1046692.36,0.120,0.610 Apr,4,CAT6,216612.53,0.130,0.130 Jun,6,CAT1,4449799.95,0.210,0.274 Jun,6,CAT2,5209480.79,0.240,0.321 Jun,6,CAT3,2478664.66,0.160,0.153 Jun,6,CAT4,1318476.99,0.130,0.810 Jun,6,CAT5,2349817.17,0.130,0.145 Jun,6,CAT6,425692.50,0.130,0.260 May,5,CAT1,4057372.58,0.210,0.284 May,5,CAT2,3504235.05,0.250,0.245 May,5,CAT3,2863510.23,0.170,0.201 May,5,CAT4,900040.46,0.130,0.630 May,5,CAT5,2564349.59,0.130,0.180 May,5,CAT6,385128.35,0.120,0.270""" grouped_values2 = pd.read_csv(StringIO(data)) fig = go.Figure() categories = grouped_values2['portfolio_category'].unique() category_colors = ["#0070C0", "#FFC000", "#AD1457", "#00A651", "#DB4437", "#6E3159", "#F4A000", "#00788C", "#5FB3C3"] for i, category in enumerate(categories): category_data = grouped_values2[grouped_values2['portfolio_category'] == category] fig.add_trace( go.Bar( x=category_data['month'], y=category_data['importancia_realizado'], name=f'R - {category}', marker_color=category_colors[i], offsetgroup=0 ) ) fig.add_trace( go.Bar( x=category_data['month'], y=category_data['importancia_referencia'], name=f'P - {category}', marker_color=category_colors[i], offsetgroup=1 ) ) fig.update_layout( barmode='stack', barnorm='percent', title='IMPORTÂNCIA PROJETADA (P) vs IMPORTANCIA REALIZADA', plot_bgcolor="rgba(0, 0, 0, 0)", xaxis_title='Mês', yaxis_title='Importância', yaxis_range=[0, 1] ) fig.show()
修改后效果:每个月份会显示两个高度为1的堆叠柱,分别对应「实际完成重要性(R)」和「计划重要性(P)」的类别占比堆叠,所有柱状图完全对齐到Y轴最大值1。
内容的提问来源于stack exchange,提问作者Marcos Dias
相关产品推荐
相关产品推荐

