I have two plots with linked x_ranges. The y_ranges are independent and with ‘autoscale’ option (DataRange1d). I would however like to autoscale y-axis (both) also after x_ranges changed (on zoom, move, …). I understand there is no functionality to automatically achieve this, so I tried to do it using callback on x_range change like this:
fig1 = figure(
...
y_range=DataRange1d(only_visible=True),
...
)
fig2 = figure(
...
x_range=fig1.x_range,
y_range=DataRange1d(only_visible=True),
...
)
xRangeChanged = CustomJS(
args={
'y1Range': fig1.y_range,
'y2Range': fig2.y_range,
},
code="""
console.log('xRangeChanged');
console.log('y1Range: ' + y1Range.start + ' - ' + y1Range.end)
console.log('y2Range: ' + y2Range.start + ' - ' + y2Range.end)
y1Range.start = 10;
y1Range.end = 20;
y2Range.start = 30;
y2Range.end = 40;
console.log('y1Range: ' + y1Range.start + ' - ' + y1Range.end)
console.log('y2Range: ' + y2Range.start + ' - ' + y2Range.end)
"""
)
fig1.x_range.js_on_change('start', xRangeChanged)
fig1.x_range.js_on_change('end', xRangeChanged)
However what it does is that it only change the y_range of the other plot than the one on which the x_range was actually changed. Even though that on console log I can see that both ranges (for both plots) were set as requested. I would expect this JS callback would change both plots.
Thank you
EDIT:
Here is minimal working example. Notice console output. The expected y_ranges are printed correctly, however the plot (the other one) is not actually rescaled as I would be expecting.
from bokeh.plotting import figure
from bokeh.plotting import output_file
from bokeh.plotting import save
from bokeh.models import ColumnDataSource
from bokeh.models.callbacks import CustomJS
from bokeh.models.ranges import DataRange1d
from bokeh.layouts import gridplot
output_file("pok.html")
cds = ColumnDataSource({
'x0': [1, 2, 3, 4, 5],
'y1': [1, 2, 3, 2, 1],
'y2': [3, 2, 1, 2, 3],
})
fig1 = figure(
x_range=(cds.data['x0'][0], cds.data['x0'][-1]),
y_range=DataRange1d(only_visible=True),
tools='xbox_zoom',
output_backend='webgl',
)
fig2 = figure(
x_range=fig1.x_range,
y_range=DataRange1d(only_visible=True),
tools='xbox_zoom',
output_backend='webgl',
)
lin1 = fig1.line(x='x0', y='y1', source=cds)
lin2 = fig2.line(x='x0', y='y2', source=cds)
xRangeChanged = CustomJS(
args={
'y1Range': fig1.y_range,
'y2Range': fig2.y_range,
},
code="""
console.log('xRangeChanged');
console.log('y1Range: ' + y1Range.start + ' - ' + y1Range.end)
console.log('y2Range: ' + y2Range.start + ' - ' + y2Range.end)
y1Range.start = 1;
y1Range.end = 10;
y2Range.start = -10;
y2Range.end = 10;
console.log('y1Range: ' + y1Range.start + ' - ' + y1Range.end)
console.log('y2Range: ' + y2Range.start + ' - ' + y2Range.end)
"""
)
fig1.x_range.js_on_change('start', xRangeChanged)
fig1.x_range.js_on_change('end', xRangeChanged)
layout = gridplot(
[
[fig1],
[fig2],
],
toolbar_location='right',
sizing_mode='stretch_both'
)
save(layout)