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

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()

原因与修复方案

问题原因

  1. 坐标轴数值类型不匹配:mplfinance绘制K线图时,x轴实际使用的是整数索引(对应DataFrame的行号),而非直接的日期时间值。用pd.date_range生成的日期序列无法匹配x轴的索引,导致填充区域不在可视范围内。
  2. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 05:37:47