Hi,
I ran into an issue on how to update extra_y_ranges
as the new x
or y
axis is selected, and I could use your help.
Short description: I’m building dashboard that display data with large range of values, so in order to have nice hexbin
display, I normalized the data (in range 0, 1) - otherwise I wasn’t able to make haxbin display with x axis values of 0-8 while y axis is 10e5-10e15. However, I would like to have on extra y and x axis the real values (or if possible overwrite the current ones). I tried manually setting yaxis.major_label_overrides
however that doesn’t work with zoom (as it disappears), and I can only define max
value.
My other approach was with extra range, however, the Figure disappears and doesn’t updates when I select new x/y axis. Can you help me with placing extra_y_ranges
in order to update Figure and the other y_axis on selecting new x/y values?
p.extra_y_ranges = {"yraw": Range1d(start=min(data[new]),
end=max(data[new]),
)}
p.add_layout(LinearAxis(y_range_name="yraw"), 'right')
Minimum executive code with one dropdown menu and ranges
are in the data_bin_change
function:
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(200, size=50),
'y': np.random.randint(20, size=50),
'z': np.random.randint(10, size=50)}
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.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
p.extra_y_ranges = {"yraw": Range1d(start=min(data[new]),
end=max(data[new]),
)}
p.add_layout(LinearAxis(y_range_name="yraw"), 'right')
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)
key_property_x.on_change("value", data_bin_change)
# Populate the initial data.
data_bin_change(None, None, key_property_x.value)
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)
p.add_tools(HoverTool(tooltips=[('Counts', '@counts')],
mode='mouse',
point_policy='follow_mouse',
renderers=[h]))
p.add_layout(ColorBar(color_mapper=cmap['transform'],
location=(0, 0),
ticker=LogTicker()),
'right')
curdoc().add_root(row(column(key_property_x), p))