How To Delete/add Rows In Bokeh Heatmap And Maintain Row Height?
I've made a Bokeh heatmap linked to a CheckBoxGroup, so that the active items in the CheckBoxGroup correspond to the rows displayed in the heatmap. i.e. checking/unchecking boxes i
Solution 1:
In the last lines of the CustomJS
callback, right after the update the yrange to reflect the deleted data
comment, you explicitly change the range - and that's exactly what makes the plot behave the way it does.
Just remove everything after source.data = newdata;
- you don't need source.change.emit();
either since you change the whole data attribute.
Solution 2:
What was needed here was to adjust frame_height
in the callback and call plot.properties.height.change.emit()
- answered with some help from here: https://discourse.bokeh.org/t/how-to-delete-add-rows-in-bokeh-heatmap-and-maintain-row-height/4917/10
Final MWE:
from bokeh.io import output_file, show
from bokeh.models import ColorBar, ColumnDataSource, LinearColorMapper
from bokeh.plotting import figure
from bokeh.transform import transform
from bokeh.layouts import row, widgetbox
from bokeh.models.callbacks import CustomJS
from bokeh.models.widgets import CheckboxGroup
import pandas as pd
output_file("test.html")
# set up data
df = pd.DataFrame([["1", "1", 0.09], ["2", "1", 0.21], ["3", "1", 0.31], ["4", "1", 0.41],
["1", "2", 0.5], ["2", "2", 0.61], ["3", "2", 0.71], ["4", "2", 0.81]],
columns=["x", "y", "values"])
# source data for plot
source = ColumnDataSource(df)
# original source dataset, does not get changed
savedsource = ColumnDataSource(df)
# set up plot
colors = ["#5A736F", "#75968f", "#a5bab7", "#c9d9d3", "#e2e2e2", "#dfccce", "#ddb7b1", "#cc7878", "#933b41",
"#550b1d"]
mapper = LinearColorMapper(palette=colors, low=0, high=1)
p = figure(title="Test", plot_width=200, plot_height=240,
x_range=["1", "2", "3", "4"], y_range=["1", "2"],
toolbar_location=None, tools="", x_axis_location="above")
p.frame_height = 240# 2 rows of height 120
p.rect(x="x", y="y", width=1, height=1, source=source,
line_color=None, fill_color=transform('values', mapper))
p.axis.axis_line_color = None
p.axis.major_tick_line_color = None
p.axis.major_label_text_font_size = "9pt"
p.axis.major_label_standoff = 0
p.xaxis.major_label_orientation = 1.0# Create the checkbox selection element
rows = ["1", "2"]
selection = CheckboxGroup(labels=rows,
active=[i for i inrange(0, len(rows))])
callback = CustomJS(args=dict(source=source, savedsource=savedsource, plot=p),
code="""
// get selected checkboxes
var active = cb_obj.active;
// get full original dataset
var origdata = savedsource.data;
// number of x-values
var numxs = plot.x_range.factors.length;
// this will be the new dataset
var newdata = {"index": [], "values": [], "x": [], "y": []};
// new y labels
var newlabels = [];
// slice out the data we want and put it into newdata
var i, j;
for (j=0; j<active.length; j++)
{
i = active[j]; // next active checkbox
newdata.index.push(...origdata.index.slice(i*numxs, i*numxs + numxs));
newdata.values.push(...origdata.values.slice(i*numxs, i*numxs + numxs));
newdata.x.push(...origdata.x.slice(i*numxs, i*numxs + numxs));
newdata.y.push(...origdata.y.slice(i*numxs, i*numxs + numxs));
newlabels.push(...origdata.y.slice(i*numxs, i*numxs + 1));
}
// replace the plot source data with newdata
source.data = newdata;
// update the yrange to reflect the deleted data
plot.y_range.factors = newlabels;
plot.y_range.end = newlabels.length;
// update plot height
new_height = newlabels.length * 120; //rowheight is 120
plot.frame_height = new_height;
plot.properties.height.change.emit();
""")
selection.js_on_change('active', callback)
layout = row(widgetbox(selection), p)
show(layout)
Post a Comment for "How To Delete/add Rows In Bokeh Heatmap And Maintain Row Height?"