How to autoscale Y axis on change of X range when zooming for instance?

Using Bokeh I would appreciate some help to scale plots Y axis as a function of X range following a zoom event for instance. The idea is to have a number of plot strips showing for instance motors current over time. When zooming over a particular X range of one strip all the other strips would zoom to the same X range and on their Y axis scale their data to fit this range. For a given time window (from user zoom) all the plots would zoom in. I have this autoscale working with matplotlib and I would like now to have the equivalent in Bokeh. I’ve copied the matplotlib code which hopefully can clarify what I am after. With Bokeh I guess I will have to:

  • link x range over the multiple plot strips
  • call a piece of javascript with a callback on a change event of x_range like fig.x_range.callback = CustomJS( …

But that’s as far as I got to. I don’t really understand yet how to access all the parameters I would need to compute the scaling of all the plots. I’m new to Bokeh and JS so have to go through the learning curve. But if someone already has a good idea of how to proceed that would help a lot. In the meantime I will continue with some tentative coding.

import math
from matplotlib import pyplot as plt
from matplotlib import ticker as ticker
import numpy as np

def rescale_y(ax):
    setmargin = 0.05
    xmin, xmax = ax.get_xlim()
    axes = ax.figure.get_axes()
    for axis in axes:
        lines = axis.get_lines()
        ylo = math.inf
        yhi = -math.inf
        for line in lines:
            x, y = line.get_data()
            cond = (x >= xmin) & (x <= xmax)
            yrest = y[cond]
            margin = (yrest.max()-yrest.min())*setmargin
            new_ylo = yrest.min()-margin
            new_yhi = yrest.max()+margin
            if new_ylo < ylo: ylo = new_ylo
            if new_yhi > yhi: yhi = new_yhi
        axis.set_ylim(ylo,yhi)
        axis.figure.canvas.draw()


# Prepare dummy data to plot
x = np.arange(0,100)
y1 = x
y2 = np.power(x, 2)
y3 = x + 10

# Prepare plots
fig, ax = plt.subplots( 2, 1, squeeze=False, sharex='col' )
#plt.subplots_adjust( hspace=0.05, left=0.05, right=0.99, top=0.95, bottom=0.05 )
fig.suptitle( 'my example' )
ax[0,0].plot( x, y1, c='blue', linewidth=1, label='plot 1')         
ax[0,0].plot( x, y2, c='red', linewidth=1, label='plot 2')          
ax[1,0].plot( x, y3, c='green', linewidth=1, label='plot 3')            

# Set callbacks on xlim changed
axes = fig.get_axes()
for i in axes:
    i.callbacks.connect('xlim_changed', rescale_y)

# Display plots
plt.show()