如何在同一图表中展示资产与负债的两个堆叠面积图
如何在同一图表中展示资产与负债的两个堆叠面积图
当然可以把资产和负债的堆叠面积图合并到同一张图表里!而且这种展示方式非常符合资产负债表的直观逻辑——资产显示在x轴上方(正数区域),负债显示在x轴下方(负数区域),两者形成清晰的对比。我给你两种可行的实现方案:
方案一:合并明细数据后用Plotly Express绘制(简洁高效)
这种方法通过合并资产和负债的明细数据集,一次调用px.area就能完成堆叠展示,再补充添加总览线即可,代码简洁易维护。
步骤说明:
- 给资产、负债的明细数据分别添加标识后缀,避免图例混淆
- 合并两个数据集(负债数值保持负数,会自动显示在x轴下方)
- 绘制堆叠面积图并添加资产、负债的总览线
- 优化图表布局(比如添加x轴参考线、调整标题)
代码示例:
import pandas as pd import plotly.express as px import plotly.graph_objects as go import streamlit as st # 1. 预处理明细数据,添加类别标识避免图例冲突 df_assets_detail = df_all.copy() df_assets_detail['fact'] = df_assets_detail['fact'] + " (Asset)" df_liabilities_detail = df_all_liabilities.copy() df_liabilities_detail['fact'] = df_liabilities_detail['fact'] + " (Liability)" # 2. 合并资产与负债的明细数据集 df_combined = pd.concat([df_assets_detail, df_liabilities_detail], ignore_index=True) # 3. 绘制基础堆叠面积图 fig = px.area( df_combined, x='end', y='val', color='fact', title=f'{symbol.upper()} : Combined Balance Sheet (Assets + Liabilities)', width=1000, height=600 ) # 4. 添加资产总览线 fig.add_trace(go.Scatter( x=df_assets['end'], y=df_assets['val'], mode='lines', name='Total Assets', line=dict(color='darkgreen', width=2) )) # 5. 添加负债总览线 fig.add_trace(go.Scatter( x=df_liabilities['end'], y=df_liabilities['val'], mode='lines', name='Total Liabilities', line=dict(color='darkred', width=2) )) # 6. 优化布局:添加x轴参考线,调整y轴标签 fig.update_layout( yaxis_title='Monetary Value', shapes=[dict( type='line', x0=df_combined['end'].min(), x1=df_combined['end'].max(), y0=0, y1=0, line=dict(color='black', width=1, dash='dash') )] ) # 渲染图表 st.plotly_chart(fig)
方案二:手动添加Trace(灵活可控)
如果你需要更精细地控制每个堆叠层的样式(比如填充透明度、线条颜色),可以直接用go.Figure()手动添加资产、负债的面积Trace,这种方式自由度更高。
代码示例:
import plotly.graph_objects as go import streamlit as st # 初始化空图表 fig = go.Figure() # 1. 逐个添加资产的堆叠面积层 for fact_name in df_all['fact'].unique(): df_sub = df_all[df_all['fact'] == fact_name] fig.add_trace(go.Scatter( x=df_sub['end'], y=df_sub['val'], fill='tonexty', # 开启堆叠填充 name=f"{fact_name} (Asset)", mode='none', # 只显示面积,不显示数据点 opacity=0.7 # 可自定义填充透明度 )) # 2. 逐个添加负债的堆叠面积层 for fact_name in df_all_liabilities['fact'].unique(): df_sub = df_all_liabilities[df_all_liabilities['fact'] == fact_name] fig.add_trace(go.Scatter( x=df_sub['end'], y=df_sub['val'], fill='tonexty', name=f"{fact_name} (Liability)", mode='none', opacity=0.7 )) # 3. 添加资产总览线 fig.add_trace(go.Scatter( x=df_assets['end'], y=df_assets['val'], mode='lines', name='Total Assets', line=dict(color='darkgreen', width=2) )) # 4. 添加负债总览线 fig.add_trace(go.Scatter( x=df_liabilities['end'], y=df_liabilities['val'], mode='lines', name='Total Liabilities', line=dict(color='darkred', width=2) )) # 5. 调整图表布局 fig.update_layout( title=f'{symbol.upper()} : Combined Balance Sheet', width=1000, height=600, yaxis_title='Monetary Value', shapes=[dict( type='line', x0=df_all['end'].min(), x1=df_all['end'].max(), y0=0, y1=0, line=dict(color='black', width=1, dash='dash') )] ) # 渲染图表 st.plotly_chart(fig)
关键注意事项
- 负债数值保持负数:这是让负债自动显示在x轴下方的核心,不需要额外调整y轴范围,Plotly会自动适配正负区间。
- 图例区分:给资产、负债的明细项分别添加后缀(比如
(Asset)/(Liability)),避免同名明细项在图例中混淆。 - 参考线优化:添加x轴的虚线参考线,能更清晰地分隔资产和负债区域。
这样实现后,你就能在同一张图表里同时看到资产的正向堆叠和负债的负向堆叠,还能通过总览线快速把握整体趋势~
备注:内容来源于stack exchange,提问作者dharmatech




