Hi, I have yet another question (sorry if I’m posting these too frequent).
I am looking for a way to update color_bar
when I change the data. I have cmap
, h
(figure) and color_bar
within data_bin_change
function, and in this setup hexbin plot gets updated - selecting different data, I can see that the colormap resets to min/max values of that data, however color_bar
remains the same. Here is the minimum working example, using bokeh version 2.2.3.
import numpy as np
from bokeh.io import curdoc
from bokeh.layouts import column, row
from bokeh.models import ColorBar, LogTicker, HoverTool, ColumnDataSource, Select
from bokeh.plotting import figure
from bokeh.transform import log_cmap
from bokeh.util.hex import hexbin
from bokeh.models import Range1d, LinearAxis
data = {'x': np.random.randint(10e4, size=1000),
'y': np.random.randint(200, size=500),
'z': np.random.randint(50, size=100)}
options = sorted(data.keys())
key_property_x = Select(title="Option:", value=options[0], options=options)
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 = 0.05
def normalize_data(data):
#Normalized data to max
# If data is all 0, then just parse the data
if (data.max(axis=0) != 0):
data_normed = data / data.max(axis=0)
else:
data_normed = data
return data_normed
def data_bin_change(attr, old, new):
p.xaxis.axis_label = p.yaxis.axis_label = new
x_normed = normalize_data(data[new])
y_normed = normalize_data(data[new])
bins = hexbin(x_normed, y_normed, hex_size)
source_bin.data = dict(r=bins.r, q=bins.q, counts=bins.counts)
cmap = log_cmap('counts', 'Cividis256', 1, max(source_bin.data['counts']))
h = p.hex_tile(q="q", r="r", size=hex_size, line_color=None,
source=source_bin, fill_color=cmap)
color_bar = ColorBar(title="Counts",
color_mapper=cmap['transform'],
location=(0, 0),
ticker=LogTicker(),
label_standoff=12,
)
return cmap, h, color_bar
key_property_x.on_change("value", data_bin_change)
data_bin_change(None, None, key_property_x.value)
cmap, h, color_bar = data_bin_change(None, None, key_property_x.value)
p.add_tools(HoverTool(tooltips=[('Counts', '@counts')],
mode='mouse',
point_policy='follow_mouse',
renderers=[h]))
p.add_layout(color_bar, 'right')
curdoc().add_root(row(column(key_property_x), p))
I tried with placing cmap
, h
, and color_bar
to different positions, and couldn’t achieve the goal.
If I place Figure h
outside data_bin_change, the colormap does not get any updates - it just uses min/max from all data.
h = p.hex_tile(q="q", r="r", size=hex_size, line_color=None,
source=source_bin, fill_color=cmap)
What I am trying to achieve is that with the new data, hexbin colormap updates to min/max value of that data (min is always 1), and the colorbar also updates to show new min/max values.