Reputation: 3263
I need to swap the x and y axes of a plot after the plot object has been created with Bokeh. I've tried to do this as follows but get the following javascript error:
Javascript Error: Cannot read property 'length' of undefined
I think this might be possible because of this bokeh issue with related PR and gist.
I'm wondering what I'm missing (or not understanding) here to get this to work.
import bokeh.plotting
import bokeh.io
def swap_axes(plot):
old_x_axis, old_y_axis = plot.below[0], plot.left[0]
old_x_range, old_y_range = plot.x_range, plot.y_range
old_x_scale, old_y_scale = plot.x_scale, plot.y_scale
plot.below = []
plot.left = []
plot.add_layout(old_y_axis, 'below')
plot.add_layout(old_x_axis, 'left')
plot.x_range, plot.y_range = old_y_range, old_x_range
plot.x_scale, plot.y_scale = old_y_scale, old_x_scale
plot.center = plot.center[::-1]
return plot
fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']
counts = [5, 3, 4, 2, 4, 6]
p = bokeh.plotting.figure(x_range=fruits, plot_height=250, title="Fruit Counts",
toolbar_location=None, tools="")
p.vbar(x=fruits, top=counts, width=0.9)
bokeh.io.show(p)
bokeh.io.show(swap_axes(p))
Upvotes: 0
Views: 388
Reputation: 34628
It's unclear why you would ever need to update a plot a plot in place in this manner outside a Bokeh server application, which actually keeps live objects in sync across the Python/JS runtime. In standalone HTML output there is literally no important way in which one plot being used to two separate file would be distinguishable from two plots being used to generate two separate files.
Regardless, this particular kind of re-arranging is going to be especially troublesome with Bokeh, as there are very many pieces that would need to be shuffled correctly. Besides what you have above, the tickers for the axes also drive the grids, those would need to be fixed up. This line: plot.center = plot.center[::-1]
does nothing of use (it does not change how the grids are configured, merely the order they are drawn). There are probably other things that need to be swapped as well.
It's a non-trivial task and basically no one has asked for it in ~6 years so we have not invested any of the very finite project resources into making it easy. My advice, as one of the lead core developers, is that you should make a function that can return two versions of the plot, based on a flag parameter, and show the two separate plots:
show(make_plot(swapped=False))
show(make_plot(swapped=True))
Also:
but just get a javascript error.
For future reference, if there is an error message, it should always, always, always be included with the question.
Upvotes: 2