Python:使用自动Y缩放绘制蜡烛图

9

我正在寻找一个Python绘图库,可以让我使用鼠标滚轮(或类似方法)对蜡烛图进行X缩放,并在缩放时自动调整Y轴比例。

作为我所寻找的示例,tradingview.com完美地实现了这一点。请参见https://uk.tradingview.com/chart/?symbol=NASDAQ:NDX。可以通过单击左上角附近的蜡烛图标并选择“Bars”来查看OHLC条形图。

Plotly几乎可以做到这一点。plotly.graph_objs中的Ohlc类可提供OHLC条形图,而默认的范围滑块是X缩放的好功能(也可以很容易地启用鼠标滚轮)。然而,据我所见,Python中没有自动Y轴比例调整功能(Y-axis autoscaling with x-range sliders in plotly),因此在数据的某个部分进行缩放会使其变得平坦。示例代码- https://plot.ly/python/ohlc-charts/

我熟悉的另一个选项是PyQtGraph,它具有良好的缩放功能,但不支持蜡烛图绘制。使用它需要编写自己的蜡烛对象。

有许多Python绘图库我不了解。是否有任何现成支持此功能的库?有人能提供干净的示例代码吗?


pyqtgraph支持蜡烛图,参见examples/customGraphicsItem.py。 - misantroop
3个回答

7
这是在finplot中如何操作的方式:
import yfinance as yf
import finplot as fplt

df = yf.download('^NDX', start='2018-01-01', end='2020-04-29')
print(df)
fplt.candlestick_ochl(df[['Open','Close','High','Low']])
fplt.show()

免责声明:我是作者。Finplot具有自动Y轴缩放功能,快速、主观并具有清晰的API。在这里查看示例。


1
只想说finplot太棒了! - Grantx
嘿,乔纳斯,我们如何启用水平缩放? - swordfish81
@Sledge81 finplot 默认情况下会启用鼠标滚轮缩放,如果您有超过20个蜡烛图。 - Jonas Byström
我们能否将finplot集成到Web应用程序中,例如Django或Flask? - panjianom
1
@pije76 不,它只支持本地。 - Jonas Byström

6
我找到的最佳解决方案是使用Bokeh。这里有一个相关的问题 - Bokeh,仅在单个轴上缩放,相应地调整另一轴。一个答案链接了一个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)

3
“fig.x_range.callback = callback” 这一部分不再起作用了。似乎“plot.x_range.js_on_change('start', callback)”可以解决问题。我们是应该针对“start”属性还是其他什么? - mbilyanov

5

我曾费劲心思地调试plotly蜡烛图表,使其按照我的意愿运行。因此,我开发了一个代码示例与大家分享。

该示例不需要任何附加的JavaScript或其他库,只需使用Dash、Plotly和一个名为pytz的日期库即可。示例代码在更新x范围滑块时提供自动更新y轴范围的功能。Y轴被设置为仅显示在图表中的价格范围,并留有两个刻度的间隔。

这对我来说非常有效,我可以在图表顶部添加任意数量的跟踪叠加层。此外,我可以在本地运行它,而无需使用plotly服务。请参见github repo:

https://github.com/gersteing/DashCandlestickCharting/blob/master/README.md

欢迎任何人尝试运行该示例,它使用Flask在本地运行。享受它吧!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接