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

如何用mplfinance将OHLC图X轴设置为固定季度刻度?

问题与解决方案

问题

编写程序为指定资产生成OHLC价格图时,需要将X轴刻度设置为每年固定月份的季度形式(如1、4、7、10月),但遇到以下问题:

  • 使用MonthLocator(interval=3)时,刻度起始月份不固定,无法满足需求;
  • 使用DateFormatter('%b %Y')时,出现日期标签重叠,甚至显示1969年错误日期的问题。

解决方案

关键修复点

  1. 固定季度刻度位置:使用MonthLocator(bymonth=[1,4,7,10])直接指定每年的季度起始月份,替代interval=3的方式,确保刻度始终落在1、4、7、10月。
  2. 解决标签重叠与错误日期:
    • 应用DateFormatter('%b %Y')格式化日期标签,并通过旋转标签、调整对齐方式避免重叠;
    • 确保数据索引为有效datetime类型,同时限定刻度生成范围在数据的起始与结束日期之间,避免无效时间戳导致的1969年错误。

修改后的完整代码

import mplfinance as mpf
import yfinance as yf
import matplotlib.pyplot as plt
from datetime import datetime
from matplotlib.ticker import MaxNLocator
from matplotlib.dates import MonthLocator, DateFormatter
import pandas as pd
import os  # 补充缺失的os导入

#%% Creamos la clase que grafica la lista de activos que desee ver, desde la fecha que querramos.
class Grafico:
    def __init__(self, assets, start_date):
        
        self.assets = assets
        self.start_date = start_date
        self.end= datetime.now()
        self.start=datetime.strptime(self.start_date, '%Y-%m-%d')
        
        self.days=(self.end-self.start).days
        
        self.CCL= self.CCL_f()
        
    def CCL_f(self):
        GGAL=yf.download('GGAL', start=self.start_date)
        GGAL_BA=yf.download('GGAL.BA',start=self.start_date)
        CCL=(GGAL_BA/GGAL)*10
        return CCL
    
        

    def plot(self):
        for file in os.listdir(): #Esto borrará los archivos viejos, para que cada vez que se ejecute el programa aparezcan en carpeta los gráficos que se quieren descargar
            if file.endswith('.png'):
                try:
                    os.remove(file)
                except Exception as e:
                    print(f'Error deleting {file}: {e}')
        for asset in self.assets:
            if ".BA" in asset:
                data = yf.download(asset, start=self.start_date, end=self.end)
                data= data/self.CCL
                self.data=data
                if asset=="BYMA.BA":
                    self.data= self.data.drop("2018-12-31")
            else:
                data = yf.download(asset, start=self.start_date, end=self.end)
                self.data=data
            
            fig, ax = mpf.plot(self.data, type='candle', style='classic',figscale=1.5, tight_layout=False, returnfig=True)
            fig.set_size_inches(11.692913385826772,8)
            ax[0].yaxis.set_major_locator(MaxNLocator(nbins=30))
            
            # --- 修复X轴刻度的核心代码 ---
            # 指定固定季度月份的刻度定位器
            locator = MonthLocator(bymonth=[1,4,7,10])
            # 设置刻度显示范围为数据的起止日期
            locator.set_axis(ax[0].xaxis)
            locator.set_view_interval(*ax[0].get_xlim())
            
            # 设置日期格式
            formatter = DateFormatter('%b %Y')
            ax[0].xaxis.set_major_locator(locator)
            ax[0].xaxis.set_major_formatter(formatter)
            
            # 旋转X轴标签,避免重叠
            plt.setp(ax[0].get_xticklabels(), rotation=45, ha='right', fontsize=5)
            # --- 核心代码结束 ---
            
            ax[0].tick_params(axis='y', labelsize=5)
            last_price = self.data['Close'].iloc[-1]
            ax[0].axhline(y=last_price, linestyle='--', color='k',linewidth=0.5)
            ax[0].set_title(f'{asset} - (Last {self.days} days)',fontsize=15, loc='center')
            plt.savefig(f'{asset}.png',bbox_inches='tight', dpi=300)

说明

  • MonthLocator(bymonth=[1,4,7,10])强制刻度仅出现在每年的1、4、7、10月,彻底解决起始月份不固定的问题;
  • plt.setp(ax[0].get_xticklabels(), rotation=45, ha='right')将标签旋转45度并右对齐,有效避免日期重叠;
  • 通过locator.set_view_interval(*ax[0].get_xlim())限定刻度生成范围,避免无效时间戳导致的1969年错误日期显示。

内容的提问来源于stack exchange,提问作者Agustín Ehrman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 23:20:40