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

Matplotlib堆叠柱状图叠加折线图不可见问题求助

问题

想要在每年地质灾害事件数的堆叠柱状图之上,添加一条代表某类地质灾害年占比的折线图。尝试使用ax.twinx()实现,但折线无法显示!

替换成普通柱状图时折线能正常显示,但堆叠柱状图不行,怀疑stacked参数存在问题。

原代码如下:

# Group data by year and count the number of events of each risk type
events_by_year_and_risk = data.groupby(['year', 'hazard'])['decision'].count().unstack()

# Calculate percentage of events that were 'drought'
total_by_year = data.groupby('ann_pub_jo')['decision'].count()
drought_by_year = data[data['hazard'] == 'drought'].groupby('year')['decision'].count()
percentage_by_year = (drought_by_year / total_by_year) * 100

# Create bar plot of events of each risk type per year
fig, ax = plt.subplots(figsize=(12, 6))
events_by_year_and_risk.plot(kind='bar', stacked=True, ax=ax)
ax.set_xlabel('Year')
ax.set_ylabel('Number of Events')
ax.set_title('Number of Events by Risk Type and Year')

# Create line plot of percentage of 'drought' events per year
ax2 = ax.twinx()
ax2.plot(percentage_by_year.index, percentage_by_year.values, color='red', marker='o', markersize=3, linewidth=2)
ax2.set_ylabel('Percentage of Drought Events')
ax2.yaxis.set_tick_params(length=5)
ax2.yaxis.set_major_formatter('{x:.0f}%')
ax2.set_ylim(0, 100)

# Adjust layout
fig.tight_layout()

# Show plot
plt.show()
原因分析
  • 分组字段不匹配:计算total_by_year时误用了ann_pub_jo作为分组字段,和后续的year字段不一致,导致percentage_by_year的索引与堆叠柱状图的x轴索引无法对齐,折线被隐藏在可视区域外。
  • x轴类型差异:pandas绘制堆叠柱状图时会将x轴转为分类变量(字符串类型),而percentage_by_year.index是数值型年份,直接绘制会出现坐标错位。
修复方案及代码

修正分组字段,并确保折线的x轴坐标与堆叠柱状图对齐,修复后的代码如下:

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.ticker import PercentFormatter

# 假设data为已加载的目标DataFrame
# 按年份和灾害类型分组统计事件数
events_by_year_and_risk = data.groupby(['year', 'hazard'])['decision'].count().unstack()

# 计算干旱事件的年占比
total_by_year = data.groupby('year')['decision'].count()  # 修正分组字段为year
drought_by_year = data[data['hazard'] == 'drought'].groupby('year')['decision'].count()
# 填充缺失年份的干旱事件数为0,避免索引不匹配
drought_by_year = drought_by_year.reindex(total_by_year.index, fill_value=0)
percentage_by_year = (drought_by_year / total_by_year) * 100

# 绘制堆叠柱状图
fig, ax = plt.subplots(figsize=(12, 6))
events_by_year_and_risk.plot(kind='bar', stacked=True, ax=ax)
ax.set_xlabel('Year')
ax.set_ylabel('Number of Events')
ax.set_title('Number of Events by Risk Type and Year')

# 绘制占比折线图
ax2 = ax.twinx()
# 使用堆叠柱状图的x轴分类位置绘制折线,确保坐标对齐
ax2.plot(ax.get_xticks(), percentage_by_year.values, color='red', marker='o', markersize=3, linewidth=2)
ax2.set_ylabel('Percentage of Drought Events')
ax2.yaxis.set_tick_params(length=5)
ax2.yaxis.set_major_formatter(PercentFormatter(decimals=0))  # 规范的百分比格式化方式
ax2.set_ylim(0, 100)

# 调整布局
fig.tight_layout()

# 显示图表
plt.show()
关键修复点
  • 将total_by_year的分组字段改为year,确保与其他数据的索引统一
  • 用reindex填充缺失年份的干旱事件数为0,避免出现NaN值导致折线中断
  • 折线绘制时使用ax.get_xticks()获取堆叠柱状图的x轴分类位置,解决坐标不匹配问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 16:05:35