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

问题描述

我的第一个需求是在烛台图表上叠加一条曲线。 要绘制此烛台图,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)

enter image description here

如果你愿意,你也可以修改日期时间格式:

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

enter image description here

我强烈建议您通读这两个教程。它们相对较短,仔细阅读它们可能只需要 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);

mpf_candlestick


关于您问题的第二部分,旧 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')

mpf_candlestick_old



参考文献:this answer by Daniel Goldfarb(当前的 mplfinance package 维护者); pandas plotting function,以及用于将 Pandas 绘图日期单位转换为 matplotlib 日期单位的 x_compat 参数

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...