Is there a way to add a new axis to a bokeh graph after it is already being displayed?

I’m trying to update a figure that is being run on a bokeh server. I found out that you can use figure.extra_y_ranges = {'name':Range1d(0,10)} and then calling figure.add_layout(LinearAxis(y_range_name='name'),'right') to add a new y-axis with the range of 0-10 to my figure. However this only works for me if I do it right after initiating the figure. What I’m trying to do however is that the new y-axis is being added on a button click.

Here is a simplified version of the code I’m running:

from bokeh.io import curdoc
from bokeh.plotting import figure
from bokeh.models import LinearAxis, Range1d
from bokeh.models.widgets import Button
from bokeh.layouts import column, row, grid
def update_fig(fig):
fig.extra_y_ranges = {‘a’:Range1d(0,10)}
fig.add_layout(LinearAxis(y_range_name=‘a’, axis_label=‘a’), ‘left’)
def update_axis():
update_fig(fig)
fig = figure()
fig.circle_dot([1,2,3,4],[1,2,3,4])
update_fig(fig) # This works
value_sel = Button(label=‘Add y-axis’)
value_sel.on_click(update_axis) # This doesn’t work
layout = row(
column(value_sel),
grid(fig)
)
curdoc().add_root(layout)

I’m then running the function with bokeh serve --show example.py

Any help would be appreciated, thanks!

It’s a known bug, see [BUG] add_layout(LinearAxis) in click handler crashes client · Issue #11033 · bokeh/bokeh · GitHub.

Oh, thanks for the reply.

I’ve only used python callbacks so far, is it possible to bypass the bug using javascript callbacks?

I am now using a workaround where I remove the figure from the layout, then add the second y axis and then add the figure back to the layout incase anyone is having the same problem

@jonkubi

An alternative possible workaround might be to create the second y-axis upfront with its visible property set to False. And then use your button-click action to set visible to True.

1 Like

@_jm suggestion about adding axes up front and hiding/showing them will probably yield the best results.

Thanks for the replies, I’ll be switching to that method :+1: