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

Plotly-Dash:基于单DataFrame列实现两个并列堆叠柱状图

解决并列堆叠柱状图的问题

你之前的代码之所以会把两个图表叠加,是因为你把两个trace都绑定到了同一个x轴(df.Field.unique())上,导致它们在同一组x标签下堆叠,而不是生成两个独立的堆叠模块并列展示。接下来我会分两种方式帮你实现需求,同时附上Dash集成的方案。

方法1:单图内并列两个堆叠柱子

这种方式是在同一个图表里,用两个x类别分别承载Field和Issue的堆叠数据,最终呈现两个并列的堆叠柱子,总高度都是8:

import plotly.graph_objects as go
import pandas as pd

# 构造你的示例DataFrame
df = pd.DataFrame({
    'Field': ['Police', 'Research', 'Police', 'Banking', 'Healthcare', 'Research', 'Healthcare', 'Banking'],
    'Issue': ['Budget cuts', 'Budget cuts', 'Time consuming', 'Lack of oversight', 'Lack of support', 'Bureaucracy', 'Bureaucracy', 'Mistrust']
})

# 计算Field和Issue的计数
field_counts = df['Field'].value_counts().sort_index()
issue_counts = df['Issue'].value_counts().sort_index()

# 生成Field维度的堆叠trace
field_traces = []
for field, count in field_counts.items():
    field_traces.append(go.Bar(
        x=['Field Distribution'],  # 固定x轴标签为统一名称
        y=[count],
        name=field
    ))

# 生成Issue维度的堆叠trace
issue_traces = []
for issue, count in issue_counts.items():
    issue_traces.append(go.Bar(
        x=['Issue Distribution'],  # 另一个x轴标签
        y=[count],
        name=issue
    ))

# 组合数据并设置布局
fig = go.Figure(data=field_traces + issue_traces)
fig.update_layout(
    barmode='stack',  # 开启堆叠模式
    title='Field vs Issue Distribution',
    xaxis={'title': 'Distribution Type'},
    yaxis={'title': 'Count', 'range': [0, 8]},  # 固定y轴范围确保总高度为8
    height=500
)
fig.show()

方法2:双生子图(左右各一个堆叠图)

如果你想要两个独立的子图并列展示,每个子图对应一个维度的堆叠柱状图,可以用make_subplots实现:

from plotly.subplots import make_subplots
import plotly.graph_objects as go
import pandas as pd

df = pd.DataFrame({
    'Field': ['Police', 'Research', 'Police', 'Banking', 'Healthcare', 'Research', 'Healthcare', 'Banking'],
    'Issue': ['Budget cuts', 'Budget cuts', 'Time consuming', 'Lack of oversight', 'Lack of support', 'Bureaucracy', 'Bureaucracy', 'Mistrust']
})

field_counts = df['Field'].value_counts().sort_index()
issue_counts = df['Issue'].value_counts().sort_index()

# 创建1行2列的子图
fig = make_subplots(rows=1, cols=2, subplot_titles=('Field Distribution', 'Issue Distribution'))

# 给第一个子图添加Field的堆叠trace
for field, count in field_counts.items():
    fig.add_trace(
        go.Bar(x=[''], y=[count], name=field),
        row=1, col=1
    )

# 给第二个子图添加Issue的堆叠trace
for issue, count in issue_counts.items():
    fig.add_trace(
        go.Bar(x=[''], y=[count], name=issue),
        row=1, col=2
    )

# 统一设置布局
fig.update_layout(
    barmode='stack',
    height=400,
    width=800
)
fig.update_yaxes(range=[0, 8], title_text='Count')  # 固定y轴高度
fig.show()

集成到Dash框架

把上述图表集成到Dash里很简单,只需要把生成图表的逻辑放到Dash的回调函数中即可:

import dash
from dash import dcc, html
from dash.dependencies import Input, Output
import plotly.graph_objects as go
import pandas as pd

# 构造数据
df = pd.DataFrame({
    'Field': ['Police', 'Research', 'Police', 'Banking', 'Healthcare', 'Research', 'Healthcare', 'Banking'],
    'Issue': ['Budget cuts', 'Budget cuts', 'Time consuming', 'Lack of oversight', 'Lack of support', 'Bureaucracy', 'Bureaucracy', 'Mistrust']
})

field_counts = df['Field'].value_counts().sort_index()
issue_counts = df['Issue'].value_counts().sort_index()

# 初始化Dash应用
app = dash.Dash(__name__)

app.layout = html.Div([
    html.H1('Field & Issue Distribution Dashboard'),
    dcc.Graph(id='stacked-bar-charts')
])

# 回调函数生成图表
@app.callback(
    Output('stacked-bar-charts', 'figure'),
    Input('stacked-bar-charts', 'id')  # 触发初始化,可根据需求添加其他交互输入
)
def render_stacked_charts(_):
    field_traces = []
    for field, count in field_counts.items():
        field_traces.append(go.Bar(
            x=['Field Distribution'],
            y=[count],
            name=field
        ))
    
    issue_traces = []
    for issue, count in issue_counts.items():
        issue_traces.append(go.Bar(
            x=['Issue Distribution'],
            y=[count],
            name=issue
        ))
    
    fig = go.Figure(data=field_traces + issue_traces)
    fig.update_layout(
        barmode='stack',
        xaxis_title='Distribution Type',
        yaxis_title='Count',
        yaxis_range=[0, 8],
        height=500
    )
    return fig

if __name__ == '__main__':
    app.run_server(debug=True)

运行这段代码后,你就能在浏览器中看到集成了目标图表的Dash应用了。

内容的提问来源于stack exchange,提问作者user8322222

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:46:30