How to change a callback created before in the code?

I am working on a code for manual classification and it is a scatter plot with the dots’ color can be changed when selected. I think it will be much more convenient to be able to decide which color to change to. I wrote the following code:

class manual_clustering():
def init(self, DF_path, label, browser):
self.DF_path = DF_path
self.label = label

    self.DF_file = pd.read_csv(self.DF_path)
    self.s = ColumnDataSource(self.DF_file)
    self.browser = browser       # <<- this is a browser created by wxpython.html2

    self.TOOLTIPS = """

(here is a long code to show pictures of respective dots)
“”"

    self.p = figure(plot_width=500, plot_height=500, tooltips=self.TOOLTIPS,tools="lasso_select, tap", title="manual cluster")
    circles = self.p.circle('x', 'y', color='color', size=10, source=self.s, line_alpha=0.6, fill_alpha=0.6)
    circles.nonselection_glyph = None

    self.s.callback = CustomJS(args=dict(s1=self.s), code="""
             var inds = cb_obj.selected.indices;
             var d1 = s1.data;
    
            for (var i = 0; i < inds.length; i++)
             {d1['color_gt'][inds[i]] = 'red';}
    
             s1.change.emit();
         """ """% (self.label))


    html = file_html(self.p, INLINE)
    self.browser.SetPage(html, ".")

def change_label(self, label):
    self.label_set = label
    self.s.callback = CustomJS(args=dict(s1=self.s), code="""
            var inds = cb_obj.selected.indices;
            var d1 = s1.data;
            for (var i = 0; i < inds.length; i++) 
            {d1['color_gt'][inds[i]] = '%s';}
            s1.change.emit();
        """ % (self.label_set))
    print(self.s.callback.code)

I can see self.s.callback.code actually changed when function change_label is used. However, what the callback is actually doing is still what it is set to do at the beginning. I wonder how can I change the callback.

  1. ColumnDataSource.callback is deprecated and will be removed in 2.0, don’t use it. Instead, use source.selected.js_on_change(...)
  2. You’re rendering the figure in a static HTML file. Do you re-render it and refresh the file when you change the callback? There’s a way to do what you need without re-rendering but you cannot use Python for that - you must use JS. An alternative is to use Bokeh server and manage the document state at the backend.