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
相关产品推荐
相关产品推荐

