Last active
May 20, 2019 13:34
-
-
Save rothnic/18371807da60b288166f to your computer and use it in GitHub Desktop.
Example Bokeh app that swaps axis and range out dynamically
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from bokeh.models import GlyphRenderer, ColumnDataSource | |
from bokeh.models.plots import Plot | |
from bokeh.models import Circle, Range1d, LinearAxis, CategoricalAxis, Axis, FactorRange | |
from bokeh.models.widgets import HBox, VBoxForm, Select | |
from bokeh.io import curdoc | |
data = {'a': [1, 2, 3, 4], | |
'b': [3, 5, 4, 5], | |
'c': ['foo', 'bar', 'foo', 'bar']} | |
col_names = list(data.keys()) | |
# because dimensions and attributes of chart are modeled, this could be auto generated | |
x_select = Select( | |
title='x', name='x_select', | |
options=col_names, value='a' | |
) | |
y_select = Select( | |
title='y', name='y_select', | |
options=col_names, value='b' | |
) | |
x_range = Range1d(start=0, end=10) | |
y_range = Range1d(start=0, end=10) | |
x_range_cat = FactorRange(factors=data['c']) | |
y_range_cat = FactorRange(factors=data['c']) | |
x_axis = LinearAxis() | |
y_axis = LinearAxis() | |
x_axis2 = CategoricalAxis() | |
y_axis2 = CategoricalAxis() | |
plot = Plot(x_range=x_range, y_range=y_range) | |
plot.add_layout(x_axis, 'below') | |
plot.add_layout(y_axis, 'left') | |
ds = ColumnDataSource(data) | |
glyph = Circle(x='a', y='b') | |
renderer = GlyphRenderer(data_source=ds, glyph=glyph) | |
plot.renderers.append(renderer) | |
selectors = [x_select, y_select] | |
inputs = VBoxForm(children=selectors) | |
hbox = HBox(children=[inputs, plot]) | |
def update_data(): | |
new_renderers = [] | |
for renderer in plot.renderers: | |
if not isinstance(renderer, Axis): | |
new_renderers.append(renderer) | |
plot.renderers = new_renderers | |
plot.below = [] | |
plot.left = [] | |
if x_select.value == 'c': | |
this_x_axis = x_axis2 | |
this_x_range = x_range_cat | |
else: | |
this_x_axis = x_axis | |
this_x_range = x_range | |
if y_select.value == 'c': | |
this_y_axis = y_axis2 | |
this_y_range = y_range_cat | |
else: | |
this_y_axis = y_axis | |
this_y_range = y_range | |
this_y_axis.plot = None | |
this_x_axis.plot = None | |
plot.add_layout(this_x_axis, 'below') | |
plot.add_layout(this_y_axis, 'left') | |
plot.x_range = this_x_range | |
plot.y_range = this_y_range | |
glyph.x = x_select.value | |
glyph.y = y_select.value | |
def input_change(attrname, old, new): | |
update_data() | |
for selector in selectors: | |
selector.on_change('value', input_change) | |
curdoc().add_root(hbox) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment