使用 matplotlib 在烛台图表中叠加数据

Overlaying data in a candlestick chart using matplotlib

我的第一个需要是在烛台图表上叠加一条曲线。 要绘制此烛台图表,mplfinance 看起来非常好。不幸的是,我没有找到在烛台上叠加额外曲线的方法。

考虑下面的示例,如果你们中有人知道如何将 'Noise' 列覆盖在从 'minutely' 数据框绘制的烛台上,那就太好了!

import pandas as pd
import mplfinance as mpf

minutely = pd.DataFrame({'Date':[pd.Timestamp('2021-01-07 00:00:00'),
                                 pd.Timestamp('2021-01-07 00:01:00'),
                                 pd.Timestamp('2021-01-07 00:02:00'),
                                 pd.Timestamp('2021-01-07 00:03:00'),
                                 pd.Timestamp('2021-01-07 00:04:00')],
                          'Open':[36769.36, 36880.00, 36851.42,36922.19,37083.18],
                          'High':[36880.00, 36880.00, 36950.00, 37089.69, 37094.70],
                          'Low': [36760.00,  36817.64, 36810.03, 36922.13, 36565.49],
                          'Close':[36880.00, 36851.97, 36922.14, 37075.80, 36691.3]})

noise = pd.DataFrame({'Date':[pd.Timestamp('2021-01-07 00:00:00'),
                                 pd.Timestamp('2021-01-07 00:01:00'),
                                 pd.Timestamp('2021-01-07 00:02:00'),
                                 pd.Timestamp('2021-01-07 00:03:00'),
                                 pd.Timestamp('2021-01-07 00:04:00')],
                          'Noise':[36779.36, 36870.00, 36881.42,36902.19,37103.18]})

# Draw candlesticks
minutely = minutely.set_index('Date')
noise = noise.set_index('Date')
mpf.plot(minutely, type='candle')

不止于此,我想使用 'old' candlestick_ohlcv 函数绘制烛台图,然后使用本机 matplotlib 功能叠加数据。 这给出了下面的代码,但是当显示烛台时,x 标度显得毫无意义。

我应该只有 5 根蜡烛,x 刻度从 2020/01/07 00:00 到 2020/01/07 00:04。

我可以看到图表显示了从 2020/01/06 16:48 到 2020/01/07 07:12 的 x 比例尺。

我不明白这个,蜡烛没有意义...

import pandas as pd
import matplotlib.pyplot as plt 
from mplfinance.original_flavor import candlestick_ohlc
import matplotlib.dates as mpdates 

minutely = pd.DataFrame({'Date':[pd.Timestamp('2021-01-07 00:00:00'),
                                 pd.Timestamp('2021-01-07 00:01:00'),
                                 pd.Timestamp('2021-01-07 00:02:00'),
                                 pd.Timestamp('2021-01-07 00:03:00'),
                                 pd.Timestamp('2021-01-07 00:04:00')],
                          'Open':[36769.36, 36880.00, 36851.42,36922.19,37083.18],
                          'High':[36880.00, 36880.00, 36950.00, 37089.69, 37094.70],
                          'Low': [36760.00,  36817.64, 36810.03, 36922.13, 36565.49],
                          'Close':[36880.00, 36851.97, 36922.14, 37075.80, 36691.3]})

noise = pd.DataFrame({'Date':[pd.Timestamp('2021-01-07 00:00:00'),
                                 pd.Timestamp('2021-01-07 00:01:00'),
                                 pd.Timestamp('2021-01-07 00:02:00'),
                                 pd.Timestamp('2021-01-07 00:03:00'),
                                 pd.Timestamp('2021-01-07 00:04:00')],
                          'Noise':[36779.36, 36870.00, 36881.42,36902.19,37103.18]})

minutely['Date'] = minutely['Date'].map(mpdates.date2num)

plt.style.use('dark_background')
fig, ax = plt.subplots() 
candlestick_ohlc(ax, minutely.values, width = 0.6,  
                 colorup = 'green', colordown = 'red',  
                 alpha = 0.8) 
# Setting labels  
ax.set_xlabel('Date') 
ax.set_ylabel('Price')
# Formatting Date
date_format = mpdates.DateFormatter('%d-%m-%Y %H:%M') 
ax.xaxis.set_major_formatter(date_format) 
fig.autofmt_xdate() 
fig.tight_layout() 
# show the plot 
plt.show()

请问有人知道将此外部数据叠加到烛台数据的方法吗? 在此先感谢您的帮助, 最佳,

您可以使用 returnfig=True 参数获取 matplotlib Figure 和 Axes 对象,在烛台图的顶部叠加绘图。返回两个轴:主轴和次轴。在以下基于您提供的示例的示例中,噪声 线图是使用主轴创建的。

