【发布时间】:2019-05-27 11:36:06
【问题描述】:
我正在使用 matplotlib 创建 OHLC 烛台股票价格图表。我正在使用 mpl_finance 的烛台_ohlc 模块来创建图表。创建图表很简单,但是图表底部的 x 和 y 轴显示显示给定光标位置的日期和 y 轴值,但我希望 x 和 y 轴显示显示日期和打开的日期,高、低、关闭 (ohlc) 值,而不仅仅是日期和 y 轴光标位置值。报价数据集采用元组列表的格式,其中每个元组包含作为数字的日期,后跟开盘价、最高价、最低价、收盘价和成交量。我正在尝试使用 matplotlib 的 format_coord 函数来指定 ohlc 值,但我无法弄清楚如何让 format_coord 函数接受包含日期和相关 ohlc 值的列表作为输入,然后给出所需的日期和 OHLC 输出。以下是我编写的一些简化代码,展示了我的问题: 下面的代码现在已经过修改,可以完全正常工作:
import matplotlib.pyplot as plt
from matplotlib.dates import DateFormatter, WeekdayLocator, DayLocator, MONDAY
from mpl_finance import candlestick_ohlc
from matplotlib.dates import date2num, num2date
def ohlc_daily_date_axis():
mondays = WeekdayLocator(MONDAY)
alldays = DayLocator()
weekFormatter = DateFormatter('%b %d %Y') # e.g., Jan 12 2018
quotes = [(737042.0, 2.72, 2.78, 2.6815, 2.74, 414378.0),
(737045.0, 2.71, 2.77, 2.57, 2.63, 578841.0),
(737046.0, 2.64, 2.64, 2.4228, 2.47, 1451450.0),
(737047.0, 2.9, 3.15, 2.7, 2.96, 7230260.0),
(737048.0, 2.92, 3.29, 2.67, 2.83, 2784110.0),
(737049.0, 2.78, 2.82, 2.4701, 2.51, 822776.0),
(737052.0, 2.56, 2.6344, 2.49, 2.5, 278883.0),
(737054.0, 2.5, 2.619, 2.34, 2.6, 606002.0),
(737055.0, 2.57, 2.63, 2.45, 2.57, 1295820.0),
(737056.0, 2.57, 2.75, 2.51, 2.65, 435838.0)]
fig, ax = plt.subplots(figsize=(18,5))
plt.subplots_adjust(bottom=0.2)
ax.xaxis.set_major_locator(mondays)
ax.xaxis.set_minor_locator(alldays)
ax.xaxis.set_major_formatter(weekFormatter)
candlestick_ohlc(ax, quotes, width=0.6)
ax.xaxis_date()
ax.autoscale_view()
plt.setp(plt.gca().get_xticklabels(), rotation=45,
horizontalalignment='right')
#the following line puts the ohlc data in the y axis display
ax.format_coord = get_ohlc_from_date_xy
# the following line puts the ohlc data in the x axis display
#ax.fmt_xdata = get_ohlc_from_date_x
plt.show()
def get_ohlc_from_date_x(dateasnum):
print('dateasnum: ', int(dateasnum))
quotes = [(737042.0, 2.72, 2.78, 2.6815, 2.74, 414378.0),
(737045.0, 2.71, 2.77, 2.57, 2.63, 578841.0),
(737046.0, 2.64, 2.64, 2.4228, 2.47, 1451450.0),
(737047.0, 2.9, 3.15, 2.7, 2.96, 7230260.0),
(737048.0, 2.92, 3.29, 2.67, 2.83, 2784110.0),
(737049.0, 2.78, 2.82, 2.4701, 2.51, 822776.0),
(737052.0, 2.56, 2.6344, 2.49, 2.5, 278883.0),
(737054.0, 2.5, 2.619, 2.34, 2.6, 606002.0),
(737055.0, 2.57, 2.63, 2.45, 2.57, 1295820.0),
(737056.0, 2.57, 2.75, 2.51, 2.65, 435838.0)]
for i in range(len(quotes)):
if int(dateasnum) == quotes[i][0]:
open = quotes[i][1]
high = quotes[i][2]
low = quotes[i][3]
close = quotes[i][4]
vol = quotes[i][5]
dte = str(num2date(dateasnum).date())
print('type(dte): ', type(dte))
print('open: ', open)
ohlc_str = dte + ' open: ' + str(open) + ' high: ' + str(high) + '
low: ' + str(low) + ' close: ' + str(close) + ' vol: ' + str(int(vol))
+ ' '
return ohlc_str
def get_ohlc_from_date_xy(dateasnum,y):
print('dateasnum: ', int(dateasnum))
quotes = [(737042.0, 2.72, 2.78, 2.6815, 2.74, 414378.0),
(737045.0, 2.71, 2.77, 2.57, 2.63, 578841.0),
(737046.0, 2.64, 2.64, 2.4228, 2.47, 1451450.0),
(737047.0, 2.9, 3.15, 2.7, 2.96, 7230260.0),
(737048.0, 2.92, 3.29, 2.67, 2.83, 2784110.0),
(737049.0, 2.78, 2.82, 2.4701, 2.51, 822776.0),
(737052.0, 2.56, 2.6344, 2.49, 2.5, 278883.0),
(737054.0, 2.5, 2.619, 2.34, 2.6, 606002.0),
(737055.0, 2.57, 2.63, 2.45, 2.57, 1295820.0),
(737056.0, 2.57, 2.75, 2.51, 2.65, 435838.0)]
for i in range(len(quotes)):
if int(dateasnum) == quotes[i][0]:
open = quotes[i][1]
high = quotes[i][2]
low = quotes[i][3]
close = quotes[i][4]
vol = quotes[i][5]
dte = str(num2date(dateasnum).date())
#print('type(dte): ', type(dte))
#print('open: ', open)
ohlc_str = 'open: ' + str(open) + ' high: ' + str(high) + '
low: ' + str(low) + ' close: ' + str(close) + ' vol: ' + str(int(vol))
return dte, ohlc_str
# This def does not work
def format_coord(x,y, quotes):
for i in range(len(quotes)):
if int(x) == quotes[i]:
open = quotes[i][1]
high = quotes[i][2]
low = quotes[i][3]
close = quotes[i][4]
vol = quotes[i][5]
y = 'open: ' + open # I'm just using open to simplify things
x = DateFormatter('%b %d %Y')
return (x,y)
if __name__ == '__main__':
ohlc_daily_date_axis()
如果我按原样运行此代码,则会收到以下错误(这是我使用不正确的 def format_coord(x,y, quotes) 方法时遇到的错误):
File "/Users/Me/Mee/python_db_programs/learn_matplotlib_test.py", line 33,
in ohlc_daily_date_axis
ax.format_coord = format_coord(quotes)
TypeError: format_coord() missing 2 required positional arguments: 'y'
and 'quotes'
如果我注释掉 ax.format_coord = format_coord(quotes) 行,那么代码运行良好,但在 x 和 y 显示中没有我想要的日期和 ohlc 值。任何有关如何进行的帮助将不胜感激。
我最终没有尝试更改 y 显示,而是将 ohlc 值添加到 x 显示。这意味着我将 ax.format_coord = format_coord(quotes) 更改为仅格式化 x 坐标的命令,即 ax.fmt_xdata 然后编写了一个使用引号列表获取每个日期对应的 ohlc 数据的 def:
ax.fmt_xdata = get_ohlc_from_date
而不是
ax.format_coord = format_coord(quotes)
然后添加这个def:
def get_ohlc_from_date(dateasnum):
print('dateasnum: ', int(dateasnum))
quotes = [(737042.0, 2.72, 2.78, 2.6815, 2.74, 414378.0),
(737045.0, 2.71, 2.77, 2.57, 2.63, 578841.0),
(737046.0, 2.64, 2.64, 2.4228, 2.47, 1451450.0),
(737047.0, 2.9, 3.15, 2.7, 2.96, 7230260.0),
(737048.0, 2.92, 3.29, 2.67, 2.83, 2784110.0),
(737049.0, 2.78, 2.82, 2.4701, 2.51, 822776.0),
(737052.0, 2.56, 2.6344, 2.49, 2.5, 278883.0),
(737054.0, 2.5, 2.619, 2.34, 2.6, 606002.0),
(737055.0, 2.57, 2.63, 2.45, 2.57, 1295820.0),
(737056.0, 2.57, 2.75, 2.51, 2.65, 435838.0)]
for i in range(len(quotes)):
if int(dateasnum) == quotes[i][0]:
open = quotes[i][1]
high = quotes[i][2]
low = quotes[i][3]
close = quotes[i][4]
vol = quotes[i][5]
dte = str(num2date(dateasnum).date())
print('type(dte): ', type(dte))
print('open: ', open)
ohlc_str = dte + ' open: ' + str(open) + ' high: ' + str(high) + '
low: ' + str(low) + ' close: ' + str(close) + ' vol: ' + str(int(vol))
+ ' '
return ohlc_str
另外,因为我使用了 matplotlibs dateasnum 函数,所以我也必须导入它:
from matplotlib.dates import num2date
虽然这不会用 ohlc 值替换 y 轴坐标,但它确实提供了 x 和 y 轴显示中的 ohlc 值
在弄清楚如何将 ohlc 值添加到 x 轴显示后,我意识到我用来将 ohlc 值添加到 x 轴显示的逻辑可以应用于 y 轴显示,从而允许显示 ohlc 值在 y 轴参数中。这是通过使用 ax.format_coord = format_coord 命令并创建一个新的 def 来完成的,该 def 将 ohlc 值分配给 y 轴返回值。我已经修改了我发布的原始代码,以便根据 ax.format_coord = format_coord 行或 ax.fmt_xdata = get_ohlc_from_date 行是否被注释掉来确定 ohlc 值是作为 x 轴显示的一部分显示还是作为一部分显示y轴显示
【问题讨论】:
-
这里的问题到底是什么?
-
嗨,我试图弄清楚如何让 y 轴显示来显示 OHLC 值而不是 y 轴光标位置。我能够解决问题并随后修改代码以显示解决方案。
-
好的,你误解了问答的概念。您提出问题,您或其他任何人都可以提供答案。因此,请将所有回答您问题的内容放在 answer 中。
-
嗨,我不清楚我应该如何回答我提出的问题。在这种情况下,我改变了我原来的问题,以便它提供我的答案。我看到我应该做的是点击页面底部的回答你的问题按钮,然后在那里发布正确的代码。回想起来,这似乎很明显。感谢您指出我的错误。
-
“回想起来”是什么意思?现在就做?!
标签: python-3.x matplotlib candlestick-chart