Issue with bound function after replacing object inside hvplot

Hi all, I’m working on a little app to show galaxy images. I have made it so that when a particular pixel in a hvplot Bokeh instance is clicked on, this is detected by stream.Tap, which calls a bound function to record which pixel was clicked. When I replace the hvplot object with an alternative plot, using a RadioButton to replace it via the .object attribute, the stream/bound function appears to stop working. I’ve tried to recreate this using minimal code whilst maintaing the functions/structure of the project, which is below. The idea for the demo is if you click on a point in the lefthand plot, it will display a number on the righthand plot. If you switch from option 1 to option 2 in the menu, this no longer works. I try to explicitly set stream.source = bin_map.object when I replace the plot, but it doesn’t seem to help. Any ideas are much appreciated!

import panel as pn
import numpy as np
from panel.layout.gridstack import GridStack
from matplotlib.figure import Figure
import matplotlib as mpl
import xarray as xr
import holoviews as hv
import hvplot.xarray
import matplotlib.cm as cm
import matplotlib.pyplot as plt
import sys

#sns.set_context("paper")
#plt.style.use('paper.mplstyle')

ACCENT = "goldenrod"
# panel serve ResolvedSEDApp.py --autoreload


pn.extension(sizing_mode="stretch_width", design='material')
pn.extension('gridstack')
facecolor = '#f7f7f7'

stream = hv.streams.Tap()

def plot_sed(x, y, cmap, shown_bins):
    skip = False
    if x == None or y == None:
        skip = True

    if not skip:
        
        random_array = np.random.uniform(size=(64, 64))
        bin = random_array[int(np.ceil(y)), int(np.ceil(x))]
        if bin not in shown_bins:
            shown_bins.append(bin)
    
    fig, ax = plt.subplots(figsize=(6, 3), constrained_layout=True, facecolor=facecolor)

    for bin in shown_bins:
        ax.text(0.5, 0.5, f"SED bin: {bin}", fontsize=20, ha='center', va='center', color='red')
        
    
    return pn.pane.Matplotlib(fig, dpi=144, tight=True, format="svg", sizing_mode="stretch_width")
    #return False


def update_image(value):

    # Problem is here? The plot_sed function which is bound to the stream is not being called after the plot is updated
    global shown_bins
    
    shown_bins = []
    bin_plot = plot_bins(value, 'viridis')
    bin_map.object = bin_plot
    stream.source = bin_map.object


def update_sidebar(active_tab, sidebar):

    settings_sidebar = pn.Column(pn.layout.Divider(), "### Settings", name='settings_sidebar')
    which_map = pn.widgets.RadioButtonGroup(options=['option 1', 'option 2'], value='option 1', name='Pixel Binning')
    settings_sidebar.append('#### Pixel Binning')
    settings_sidebar.append(which_map)

    pn.bind(update_image, which_map.param.value, watch=True)

    if active_tab == 0:
        sidebar.append(settings_sidebar)
    else:
        # Check if already in sidebar
        for item in sidebar:
            if item.name == 'settings_sidebar':
                sidebar.remove(item)


def plot_bins(bin_type, cmap):
    array = np.random.uniform(size=(64, 64))
    dimensions = np.linspace(0, 64, 64)
    im_array = xr.DataArray(array, dims=['y', 'x'], name=f'{bin_type} bins', coords={'x': dimensions, 'y': dimensions})
    hvplot = im_array.hvplot('x','y').opts(cmap=cmap, xaxis=None, yaxis=None, clabel=f'{bin_type} Bin')
    return hvplot


def main(components):
    global shown_bins
    global bin_map
    global stream 
    global sed_results_grid
    global cmap

    sidebar, tabs = components

    sed_results_grid = GridStack(sizing_mode='stretch_both', allow_resize=True,
                                allow_drag=True, min_height=400, mode='override', nrows=1, ncols=4)

    cmap = 'viridis'
    hvplot_bins = plot_bins('type 1', cmap)
    
    bin_map = pn.pane.HoloViews(hvplot_bins, sizing_mode='stretch_height')
    
    stream.source = bin_map.object

    shown_bins = []
    obj = pn.bind(plot_sed, stream.param.x, stream.param.y, cmap, shown_bins, watch=False)
    
    sed_results_grid[0, :2] = bin_map
    sed_results_grid[0, 2:] = obj

    galaxy_tabs = pn.Tabs()

    galaxy_tabs.append(('Galaxy 1', sed_results_grid))
    
    update_sidebar(0, sidebar)
    tabs.append(('Galaxy 1', galaxy_tabs))
    
    
def resolved_sed_interface():

    tabs = pn.Tabs(closable=True, dynamic=True)
    
    sidebar = pn.Column("### Upload .h5")
    
    components = [sidebar, tabs]

    main(components)

    return pn.template.FastListTemplate(
        title="Resolved SED Viewer", sidebar=[sidebar], main=[tabs], accent=ACCENT
    )

resolved_sed_interface().servable()