mplfinance图表指定区域无法着色的原因及解决方法
问题:mplfinance绘制K线图时指定区域着色不显示
环境:matplotlib v3.7.0、mplfinance v0.12.9b7、Python 3.10
尝试为mplfinance绘制的股票K线图指定区域添加着色,但着色区域未显示,代码如下:
import yfinance as yf import mplfinance as mpf import pandas as pd # Download the stock data df = yf.download('TSLA', start='2022-01-01', end='2022-03-31') # Define the date ranges for shading red_range = ['2022-01-15', '2022-02-15'] blue_range = ['2022-03-01', '2022-03-15'] # Create a function to shade the chart regions def shade_region(ax, region_dates, color): region_dates.sort() start_date = region_dates[0] end_date = region_dates[1] # plot vertical lines ax.axvline(pd.to_datetime(start_date), color=color, linestyle='--') ax.axvline(pd.to_datetime(end_date), color=color, linestyle='--') # create fill xmin, xmax = ax.get_xlim() ymin, ymax = ax.get_ylim() ax.fill_between(pd.date_range(start=start_date, end=end_date), ymin, ymax, alpha=0.2, color=color) ax.set_xlim(xmin, xmax) ax.set_ylim(ymin, ymax) # Plot the candlestick chart with volume fig, axlist = mpf.plot(df, type='candle', volume=True, style='charles', title='TSLA Stock Price', ylabel='Price ($)', ylabel_lower='Shares Traded', figratio=(2,1), figsize=(10,5), tight_layout=True, returnfig=True) # Get the current axis object ax = axlist[0] # Shade the regions on the chart shade_region(ax, red_range, 'red') shade_region(ax, blue_range, 'blue') # Show the plot mpf.show()
原因与修复方案
问题原因
- 坐标轴数值类型不匹配:mplfinance绘制K线图时,x轴实际使用的是整数索引(对应DataFrame的行号),而非直接的日期时间值。用
pd.date_range生成的日期序列无法匹配x轴的索引,导致填充区域不在可视范围内。 fill_between参数错误:fill_between的第一个参数应该是x轴的数值范围(即对应日期的行索引),而非日期对象,直接传入日期会导致填充逻辑失效。
修复步骤
方案一:利用mplfinance内置功能(推荐)
mplfinance原生支持通过fills和vlines参数添加着色区域与分割线,无需手动操作坐标轴:
import yfinance as yf import mplfinance as mpf import pandas as pd df = yf.download('TSLA', start='2022-01-01', end='2022-03-31') # 将日期转换为DataFrame对应的索引位置 def get_date_indices(df, start_date, end_date): start_idx = df.index.get_loc(pd.to_datetime(start_date)) end_idx = df.index.get_loc(pd.to_datetime(end_date)) return start_idx, end_idx red_start, red_end = get_date_indices(df, '2022-01-15', '2022-02-15') blue_start, blue_end = get_date_indices(df, '2022-03-01', '2022-03-15') # 配置着色区域和垂直分割线 fills = [ {'x': (red_start, red_end), 'color': 'red', 'alpha': 0.2}, {'x': (blue_start, blue_end), 'color': 'blue', 'alpha': 0.2} ] vlines = [ {'x': red_start, 'color': 'red', 'linestyle': '--'}, {'x': red_end, 'color': 'red', 'linestyle': '--'}, {'x': blue_start, 'color': 'blue', 'linestyle': '--'}, {'x': blue_end, 'color': 'blue', 'linestyle': '--'} ] # 绘制图表 mpf.plot(df, type='candle', volume=True, style='charles', title='TSLA Stock Price', ylabel='Price ($)', ylabel_lower='Shares Traded', figratio=(2,1), figsize=(10,5), tight_layout=True, fills=fills, vlines=vlines)
方案二:修改原函数适配坐标轴
如果坚持使用原有函数结构,需将日期转换为x轴索引值,调整fill_between的参数:
import yfinance as yf import mplfinance as mpf import pandas as pd df = yf.download('TSLA', start='2022-01-01', end='2022-03-31') red_range = ['2022-01-15', '2022-02-15'] blue_range = ['2022-03-01', '2022-03-15'] def shade_region(ax, df, region_dates, color): region_dates.sort() start_date = pd.to_datetime(region_dates[0]) end_date = pd.to_datetime(region_dates[1]) # 获取日期对应的x轴索引 start_idx = df.index.get_loc(start_date) end_idx = df.index.get_loc(end_date) # 绘制垂直分割线 ax.axvline(start_idx, color=color, linestyle='--') ax.axvline(end_idx, color=color, linestyle='--') # 获取y轴范围并填充区域 ymin, ymax = ax.get_ylim() ax.fill_between([start_idx, end_idx], ymin, ymax, alpha=0.2, color=color) fig, axlist = mpf.plot(df, type='candle', volume=True, style='charles', title='TSLA Stock Price', ylabel='Price ($)', ylabel_lower='Shares Traded', figratio=(2,1), figsize=(10,5), tight_layout=True, returnfig=True) ax = axlist[0] shade_region(ax, df, red_range, 'red') shade_region(ax, df, blue_range, 'blue') mpf.show()
内容的提问来源于stack exchange,提问作者Homunculus Reticulli
相关产品推荐
相关产品推荐

