我制作了一个链接到 CheckBoxGroup 的 Bokeh 热图,以便 CheckBoxGroup 中的事件项目对应于热图中显示的行。即选中/取消选中 CheckBoxGroup 中的框会在热图中添加或删除行。一切正常,除了我希望热图的行保持相同的高度,无论热图中有多少行。实际发生的情况是保留热图的原始高度,并调整行大小以适应原始高度。
我这里有一个 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.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 in range(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;
source.change.emit();
""")
selection.js_on_change('active', callback)
layout = row(widgetbox(selection), p)
show(layout)
我尝试更改plot.plot_height和plot.height_policy,但似乎都没有任何效果。
最佳答案
在 CustomJS
回调的最后几行中,在更新 yrange 以反射(reflect)已删除的数据
注释之后,您显式更改了范围 - 这正是使情节的表现就是这样。
只需删除 source.data = newdata;
之后的所有内容 - 您也不需要 source.change.emit();
,因为您更改了整个数据属性。
关于javascript - 如何在 Bokeh 热图中删除/添加行并保持行高?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60614866/