Я использую matplotlib для создания графика цены свечей OHLC.Я использую модуль Candstick_ohlc в mpl_finance для создания графика.Создать диаграмму несложно, однако отображение осей x и y в нижней части диаграммы показывает дату и значение оси y для заданной позиции курсора, но я бы хотел, чтобы на оси x и y отображались дата и открытые даты,значения high, low, close (ohlc), а не просто значение даты и позиции курсора оси y.Набор данных кавычек представлен в формате списка кортежей, где каждый кортеж содержит дату в виде числа, за которым следуют открытия, максимумы, минимумы, закрытие и объем.Я пытаюсь использовать функцию format_coord в matplotlib для указания значений 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), тогда код запуститсяхорошо, но без желаемой даты и значений ohlc на дисплее x и y.Буду очень признателен за любую помощь в том, как поступить.
В итоге я не пытался изменить отображение y, а вместо этого добавил значения ohlc на дисплей x.Это означает, что я изменил ax.format_coord = format_coord (quotes) на команду, которая просто форматирует координату x, то есть ax.fmt_xdata, а затем записала def, в котором использовался список кавычек для получения каждой даты, соответствующей данным ohlc:
ax.fmt_xdata = get_ohlc_from_date
вместо
ax.format_coord = format_coord(quotes)
, а затем добавил это определение:
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
Кроме того, поскольку я использовал функцию dateasnum matplotlibs, мне пришлось также импортировать ее:
from matplotlib.dates import num2date
Хотя это не заменяет координату оси y значениями ohlc, оно отображает значения ohlc на дисплее по осям x и y
После выяснения, как добавить значения ohlc к отображению оси xЯ понял, что логика, которую я использовал для добавления значений ohlc к отображению оси x, может быть применена к отображению оси y, что позволяет отображать значения ohlc в параметре оси y.Это было достигнуто с помощью команды ax.format_coord = format_coord и создания нового значения def, в котором значения ohlc присваиваются возвращаемому значению оси y.Я изменил исходный код, который я разместил, чтобы в зависимости от того, закомментирована ли строка ax.format_coord = format_coord или строка ax.fmt_xdata = get_ohlc_from_date, определяется, будут ли значения ohlc отображаться как часть отображения оси x или как частьотображения оси y