Reputation: 23
I'm working on a dashboard where the user clicks on one of many dots on a regular scatter plot to get more information about that dot. Each dot represents a group of data, and when clicked on, the user should be able to see a table in which the related group of data is listed.
The table will be listed right next to the plot, and the rows will change every time a new dot (or multiple dots) is selected.
I'll then need to add filters to this table, so it needs to be interactive too. The plot does not change during filtering, only the related data in the table will.
I've seen the following example, which achieves the exact opposite that I want to achieve:
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))
I tried replacing source1 and source2 inside the button callback in an attempt to reverse the filtering (i.e. choose a point on the figure and filter the data table). But the data table is not filtered at all, instead the row that corresponds to the data point is simply selected. Any idea how to filter out the rest of the rows that are not selected on the plot?
Upvotes: 0
Views: 1235
Reputation: 23
I found the answer in another question: Bokeh DataTable won't update after trigger('change') without clicking on header
Apparently the data table change needs to be triggered too.
Upvotes: 1