请注意,mpf.plot returns 一个图,其中 x 轴刻度默认由从零开始的整数单位组成(如 pandas 条形图)。这是因为绘图函数的构建是为了可视化交易时间的数据,而不是连续的日期时间变量,后者会包含许多非交易时间的间隙。可以通过设置 show_nontrading=True 来更改此行为。在下面的示例中,我为这两种选择提供了一种解决方案,使用 pandas 绘图函数绘制直线,因为与 matplotlib 相比,它使用起来稍微方便一些:

import pandas as pd                                        # v 1.1.3
import matplotlib.pyplot as plt                            # v 3.3.2
import matplotlib.dates as mpdates
import mplfinance as mpf                                   # v 0.12.7a4
from mplfinance.original_flavor import candlestick_ohlc

# Create sample data
dti = pd.date_range('2021-01-07', periods=5, freq='min')

minutely = pd.DataFrame({'Open':[36769.36, 36880.00, 36851.42,36922.19,37083.18],
                         'High':[36880.00, 36880.00, 36950.00, 37089.69, 37094.70],
                         'Low': [36760.00,  36817.64, 36810.03, 36922.13, 36565.49],
                         'Close':[36880.00, 36851.97, 36922.14, 37075.80, 36691.3]},
                        index=dti)

noise = pd.DataFrame({'Noise':[36779.36, 36870.00, 36881.42,36902.19,37103.18]},
                     index=dti)

# Create candlestick chart overlaid with a pandas line plot
fig, (ax1, ax2) = mpf.plot(minutely, type='candle', returnfig=True, figsize=(6,4))
noise.plot(ax=ax1, use_index=False);

# # Create same figure including non-trading hours, in this case the datetime
# # variable is used for the x-axis scale
# fig, (ax1, ax2) = mpf.plot(minutely, type='candle', show_nontrading=True,
#                            returnfig=True, figsize=(6,4))
# noise.plot(ax=ax1, x_compat=True);


关于问题的第二部分,旧 candlestick_ohlcv 函数的文档字符串指出 width 是一天的一小部分(对应于 matplotlib 日期单位)。示例数据仅持续几分钟,但您设置了 width=0.6(超过半天),这会产生非常宽的烛条,使图表难以阅读。设置 width=0.0003 似乎效果很好。另一件需要调整的事情是 x 刻度,因为它们似乎被放置在有些随机的位置。这是一个使用与上述相同数据的示例:

# Edit minutely dataframe for use with candlestick_ohlc function
minutely['Date'] = mpdates.date2num(minutely.index)
minutely = minutely[['Date', 'Open', 'High', 'Low', 'Close']]

# Create candlestick chart overlaid with a pandas line plot
plt.style.use('dark_background')
fig, ax = plt.subplots(figsize=(6,4))
candlestick_ohlc(ax, minutely.values, width=0.0003,
                 colorup='green', colordown='red', alpha=0.8)
noise.plot(ax=ax, x_compat=True)

# Set labels
ax.set_xlabel('Date')
ax.set_ylabel('Price')

# Create ticks that match the locations of the candlesticks and format labels
ax.set_xticks(minutely['Date'])
date_format = mpdates.DateFormatter('%H:%M\n%d-%m-%Y ') 
ax.xaxis.set_major_formatter(date_format)
fig.autofmt_xdate(rotation=0, ha='center')



参考资料: (the current mplfinance package maintainer); pandas plotting function, and the x_compat 用于将 pandas 绘图日期单位转换为 matplotlib 日期单位的参数

您可以通过在上面的第一个代码示例中添加 仅一行代码 来实现:

在调用 mpf.plot() 之前添加以下行:

ap = mpf.make_addplot(noise)

然后更改对 mpf.plot() 的调用以包含 addplot 关键字,因此:

ap = mpf.make_addplot(noise)
mpf.plot(minutely, type='candle', addplot=ap)

如果需要,您还可以修改日期时间格式:

ap = mpf.make_addplot(noise)
mpf.plot(minutely, type='candle', addplot=ap, datetime_format='%b %d, %H:%M')

我强烈建议您通读这两个教程。它们相对较短,可能只需要 15 到 30 分钟来仔细阅读它们:


P.S。作为一般规则,我不鼓励访问 mplfinance 的 Figure 和 Axes 对象:您的代码因此会简单得多。对图和轴的访问只能用于需要 mplfinance 尚不支持的高级功能的绘图。如果您通读了这些教程,我相信您会发现 大多数使用财务图表完成的事情都可以简单地完成,而无需直接操作图形和坐标轴