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
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()