Hi,
this glitch has been bothering me for a while. I have 3 Select options: Group
contains a list of valid properties for Option X
and Option Y
- which are then translated into the plot, thus plot updates after every Select option.
The issue: When selecting Option X
, the ‘Option Y’ is reset to [0] item - and I would like it to stay as it was. You can see that if you select first ‘Option Y’ to e.g. z
, and then you want Option X
to be y
, the plot is updated and the Y will be reset to x
and not keeping its value.
Expected:
On Group
select: Option X
and Option Y
gets [0] items from the active group (group here has always x, y, z, but it is generally different - and this part works with this setup). So it will plot x
vs x
.
Selecting X
or Y
does not reset each other to [0].
I believe the error is within circular Select options that I have here, however, if I place update_group
in group; and update_x
in key_property_x, and update_y
in key_property_y – Nothing works.
group.on_change("value", update_x)
key_property_x.on_change("value", update_y)
key_property_y.on_change("value", update_group)
Here is the minimum executive code (I removed additional colorbar lines for clarity):
import numpy as np
from bokeh.io import curdoc
from bokeh.layouts import column, row
from bokeh.models import ColumnDataSource, Select
from bokeh.plotting import figure
from bokeh.transform import log_cmap
from bokeh.util.hex import hexbin
data = {'x': np.random.randint(10, size=1000),
'y': np.random.randint(20, size=500),
'z': np.random.randint(50, size=100)}
options = sorted(data.keys())
def update_group(attr, old, new):
key_property_x.options = options
key_property_y.options = options
return old, new
def update_x(attr, old, new):
key_property_x.options = options
key_property_x.value = options[0]
return old, new
def update_y(attr, old, new):
key_property_y.options = options
key_property_y.value = options[0]
group = Select(title="Group", value=options[0], options=options)
key_property_x = Select(title="Option X:", value=options[0], options=options)
key_property_y = Select(title="Option Y:", value=options[0], options=options)
group.on_change("value", update_x)
key_property_x.on_change("value", update_y)
key_property_y.on_change("value", update_group)
def update_plot():
return dict(x=data[key_property_x.value],
y=data[key_property_x.value])
p = figure(tools='pan,box_zoom,box_select,reset,wheel_zoom, undo,redo,save',
match_aspect=True, background_fill_color='white', toolbar_location="above")
p.grid.visible = False
source_bin = ColumnDataSource(data=dict(r=[], q=[], counts=[]))
hex_size = 1
def data_bin_change(attr, old, new):
p.xaxis.axis_label = key_property_x.value
p.yaxis.axis_label = key_property_y.value
x = data[new]
y = data[new]
bins = hexbin(x, y, hex_size)
source_bin.data = dict(r=bins.r, q=bins.q, counts=bins.counts)
key_property_x.on_change("value", data_bin_change)
key_property_y.on_change("value", data_bin_change)
col_map = data_bin_change(None, None, group.value)
cmap = log_cmap('counts', 'Cividis256', 1, col_map)
h = p.hex_tile(q="q", r="r", size=hex_size, line_color=None,
source=source_bin, fill_color=cmap)
curdoc().add_root(row(column(group, key_property_x, key_property_y), p))
I could really use help how to set up update_x
and update_y
so that one doesn’t reset the other (in this case OptionX resets OptionY). I tried various combinations of my current on_change
functions, and none of them worked.