Tap: Replace the current selection instead of toogle

Hi guys,

I am building an application in which I click on a heatmap and get the corresponding line.

The Tap has by default selected the “Toggle current selection” but I observed that after the first click on a heatmap element, it doesn’t update the corresponding line. But when I have selected in the Tap the “Replace current selection”, it works fine. I mean, each time I click I get always the updated line.

Can I set programmatically the default on the Tap to “Replace Current Selection” ???

Here is a minimal example:

from bokeh.io import curdoc
from bokeh.layouts import column
from bokeh.models import ColumnDataSource, ColorBar, LinearColorMapper
from bokeh.plotting import figure
from bokeh.transform import linear_cmap
import numpy as np
import pandas as pd

# Create initial random heatmap data
heatmap_data = np.random.random((10, 10))

# Data for time series plot (initially empty)
time_series_data = pd.DataFrame(dict(x=[], y=[]))

# Create a heatmap figure
heatmap_source = ColumnDataSource(data=dict(image=[heatmap_data]))
color_mapper = LinearColorMapper(palette="Viridis256", low=0, high=1)

p_heatmap = figure(title="Heatmap", tools="tap", x_range=(0, 10), y_range=(0, 10), )
p_heatmap.image(image='image', x=0, y=0, dw=10, dh=10, color_mapper=color_mapper, source=heatmap_source)
color_bar = ColorBar(color_mapper=color_mapper, location=(0, 0))
p_heatmap.add_layout(color_bar, 'right')

# Create the time series plot (initially empty)
time_series_source = ColumnDataSource(data=dict(x=[], y=[]))
p_timeseries = figure(title="Time Series", x_axis_label="Time", y_axis_label="Random Value", )
p_timeseries.line('x', 'y', source=time_series_source)

# Callback function to update the time series plot
def update_timeseries(attr, old, new):
    # Get the selected index from heatmap
    selected_index = new
    print(selected_index)
    if selected_index:
        # Generate random time series data
        x = np.arange(100)
        y = np.random.random(100)
        time_series_source.data = dict(x=x, y=y)

# Add the callback to the selected property of the ColumnDataSource
heatmap_source.selected.on_change('image_indices', update_timeseries)

# Layout of heatmap and time series
layout = column(p_heatmap, p_timeseries)

# Add the layout to the current document
curdoc().add_root(layout)

Thanks a lot.

I found the solution by adding these 3 lines of code:

from bokeh.models import TapTool
#...
tap_tool = p_heatmap.select(type=TapTool)
tap_tool.mode = 'replace'
1 Like