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

matplotlib中ax.axvspan绘图无显示无报错问题求解

matplotlib axvspan 高亮区域不显示问题排查解决

问题现象

调用ax.axvspan()添加垂直区间高亮时无报错,但目标区域不在生成图片中显示,原始运行效果如下:
运行效果截图

原始代码片段:

fig = plt.figure(figsize=(15, 6))
ax = fig.add_subplot(111)

xtime       = np.linspace(1,372,372)
ax.plot(xtime, sp12, 'black', alpha=1.00, linewidth=2)
ax.fill_between(xtime, 0., sp12, sp12> 0., color='blue', alpha=.75)
ax.fill_between(xtime, 0., sp12, sp12< 0., color='red',  alpha=.75)

plt.xlabel('Years')
plt.ylabel('SPI')
plt.title('SPI-12 Macuelizo[ (1985-2015)', fontsize=12)
ax.axhline(-0.6, color='red', label='SPI - 0.6')
ax.axhline(-1.3, color='magenta', label='SPI - 1.3')
ax.axvspan(1997, 1998, color='magenta', alpha=0.7)

ax.set_xlim(0, 372)
ax.set_ylim(-4, 3)
ax.set_xticklabels(range(1985,2016,1*4))

plt.grid(True)
plt.legend()
ax.autoscale_view()

plt.savefig('SP12_macuelizo.jpg')

根因分析

问题核心是传入axvspan的坐标和x轴实际数值范围完全不匹配:

  • 代码中x轴实际取值是0~372,对应1985-2015年共372个月份的序列索引,本身不存在1997、1998这两个坐标点
  • axvspan(1997,1998)把高亮块画到了x轴1997~1998的位置,远超出set_xlim(0,372)设置的可视范围,matplotlib不会渲染可视区域外的元素,也不会抛出坐标越界的错误
  • 额外隐患:直接调用set_xticklabels修改刻度标签但未设置对应刻度位置,会导致年份标签和实际x轴位置错位,就算高亮位置正确也会出现标签和区域对不齐的问题;末尾的autoscale_view()会自动调整坐标轴范围,容易把可视区域拉偏。

修复方案

  • 先把需要高亮的年份转换成x轴对应的序列索引:x轴从1985年1月(x=1位置)开始计数,年份y对应的x坐标为(y-1985)*12
  • 用转换后的坐标替换axvspan中直接写的年份数值
  • 先设置x轴刻度位置,再绑定年份标签,避免错位
  • 移除多余的autoscale_view()调用,防止坐标轴范围被自动修改

修正后代码

fig = plt.figure(figsize=(15, 6))
ax = fig.add_subplot(111)

xtime = np.linspace(1,372,372)
ax.plot(xtime, sp12, 'black', alpha=1.00, linewidth=2)
ax.fill_between(xtime, 0., sp12, sp12> 0., color='blue', alpha=.75)
ax.fill_between(xtime, 0., sp12, sp12< 0., color='red',  alpha=.75)

plt.xlabel('Years')
plt.ylabel('SPI')
plt.title('SPI-12 Macuelizo (1985-2015)', fontsize=12)
ax.axhline(-0.6, color='red', label='SPI - 0.6')
ax.axhline(-1.3, color='magenta', label='SPI - 1.3')

# 转换高亮年份为x轴实际坐标
highlight_start = (1997 - 1985) * 12
highlight_end = (1998 - 1985) * 12
ax.axvspan(highlight_start, highlight_end, color='magenta', alpha=0.7, label='1997-1998')

ax.set_xlim(0, 372)
ax.set_ylim(-4, 3)
# 先设置刻度位置再绑定标签,避免错位
tick_pos = [(y - 1985)*12 for y in range(1985,2016,4)]
ax.set_xticks(tick_pos)
ax.set_xticklabels(range(1985,2016,4))

plt.grid(True)
plt.legend()

plt.savefig('SP12_macuelizo.jpg', dpi=300, bbox_inches='tight')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 07:06:48