Как получить отображение оси Y на графике свечей OHLC matplotlib для отображения значений OHLC, а не положения курсора на оси y - PullRequest
0 голосов
/ 30 декабря 2018

Я использую 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

1 Ответ

0 голосов
/ 04 января 2019

Ниже приведено решение, которое позволяет показаниям осей x и y таблицы свечей OHL matplotlib для отображения значений OHLC в показаниях оси Y, а не положения курсора оси Y.

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






if __name__ == '__main__':
    ohlc_daily_date_axis()
...