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

Matplotlib股票均线图条件背景色偏移问题原因排查

问题原因与修复方案

核心问题分析

你的代码出现背景色偏移、错误渲染的原因有三个:

  • x轴坐标不匹配:matplotlib处理时间序列时会把datetime索引转为内部浮点值,但pcolorfast默认从x=0开始映射数据,和实际x轴的日期坐标完全错位,导致颜色块和数据点偏移半个区间,末尾颜色对应错误。
  • NaN的错误渲染:pcolorfast不会自动忽略NaN值,而是用颜色映射的邻接值或中间值填充NaN区域,前9个无EMA的NaN数据被错误渲染成红色。
  • 区间映射逻辑不匹配:pcolorfast是为二维网格设计的,每个数据值对应一个矩形区间(x从i到i+1),但你的折线图是基于离散点绘制的,两者的位置逻辑不兼容。

修复后的代码

from yahoo_fin import stock_info as si
import talib
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

sym = 'SBUX'
data = si.get_data(sym, start_date='01/01/2022')
data['ma10'] = talib.EMA(data['close'], 10)
conditions = [(data['close'] / data['ma10'] - 1 > 0.05), 
              (data['close'] / data['ma10'] - 1 < -0.05)]
values = [1, -1]

data['above_below'] = np.select(conditions, values, default=0)  # 用0替换NaN,对应黄色中间色
fig, ax = plt.subplots()

# 绘制收盘价和均线
ax.plot(data.close, label='Close')
ax.plot(data.ma10, label='10-day EMA')

# 将datetime索引转为matplotlib的数值坐标
x = mdates.date2num(data.index)
# 生成pcolorfast需要的x区间边界(n个点对应n+1个边界)
x_bounds = np.concatenate([x, [x[-1] + (x[1] - x[0])]])
# 获取y轴的上下限
y_bounds = ax.get_ylim()

# 绘制背景色,确保x区间和数据点对齐,设置vmin/vmax固定颜色映射
ax.pcolorfast(x_bounds, y_bounds, data['above_below'].values[np.newaxis], 
              cmap='RdYlGn', vmin=-1, vmax=1, alpha=0.3)

# 添加图例和格式化x轴日期
ax.legend()
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

关键修改说明

  1. 替换NaN为0:把default=np.nan改成default=0,这样无EMA的区域会显示黄色(RdYlGn的中间色),避免错误填充邻接颜色。如果想让这些区域透明,可以用np.ma.masked_invalid(data['above_below'])生成掩码数组,pcolorfast会忽略掩码区域。
  2. 匹配x轴坐标:用mdates.date2num把日期转为matplotlib的数值坐标,再生成包含区间边界的x_bounds,确保每个颜色块对应两个相邻日期之间的区间,和折线图的点位置完全对齐。
  3. 固定颜色映射范围:设置vmin=-1和vmax=1,保证1对应绿色、-1对应红色,不会因为数据分布变化导致颜色偏移。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 04:20:58