问题描述
我的第一个需求是在烛台图表上叠加一条曲线。
要绘制此烛台图,mplfinance
看起来很不错。不幸的是,我发现无法将额外的曲线叠加到烛台上。
考虑下面的示例,如果你们中有人知道如何在从“分钟”数据帧绘制的烛台上覆盖“噪声”列,那就太好了!
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,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'),'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')
不止于此,我还想使用“旧”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'),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()
请问,有人知道将外部数据叠加到烛台数据的方法吗? 在此先感谢您的帮助, 最好的,
解决方法
您可以通过在上面的第一个代码示例中添加仅一行代码来实现:
在调用 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,addplot=ap,datetime_format='%b %d,%H:%M')
我强烈建议您通读这两个教程。它们相对较短,仔细阅读它们可能只需要 15 到 30 分钟:
附言作为一般规则,我不鼓励访问 mplfinance 的 Figure 和 Axes 对象:因此您的代码会简单得多。访问图形和轴应仅用于需要 mplfinance 尚不支持的高级功能的绘图。如果您通读教程,我相信您会发现使用金融图完成的大多数事情都可以简单地完成,而无需直接操作图形和轴。
,您可以使用 returnfig=True
参数在烛台图顶部叠加一个图来获取 matplotlib Figure 和 Axes 对象。返回两个轴:主轴和次轴。在以下基于您提供的示例的示例中,噪声 线图是使用主轴创建的。
请注意,mpf.plot
返回一个图形,其中 x 轴比例默认由从零开始的整数单位组成(如熊猫条形图)。这是因为绘图函数的构建是为了可视化交易时间的数据,而不是包含许多非交易时间间隔的连续日期时间变量。可以通过设置 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,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,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,show_nontrading=True,# returnfig=True,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')
参考文献:this answer by Daniel Goldfarb(当前的 mplfinance package 维护者); pandas plotting function,以及用于将 Pandas 绘图日期单位转换为 matplotlib 日期单位的 x_compat
参数