Plotly分组堆叠图表多值重叠问题求助及Python替代库咨询
Plotly分组堆叠图表异常问题解决方案及替代库推荐
问题根源分析
你的代码核心问题在于同一分组(offsetgroup)内的堆叠条形图,后续系列的base参数未正确设置为前面所有堆叠系列的总和。比如offsetgroup=0中,除第一个"Manhattan ES"外,"Staten Island ES"、"East/NorthEast ES"等系列的base都直接取了data["mes"],导致所有后续系列都从第一个系列的高度开始堆叠,互相重叠,无法正确展示全部数据。
修复方案
需要为每个堆叠系列计算累积基准值(base),确保每个系列都堆叠在前一个系列的顶部。以下是修正后的代码示例:
from plotly import graph_objects as go # 假设变量已定义(m18parish_tot等) data = { "mes":[m18parish_tot, 23, 32, 10, 23], "sles":[sl18parish_tot, 23, 32, 10, 23], "dutches":[dutch18parish_tot, 23, 32, 10, 23], "enebes":[eneb18parish_tot, 23, 32, 10, 23], "nwppes":[nwpp18parish_tot, 23, 32, 10, 23], "cwes":[cw18parish_tot, 23, 32, 10, 23], "oes":[o18parish_tot, 23, 32, 10, 23], "res":[r18parish_tot, 23, 32, 10, 23], "ues":[u18parish_tot, 23, 32, 10, 23], "nwsbes":[nwsb18parish_tot, 23, 32, 10, 23], "mhs": [m18parishhs_tot, 8, 18, 6, 0], "slhs": [sl18parishhs_tot, 18, 18, 0, 20], "mec": [m18parishec_tot, 8, 18, 6, 0], "slec": [sl18parishec_tot, 18, 18, 0, 20], "bhes":[bh18parish_tot, 23, 32, 10, 23], "labels": [ "2018-2019", "2019-2020", "2020-2021", "2021-2022", "2022-2023" ] } # 计算offsetgroup=0的累积基准值 data['sles_base'] = [m + s for m, s in zip(data['mes'], data['sles'])] data['enebes_base'] = [m + s + e for m, s, e in zip(data['mes'], data['sles'], data['enebes'])] data['dutches_base'] = [m + s + e + d for m, s, e, d in zip(data['mes'], data['sles'], data['enebes'], data['dutches'])] data['nwppes_base'] = [m + s + e + d + n for m, s, e, d, n in zip(data['mes'], data['sles'], data['enebes'], data['dutches'], data['nwppes'])] fig = go.Figure( data=[ go.Bar( name="Manhattan ES", x=data["labels"], y=data["mes"], text=data["mes"], offsetgroup=0, ), go.Bar( name="Staten Island ES", x=data["labels"], y=data["sles"], text=data["sles"], offsetgroup=0, base=data["mes"], ), go.Bar( name="East/NorthEast ES", x=data["labels"], y=data["enebes"], text=data["enebes"], offsetgroup=0, base=data["sles_base"], ), go.Bar( name="Dutchess ES", x=data["labels"], y=data["dutches"], text=data["dutches"], offsetgroup=0, base=data["enebes_base"], ), go.Bar( name="Northwest ES", x=data["labels"], y=data["nwppes"], text=data["nwppes"], offsetgroup=0, base=data["dutches_base"], ), go.Bar( name="M3 HS", x=data["labels"], y=data["mhs"], text=data["mhs"], offsetgroup=1, ), go.Bar( name="SL HS", x=data["labels"], y=data["slhs"], text=data["slhs"], offsetgroup=1, base=data["mhs"], ), go.Bar( name="M3 EC", x=data["labels"], y=data["mec"], text=data["mec"], offsetgroup=2, ), go.Bar( name="Sl EC", x=data["labels"], y=data["slec"], text=data["slec"], offsetgroup=2, base=data["mec"], ) ], layout=go.Layout( title="", yaxis_title="Actual Enrollment", xaxis_title="Years" ) ) fig.update_xaxes(type='category') fig.update_yaxes(dtick=500) fig.update_yaxes(range=[0, 9000]) fig.update_layout(barmode='group') fig.show()
可替代的Python可视化库
如果需要更简洁的实现方式,或对图表风格有不同需求,可以考虑以下库:
1. Matplotlib
Python最基础的可视化库,灵活性极强,通过bottom参数实现分组堆叠:
import matplotlib.pyplot as plt import pandas as pd df = pd.DataFrame(data).set_index('labels') x = range(len(df.index)) width = 0.25 # ES组堆叠 bottom = [0]*len(x) for col in ['mes', 'sles', 'enebes', 'dutches', 'nwppes']: plt.bar([i - width for i in x], df[col], width, label=col, bottom=bottom) bottom = [b + v for b, v in zip(bottom, df[col])] # HS组堆叠 bottom = [0]*len(x) for col in ['mhs', 'slhs']: plt.bar(x, df[col], width, label=col, bottom=bottom) bottom = [b + v for b, v in zip(bottom, df[col])] # EC组堆叠 bottom = [0]*len(x) for col in ['mec', 'slec']: plt.bar([i + width for i in x], df[col], width, label=col, bottom=bottom) bottom = [b + v for b, v in zip(bottom, df[col])] plt.xticks(x, df.index) plt.xlabel('Years') plt.ylabel('Actual Enrollment') plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left') plt.show()
2. Pandas Plot
基于Matplotlib,直接通过DataFrame快速生成分组堆叠图,代码极简:
import pandas as pd df = pd.DataFrame(data).set_index('labels') # 分组整理数据 es_df = df[['mes', 'sles', 'enebes', 'dutches', 'nwppes']] hs_df = df[['mhs', 'slhs']] ec_df = df[['mec', 'slec']] # 绘制分组堆叠图 ax = es_df.plot(kind='bar', stacked=True, width=0.25, position=0) hs_df.plot(kind='bar', stacked=True, width=0.25, position=1, ax=ax) ec_df.plot(kind='bar', stacked=True, width=0.25, position=2, ax=ax) ax.set_xlabel('Years') ax.set_ylabel('Actual Enrollment') ax.legend(bbox_to_anchor=(1.05, 1), loc='upper left') plt.show()
3. Seaborn
基于Matplotlib,专注统计可视化,语法简洁,可通过自定义实现分组堆叠,适合结合统计分析的场景,代码风格更统一。
4. Altair
声明式可视化库,语法清晰易懂,适合构建复杂交互图表,支持分组堆叠;通过分层语法定义图表结构,自动处理堆叠逻辑,代码可读性高。
内容的提问来源于stack exchange,提问作者user14929029
相关产品推荐
相关产品推荐

