I want to change the color of my plot during runtime by selecting the data sources column name from a dropdown list.
Here is my code:
import pandas as pd
from bokeh.models import Dropdown, ColumnDataSource, CustomJS
from bokeh.transform import factor_cmap
from bokeh.layouts import column
from bokeh.plotting import show,figure
plot = figure(tools='tap, pan, wheel_zoom', width=1500, height=700 )
node_df = pd.DataFrame(data=dict(x=[1, 2, 3], y=[4, 5, 6], Option_A=['red', 'green', 'blue'], Option_B=['green', 'blue','red']))
node_source = ColumnDataSource(node_df)
mapper = factor_cmap(field_name='Option_A', palette=['red', 'green', 'blue'], factors = ['red','green','blue'])
node_renderer = plot.circle('x', 'y', source=node_source, size=10, color=mapper, selection_color=mapper,
nonselection_color=mapper, selection_alpha=1, nonselection_alpha=0.2, line_color="black",
selection_line_color="black", nonselection_line_color="black")
Dropdown_node_color = Dropdown(button_type="warning", menu = ['Option_A','Option_B'])
callback_node_color = CustomJS(args=dict(renderer=node_renderer, source=node_source),code="""
renderer.glyph.field = this.item;
renderer.change.emit();
""")
Dropdown_node_color.js_on_event("menu_item_click", callback_node_color)
layout = column(
Dropdown_node_color,
plot
)
show(layout)
A possible work around is the following:
import pandas as pd
from bokeh.models import Dropdown, ColumnDataSource, CustomJS
from bokeh.transform import factor_cmap
from bokeh.layouts import column
from bokeh.plotting import show,figure
plot = figure(tools='tap, pan, wheel_zoom', width=1500, height=700 )
node_df = pd.DataFrame(data=dict(x=[1, 2, 3], y=[4, 5, 6], Option_A=['red', 'green', 'blue'], Option_B=['green', 'blue','red']))
node_source = ColumnDataSource(node_df)
mapper = factor_cmap(field_name='Fillcolor', palette=['red', 'green', 'blue'], factors = ['red','green','blue'])
node_renderer = plot.circle('x', 'y', source=node_source, size=10, color=mapper, selection_color=mapper,
nonselection_color=mapper, selection_alpha=1, nonselection_alpha=0.2, line_color="black",
selection_line_color="black", nonselection_line_color="black")
Dropdown_node_color = Dropdown(button_type="warning", menu = ['Option_A','Option_B'])
callback_node_color = CustomJS(args=dict(renderer=node_renderer, source=node_source),code="""
//renderer.glyph.field = this.item;
//renderer.change.emit();
var selected_column_data = source.data[this.item];
source.data['Fillcolor'] = selected_column_data;
source.change.emit();
""")
Dropdown_node_color.js_on_event("menu_item_click", callback_node_color)
layout = column(
Dropdown_node_color,
plot
)
show(layout)
I have only found examples of how to do this by updating the values in the ColumnDataSource, but I'd like to avoid this copying work around.
How could I solve this without using a server application? I'd be very grateful for tips (also in general about using bokeh).