Search code examples
pythonbokehholoviews

Is it possible to scale yrange automatically in holoviews?


I used holoviews to display the line chart, but when I move it horizontally with the pan tool, the line goes off the screen in the vertical direction. Therefore, I wanted a function that autoscales yrange so that the line does not jump out of the screen at any time. enter image description here

My ideal is the graph on this site. https://www.binance.com/en/trade/BTC_USDT

Is there a way to implement this using holoviews?


Solution

  • With reference to the official tutorial, I implemented a simple code for autoscale.

    HoloViews user guide -「Custom Interactivity」

    The autoscale() works only for Holoviews' drawing methods that take X, Y as arguments, such as hv.Scatter, hv.Curve, hv.Point, hv.Histogram, hv.Area.

    import numpy as np
    import pandas as pd
    import holoviews as hv
    hv.extension("bokeh")
    
    def autoscale(fig):
        x, y  = fig.dimension_values(0), fig.dimension_values(1)
        def draw(x_range, y_range):
            if not x_range: return fig
            xr_start, xr_end = x_range
            mask = (xr_start < x) & (x < xr_end)
            yr_start, yr_end = y[mask].min(), y[mask].max()
            yr_start, yr_end = yr_start - (abs(yr_end - yr_start)*0.1), yr_end + (abs(yr_end - yr_start)*0.1)
            if yr_start == False or yr_start == None or yr_start == yr_end:
                yr_start, yr_end = y_range
            return fig.opts(hooks=[
                lambda plot, _:
                    plot.handles['y_range'].update(start=yr_start, end=yr_end)
            ], active_tools=["wheel_zoom"])
        return hv.DynamicMap(draw, streams=[hv.streams.RangeXY()])
    
    x = pd.date_range("2020-01-01", "2020-4-09")
    y = np.cumsum(np.random.randn(len(x)))
    
    autoscale(hv.Curve((x, y)) * hv.Curve((x, y*1.5))) # also works overlay
    autoscale(hv.Curve((x, y)))
    

    It looks like we can improve it, but I hope the official will provide an autoscale feature.