如何将堆叠条形图转换为100%堆叠条形图(Python Plotly)
100%堆叠条形图修改方案(适配Location维度)
核心问题修正
你之前的方案失效是因为没按Location维度分组计算占比——100%堆叠的核心是每个X轴类别(即每个Location)下的所有堆叠项占比总和为100%,而非全局设备的占比。
步骤1:数据预处理(计算区域内设备占比)
先通过Pandas按Location和Brewer分组统计,再计算每个区域内各设备的占比:
import pandas as pd # 假设你的原始数据框为df,包含Location、Brewer列(每行对应一条销售/使用记录) # 1. 统计每个区域-设备组合的使用次数 grouped_data = df.groupby(['Location', 'Brewer']).size().reset_index(name='UsageCount') # 2. 计算每个区域内,各设备的使用占比(转为百分比) grouped_data['UsagePercentage'] = grouped_data.groupby('Location')['UsageCount'].transform( lambda x: (x / x.sum()) * 100 )
如果你的数据已经有预统计的计数列(比如TotalUsage),把size()换成sum('TotalUsage')即可。
步骤2:修改Plotly代码生成100%堆叠图
用预处理后的占比数据绘图,固定Y轴范围为0-100:
方案A:Plotly Express(简洁版)
import plotly.express as px fig = px.bar( grouped_data, x='Location', y='UsagePercentage', color='Brewer', barmode='stack', title='各区域酿酒设备使用占比', labels={ 'UsagePercentage': '使用占比(%)', 'Location': '区域', 'Brewer': '酿酒设备' } ) # 固定Y轴为0-100,显示整数百分比 fig.update_layout( yaxis=dict( range=[0, 100], tickformat='.0f%', title='使用占比(%)' ) ) fig.show()
方案B:Plotly Graph Objects(自定义度更高)
如果需要更精细的样式控制,用graph_objects实现:
import plotly.graph_objects as go import numpy as np # 获取所有唯一的Location和Brewer locations = grouped_data['Location'].unique() brewers = grouped_data['Brewer'].unique() fig = go.Figure() # 为每个酿酒设备添加堆叠条形 for brewer in brewers: brewer_data = grouped_data[grouped_data['Brewer'] == brewer] # 确保每个Location都有数据(避免缺失) brewer_data = brewer_data.set_index('Location').reindex(locations).fillna(0).reset_index() fig.add_trace(go.Bar( x=brewer_data['Location'], y=brewer_data['UsagePercentage'], name=brewer, text=brewer_data['UsagePercentage'].round(1).astype(str) + '%', # 显示占比标签 textposition='inside' )) # 设置堆叠模式和Y轴 fig.update_layout( barmode='stack', title='各区域酿酒设备使用占比', yaxis=dict( range=[0, 100], tickformat='.0f%', title='使用占比(%)' ), xaxis_title='区域' ) fig.show()
效果说明
修改后每个区域的堆叠条形总高度都是100%,能清晰对比同一区域内不同设备的使用占比差异,同时保留Location维度的分组展示。
内容的提问来源于stack exchange,提问作者coffeefin
相关产品推荐
相关产品推荐

