如何在子图K线图上添加移动平均线(SMA)并解决报错
使用mplfinance在子图K线添加SMA时的错误解决与数据修正
错误原因分析
1. make_addplot未指定对应外部Axes
当使用外部Matplotlib Axes(即通过plt.subplots()手动创建的子图轴)时,mpf.make_addplot()必须明确指定ax参数,告知mplfinance要将附加绘图绘制到哪个轴上。原代码中创建addplot时未指定该参数,导致mplfinance无法匹配对应外部子图,触发类型错误。
2. 数据不匹配逻辑错误
原代码中将基于10年月度数据计算的8-Month SMA,错误添加到5年周度K线图上,两者时间维度、数据频率完全不匹配,既会导致绘图异常,也不符合技术分析逻辑。
完整修正代码
import yfinance as yf import matplotlib.pyplot as plt import mplfinance as mpf # 定义标的与时间范围 ticker_symbol = "AAPL" start_date_1 = "2013-09-24" end_date_1 = "2023-09-24" start_date_2 = "2017-09-24" end_date_2 = "2023-09-24" start_date_3 = "2022-09-24" end_date_3 = "2023-09-24" start_date_4 = "2023-03-24" end_date_4 = "2023-09-24" # 获取数据并计算对应周期SMA # 10年月度数据 + 8月SMA apple_ohlc_1 = yf.download(ticker_symbol, start=start_date_1, end=end_date_1, interval="1mo") apple_ohlc_1["8-Month SMA"] = apple_ohlc_1["Close"].rolling(8).mean() # 5年周度数据 + 40周SMA apple_ohlc_2 = yf.download(ticker_symbol, start=start_date_2, end=end_date_2, interval="1wk") apple_ohlc_2["40-Week SMA"] = apple_ohlc_2["Close"].rolling(40).mean() # 1年日线数据 + 50/200日SMA apple_ohlc_3 = yf.download(ticker_symbol, start=start_date_3, end=end_date_3, interval="1d") apple_ohlc_3["50-Day SMA"] = apple_ohlc_3["Close"].rolling(50).mean() apple_ohlc_3["200-Day SMA"] = apple_ohlc_3["Close"].rolling(200).mean() # 6个月日线数据 + 50/200日SMA apple_ohlc_4 = yf.download(ticker_symbol, start=start_date_4, end=end_date_4, interval="1d") apple_ohlc_4["50-Day SMA"] = apple_ohlc_4["Close"].rolling(50).mean() apple_ohlc_4["200-Day SMA"] = apple_ohlc_4["Close"].rolling(200).mean() # 创建2x2子图布局 fig, axs = plt.subplots(2, 2, figsize=(30, 22)) # -------------------------- 第一个子图:10年月度K线 + 8月SMA -------------------------- ap1 = mpf.make_addplot(apple_ohlc_1["8-Month SMA"], color="b", label="8-Month SMA", ax=axs[0,0]) mpf.plot(apple_ohlc_1, type='candle', ax=axs[0,0], style='yahoo', xrotation=0, addplot=ap1) axs[0,0].set_title("Apple 10-Year Monthly Chart") axs[0,0].set_xlabel("Date") axs[0,0].set_ylabel("Price") axs[0,0].legend() axs[0,0].grid() # -------------------------- 第二个子图:5年周度K线 + 40周SMA -------------------------- ap2 = mpf.make_addplot(apple_ohlc_2["40-Week SMA"], color="r", label="40-Week SMA", ax=axs[0,1]) mpf.plot(apple_ohlc_2, type='candle', ax=axs[0,1], style='yahoo', xrotation=0, addplot=ap2) axs[0,1].set_title("Apple 5-Year Weekly Chart") axs[0,1].set_xlabel("Date") axs[0,1].set_ylabel("Price") axs[0,1].legend() axs[0,1].grid() # -------------------------- 第三个子图:1年日线K线 + 50/200日SMA -------------------------- ap3_1 = mpf.make_addplot(apple_ohlc_3["50-Day SMA"], color="g", label="50-Day SMA", ax=axs[1,0]) ap3_2 = mpf.make_addplot(apple_ohlc_3["200-Day SMA"], color="orange", label="200-Day SMA", ax=axs[1,0]) mpf.plot(apple_ohlc_3, type='candle', ax=axs[1,0], style='yahoo', xrotation=0, addplot=[ap3_1, ap3_2]) axs[1,0].set_title("Apple 1-Year Daily Chart") axs[1,0].set_xlabel("Date") axs[1,0].set_ylabel("Price") axs[1,0].legend() axs[1,0].grid() # -------------------------- 第四个子图:6个月日线K线 + 50/200日SMA -------------------------- ap4_1 = mpf.make_addplot(apple_ohlc_4["50-Day SMA"], color="g", label="50-Day SMA", ax=axs[1,1]) ap4_2 = mpf.make_addplot(apple_ohlc_4["200-Day SMA"], color="orange", label="200-Day SMA", ax=axs[1,1]) mpf.plot(apple_ohlc_4, type='candle', ax=axs[1,1], style='yahoo', xrotation=0, addplot=[ap4_1, ap4_2]) axs[1,1].set_title("Apple 6-Month Daily Chart") axs[1,1].set_xlabel("Date") axs[1,1].set_ylabel("Price") axs[1,1].legend() axs[1,1].grid() plt.tight_layout() plt.show()
关键修改点说明
- 指定addplot的ax参数:每个
mpf.make_addplot()都添加ax=axs[row, col],明确绑定到对应的子图轴,解决类型错误。 - 修正数据匹配:第一个子图的K线数据改为
apple_ohlc_1(月度数据),与8-Month SMA时间频率一致,其他子图同理匹配对应周期的SMA。 - 多SMA添加方式:需要添加多条均线时,将多个addplot对象放入列表传入
addplot参数。 - 优化布局:添加
plt.tight_layout()避免子图标题、标签重叠。
内容的提问来源于stack exchange,提问作者Kituva Ravindran Praveen
相关产品推荐
相关产品推荐

