散景图上的可点击点
Clickable dots on Bokeh Plots
我正在开发一个仪表板,用户可以在其中单击常规散点图上的许多点之一以获取有关该点的更多信息。每个点代表一组数据,单击时,用户应该能够看到 table,其中列出了相关数据组。
table 将列在绘图旁边,每次选择一个新点(或多个点)时,行都会改变。
然后我需要向此 table 添加过滤器,因此它也需要具有交互性。图在过滤过程中不会改变,只有 table 中的相关数据会改变。
我看过下面的例子,它实现了与我想要实现的完全相反的效果:
from bokeh.plotting import Figure, output_file, show
from bokeh.models import CustomJS
from bokeh.models.sources import ColumnDataSource
from bokeh.layouts import column, row
from bokeh.models.widgets import DataTable, TableColumn, Toggle
from random import randint
import pandas as pd
output_file("data_table_subset_example.html")
data = dict(
x=[randint(0, 100) for i in range(10)],
y=[randint(0, 100) for i in range(10)],
z=['some other data'] * 10
)
df = pd.DataFrame(data)
#filtering dataframes with pandas keeps the index numbers consistent
filtered_df = df[df.x < 80]
#Creating CDSs from these dataframes gives you a column with indexes
source1 = ColumnDataSource(df) # FIGURE
source2 = ColumnDataSource(filtered_df) # TABLE - FILTERED
fig1 = Figure(plot_width=200, plot_height=200)
fig1.circle(x='x', y='y', source=source1)
columns = [
TableColumn(field="x", title="X"),
TableColumn(field="z", title="Text"),
]
data_table = DataTable(source=source2, columns=columns, width=400, height=280)
button = Toggle(label="Select")
button.callback = CustomJS(args=dict(source1=source1, source2=source2), code="""
var inds_in_source2 = source2.get('selected')['1d'].indices;
var d = source2.get('data');
var inds = []
if (inds_in_source2.length == 0) { return; }
for (i = 0; i < inds_in_source2.length; i++) {
inds.push(d['index'][i])
}
source1.get('selected')['1d'].indices = inds
source1.trigger('change');
""")
show(column(fig1, data_table, button))
我尝试在按钮回调中替换 source1 和 source2 以尝试反转过滤(即选择图中的一个点并过滤数据 table)。但是数据 table 根本没有被过滤,而是简单地选择了与数据点对应的行。知道如何过滤掉图中未选择的其余行吗?
我在另一个问题中找到了答案:
显然也需要触发数据 table 更改。
我正在开发一个仪表板,用户可以在其中单击常规散点图上的许多点之一以获取有关该点的更多信息。每个点代表一组数据,单击时,用户应该能够看到 table,其中列出了相关数据组。
table 将列在绘图旁边,每次选择一个新点(或多个点)时,行都会改变。
然后我需要向此 table 添加过滤器,因此它也需要具有交互性。图在过滤过程中不会改变,只有 table 中的相关数据会改变。
我看过下面的例子,它实现了与我想要实现的完全相反的效果:
from bokeh.plotting import Figure, output_file, show
from bokeh.models import CustomJS
from bokeh.models.sources import ColumnDataSource
from bokeh.layouts import column, row
from bokeh.models.widgets import DataTable, TableColumn, Toggle
from random import randint
import pandas as pd
output_file("data_table_subset_example.html")
data = dict(
x=[randint(0, 100) for i in range(10)],
y=[randint(0, 100) for i in range(10)],
z=['some other data'] * 10
)
df = pd.DataFrame(data)
#filtering dataframes with pandas keeps the index numbers consistent
filtered_df = df[df.x < 80]
#Creating CDSs from these dataframes gives you a column with indexes
source1 = ColumnDataSource(df) # FIGURE
source2 = ColumnDataSource(filtered_df) # TABLE - FILTERED
fig1 = Figure(plot_width=200, plot_height=200)
fig1.circle(x='x', y='y', source=source1)
columns = [
TableColumn(field="x", title="X"),
TableColumn(field="z", title="Text"),
]
data_table = DataTable(source=source2, columns=columns, width=400, height=280)
button = Toggle(label="Select")
button.callback = CustomJS(args=dict(source1=source1, source2=source2), code="""
var inds_in_source2 = source2.get('selected')['1d'].indices;
var d = source2.get('data');
var inds = []
if (inds_in_source2.length == 0) { return; }
for (i = 0; i < inds_in_source2.length; i++) {
inds.push(d['index'][i])
}
source1.get('selected')['1d'].indices = inds
source1.trigger('change');
""")
show(column(fig1, data_table, button))
我尝试在按钮回调中替换 source1 和 source2 以尝试反转过滤(即选择图中的一个点并过滤数据 table)。但是数据 table 根本没有被过滤,而是简单地选择了与数据点对应的行。知道如何过滤掉图中未选择的其余行吗?
我在另一个问题中找到了答案:
显然也需要触发数据 table 更改。