1

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?

karutt
  • 359
  • 1
  • 11

2 Answers2

1

I think that can be done in HoloViews with a Python callback attached to the pan tool; see the HoloViews user guide.

It seems like something that would be best addressed using Bokeh at the JavaScript level and then enabled with some new option autorange_y, and indeed searching for "bokeh autoscale y axis" shows that lots of people have requested this over the years. I don't see any actual general solutions posted, but there's a gist with an example of doing it in JS for one type of plot. Probably worth filing a feature request at https://github.com/bokeh/bokeh/issues asking for a more general solution.

James A. Bednar
  • 3,195
  • 1
  • 9
  • 13
1

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.

karutt
  • 359
  • 1
  • 11