You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 05:30:59