matplotlib.finance.candlestick_ohlc 绘制日内 1 分钟柱形图数据,每小时都有时间间隔和适当的 xticklabels

Sta*_*ish 5 python datetime matplotlib candlestick-chart

问题是:

我想绘制一只股票的日内 1 分钟 OHLC 条形图。每日交易时间由几个交易时段组成。下面列出了:

交易日期:2017/09/14

包含交易时间:2017/09/13 21:00 - 23:00、2017/09/14 9:00 - 10:15、10:30 - 11:30、13:30 - 15:00。

正如你所看到的,如果我直接使用的话candlestick_ohlc,是会有间隙的。

现在,如果我得到 1 分钟的数据作为数据框。如何绘制烛台图,任何柱之间没有间隙(例如,10:15 和 10:30 柱之间没有间隙),并且让 xticklabels 仅显示每小时的主要价格变动,例如 22:00、23: 00、10:00 以及每 15 分钟一次的小滴答声,例如 21:15、21:30、21:45 等。

这是我的数据框 1 个交易日的样子: 在此输入图像描述

您可以在此处生成一些具有类似形式的伪数据:

def generate_pseudo_data():
    # datetime index data
    idx = pd.date_range('2017-09-13 21:01:00',
                        '2017-09-13 23:00:00', freq='1min')
    idx = idx.append(pd.date_range('2017-09-14 09:01:00',
                                   '2017-09-14 10:15:00', freq='1min'))
    idx = idx.append(pd.date_range('2017-09-14 10:31:00',
                                   '2017-09-14 11:30:00', freq='1min'))
    idx = idx.append(pd.date_range('2017-09-14 13:31:00',
                                   '2017-09-14 15:00:00', freq='1min'))

    # OHLC
    inc = np.random.randint(-2, 3, size=idx.shape).cumsum()
    opens = 3500 + inc
    closes = opens + np.random.randint(-3, 3, idx.shape)
    range_max = np.max(np.concatenate([opens.reshape(-1, 1),
                                       closes.reshape(-1, 1)], axis=1), axis=1)
    highs = range_max + np.random.randint(0, 5, size=idx.shape)
    range_min = np.min(np.concatenate([opens.reshape(-1, 1),
                                       closes.reshape(-1, 1)], axis=1), axis=1)
    lows = range_min - np.random.randint(0, 5, size=idx.shape)
    bar_df = pd.DataFrame({'open': opens, 'high': highs, 'low': lows,
                           'close': closes}, index=idx)
    return bar_df
Run Code Online (Sandbox Code Playgroud)

我在 matplotlib.finance 模块中看到,有candlestic2_ohlc, 和candlestick_ohlc。我的第一次尝试是使用它candlestick2_ohlc,因为它不需要数字datetime参数,否则会弄乱带有许多间隙的条形。我没有得到任何间隙,但我无法将 xticklabels 制作为我想要的,因为我现在不知道如何将 datetimeIndex 信息传递给 xticklabels。

这是我首先尝试的:基本上是从这篇文章中学到的: 如何在 matplotlib 中用日期时间绘制 ohlc 烛台?

from datetime import datetime, time

import pandas as pd
import numpy as np

import matplotlib as mpl
import matplotlib.pyplot as plt
from matplotlib.finance import candlestick2_ohlc, candlestick_ohlc
import matplotlib.dates as mdates
from matplotlib import ticker

bar_df = generate_pseudo_data()
fig, ax = plt.subplots()
figManager = plt.get_current_fig_manager()
figManager.window.showMaximized()

candlestick2_ohlc(ax, bar_df.open, bar_df.high, bar_df.low, bar_df.close,
                  width=0.6, colorup='r', colordown='c', alpha=1)
xdate = bar_df.index
def mydate(x, pos):
    try:
        return xdate[int(x)]
    except IndexError:
        return ''

ax.xaxis.set_major_formatter(ticker.FuncFormatter(mydate))
# Everything works fine up to now.
# However the xticklabels are not exactly at 22:00, 23:00, etc.
# And no minor tick labels set up at 21:15, 21:30, 21:45, etc.

# I tried either one of the command below, but both failed with no xticklabels
# showed up.

ax.xaxis.set_major_locator(mdates.HourLocator())
ax.xaxis.set_major_locator(mdates.MinuteLocator(byminute=[0, 15, 30, 45],
                                                interval=1))

# This one works because it only tells xticklabels to have at most
# 8 tick labels, but no info about where the xticklabels should be.
ax.xaxis.set_major_locator(ticker.MaxNLocator(8))
Run Code Online (Sandbox Code Playgroud)

Candlestick_ohlc 结果

请帮忙。

Imp*_*est 3

当前您正在根据其索引绘制数据。\n但是,如果您想使用matplotlib.dates定位器和格式化程序,则需要在轴上绘制日期。\n使用 是不可能的candlestick2_ohlc。相反,您需要使用candlestick_ohlc函数。实际上,您链接到的问题的答案中也提到了这一点。\n但是,使用实际日期不允许合并注释,除了可能在不同的子图中绘制之外,请参阅\xe2\x98\xbcbroken 轴示例

\n\n

因此,这里的解决方案可能是继续绘制索引并将刻度设置到与所需刻度标签相对应的位置。

\n\n
xdate = bar_df.index\ndef mydate(x, pos):\n    try:\n        return xdate[int(x)]\n    except IndexError:\n        return \'\'\n# create date ranges of possible dates to show as major and minor ticklabels\nmajor_dr = pd.date_range(\'2017-09-13 21:00:00\',\'2017-09-14 15:00:00\', freq=\'60min\')\nminor_dr = pd.date_range(\'2017-09-13 21:00:00\',\'2017-09-14 15:00:00\', freq=\'15min\')\n# calculate positions of the above dates inside the dataframe index\nmajor_ticks = np.isin(xdate, major_dr).nonzero()[0] \nminor_ticks = np.isin(xdate, minor_dr).nonzero()[0]\n# use those positions to put ticks at\nax.xaxis.set_major_locator(ticker.FixedLocator(major_ticks))\nax.xaxis.set_minor_locator(ticker.FixedLocator(minor_ticks))\nax.minorticks_on()\nax.xaxis.set_major_formatter(ticker.FuncFormatter(mydate))\nfig.autofmt_xdate()\n
Run Code Online (Sandbox Code Playgroud)\n\n

结果看起来像

\n\n

在此输入图像描述

\n\n

这读起来非常令人困惑,但据我所知,这就是问题所要求的。

\n