Python:用自动Y变焦绘制烛台

我正在寻找一个
Python绘图库,它允许我通过鼠标滚轮(或类似)和X缩放来绘制烛台(最好是OHLC条形变体),并在缩放时绘制自动缩放的Y轴.

作为我正在寻找的一个例子,tradingview.com完美地做到了这一点.请参阅https://uk.tradingview.com/chart/?symbol=NASDAQ:NDX.单击左上角附近的烛台图标并选择“条形图”,可以看到OHLC条形图.

Plotly几乎能够做到这一点. plotly.graph_objs中的Ohlc类给出了OHLC条,默认的rangelider是X变焦的一个很好的功能(鼠标滚轮也可以轻松启用).然而,据我所知,自动Y缩放在Python中是不可用的(Y-axis autoscaling with x-range sliders in plotly),因此放大一部分数据会使它显得平坦.示例代码 – https://plot.ly/python/ohlc-charts/

我熟悉的另一个选项是PyQtGraph,它具有很好的缩放功能,但不支持烛台图.使用它将涉及编码我自己的烛台对象.

我不知道有各种各样的Python绘图库.那里有什么开箱即用的支持吗?任何人都可以提供示例代码来干净利落地完成

最佳答案 我发现的最佳解决方案是使用Bokeh.这里有一个相关的问题 –
Bokeh, zoom only on single axis, adjust another axis accordingly.一个答案链接
gist,它给出了一个设置烛台自动Y变焦的例子.

不幸的是,这远不是一个“开箱即用”的解决方案,因为它涉及编码自定义JavaScript回调.但是,解决方案仍然相当简单.我无法在gist上运行代码,主要是由于Pandas DataReader的问题.这是代码的更新版本,它使用了Bokeh提供的示例数据(根据Bokeh Candlesicks example),在TradingView中添加了更多相似之处,并解决了我发现的一些其他问题:

import pandas as pd

from bokeh.io import output_file, show
from bokeh.plotting import figure
from bokeh.models import CustomJS, ColumnDataSource
from bokeh.sampledata.stocks import MSFT


def candlestick_plot(df):
    fig = figure(sizing_mode='stretch_both',
                 tools="xpan,xwheel_zoom,undo,redo,reset,crosshair,save",
                 active_drag='xpan',
                 active_scroll='xwheel_zoom',
                 x_axis_type='datetime')

    inc = df.close > df.open
    dec = ~inc

    fig.segment(df.date[inc], df.high[inc], df.date[inc], df.low[inc], color="green")
    fig.segment(df.date[dec], df.high[dec], df.date[dec], df.low[dec], color="red")
    width_ms = 12*60*60*1000 # half day in ms
    fig.vbar(df.date[inc], width_ms, df.open[inc], df.close[inc], color="green")
    fig.vbar(df.date[dec], width_ms, df.open[dec], df.close[dec], color="red")

    source = ColumnDataSource({'date': df.date, 'high': df.high, 'low': df.low})
    callback = CustomJS(args={'y_range': fig.y_range, 'source': source}, code='''
        clearTimeout(window._autoscale_timeout);

        var date = source.data.date,
            low = source.data.low,
            high = source.data.high,
            start = cb_obj.start,
            end = cb_obj.end,
            min = Infinity,
            max = -Infinity;

        for (var i=0; i < date.length; ++i) {
            if (start <= date[i] && date[i] <= end) {
                max = Math.max(high[i], max);
                min = Math.min(low[i], min);
            }
        }
        var pad = (max - min) * .05;

        window._autoscale_timeout = setTimeout(function() {
            y_range.start = min - pad;
            y_range.end = max + pad;
        });
    ''')

    fig.x_range.callback = callback
    show(fig)

df = pd.DataFrame(MSFT)
df["date"] = pd.to_datetime(df["date"])
output_file("candlestick.html")
candlestick_plot(df)
点赞