You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用mplfinance绘制共享X轴的多子图时,子图无数据、标题不显示的问题咨询

解决mplfinance多子图带成交量不显示的问题

这个问题我之前折腾过好一会儿,核心原因是:当你开启volume=True时,mplfinance会自动创建两个坐标轴(上方的价格轴+下方的成交量轴),而你之前只传递了一个ax参数,mplfinance没办法正确把内容映射到你手动创建的子图里,最后就导致轴范围被重置成默认的0-1,数据和标题都没显示出来。

下面给你两种靠谱的解决方案,都是我实际用过的:

方案1:用GridSpec手动分配双轴位置(推荐,更灵活)

这种方式直接在matplotlib的画布上给每个币种分配两行空间,分别放价格轴和成交量轴,然后明确告诉mplfinance该用哪个轴:

import mplfinance as mpf
from matplotlib import pyplot as plt
from matplotlib.gridspec import GridSpec

N = len(df_coins)
# 创建主画布,高度按子图数量比例设置
fig = plt.figure(figsize=(20, 5*N))
# 生成网格:每个币种占2行(价格+成交量),整列宽度
gs = GridSpec(2*N, 1, figure=fig)

for idx, (coin, df) in enumerate(df_coins.items()):
    # 给当前币种创建价格轴和成交量轴,共享X轴避免重复标签
    ax_price = fig.add_subplot(gs[2*idx, 0])
    ax_volume = fig.add_subplot(gs[2*idx+1, 0], sharex=ax_price)
    
    # 绘制时明确指定价格轴和成交量轴
    mpf.plot(df, 
             ax=ax_price, 
             volume_ax=ax_volume,
             title=coin, 
             type='line', 
             volume=True, 
             show_nontrading=True)

# 自动调整子图间距,防止标题和轴标签重叠
plt.tight_layout()
plt.show()

方案2:利用mplfinance的returnfig参数整合轴

如果不想手动管理网格,可以让mplfinance自己生成每个图表的轴,再把这些轴移植到主画布上:

import mplfinance as mpf
from matplotlib import pyplot as plt

N = len(df_coins)
fig = plt.figure(figsize=(20, 5*N))

for idx, (coin, df) in enumerate(df_coins.items()):
    # 让mplfinance返回它生成的图形和坐标轴对象
    mpf_fig, mpf_axes = mpf.plot(df, 
                                 title=coin, 
                                 type='line', 
                                 volume=True, 
                                 show_nontrading=True,
                                 returnfig=True)
    # 取出mplfinance生成的价格轴和成交量轴
    ax_price, ax_volume = mpf_axes
    
    # 将这两个轴绑定到我们的主画布上
    ax_price.figure = fig
    ax_volume.figure = fig
    fig.axes.append(ax_price)
    fig.axes.append(ax_volume)
    
    # 设置轴的位置:每个币种占5单位高度,成交量轴高度设为价格轴的1/3
    # 这里的坐标是画布的相对位置(0-1)
    price_pos = [0.1, 1 - (idx+1)*5/fig.get_figheight(), 0.8, 3.5/fig.get_figheight()]
    vol_pos = [0.1, 1 - (idx+1)*5/fig.get_figheight() + 0.2, 0.8, 1.3/fig.get_figheight()]
    ax_price.set_position(price_pos)
    ax_volume.set_position(vol_pos)

plt.tight_layout()
plt.show()

额外提示

  • 如果你不需要成交量图,只传ax=ax就可以正常工作,但只要开了volume=True,就必须指定volume_ax或者用returnfig=True的方式处理双轴。
  • 方案1里的sharex=ax_price已经帮你实现了共享X轴,不会再出现重复的X标签啦。

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

火山引擎 最新活动