☰Read-only archive⌕
Looking for help with Bokeh?

This is a read-only archive. Ask questions and join the conversation on GitHub.

Visit Community Support on GitHub →
Archived discussions · Captured October 28, 2026

How to link ColorPicker with factor_cmap

Community Supportbokeh
Jonas_Grave_Kristens
Jonas_Grave_Kristens

@dinya Actually I do not see any reason to have multiple CDS, one for each bar. One way to achieve what you want is to have a fruit Selector and one ColorPicker. Add a CustomJS callback to each of those widgets. Example below is based on using factor_cmap for fill_color of the vbar. If instead one is using a specific field in the CDS for color of the bars, then one can easily change callbacks for that case.

The CustomJS callback for the Selector is used to update the color property of the ColorPicker in order to display the current color of the selected fruit (bar) .

CustomJS callback for the ColorPicker is used to update the palette in the factor_cmap that is used to map fill_color to the fruits.

from bokeh.models import ColumnDataSource, ColorPicker, CustomJS, Select
from bokeh.palettes import Bright6
from bokeh.plotting import figure, show
from bokeh.transform import factor_cmap
from bokeh.layouts import column, row

fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']
counts = [5, 3, 4, 2, 4, 6]

source = ColumnDataSource(data=dict(fruits=fruits, counts=counts))

p = figure(
    x_range = fruits, height = 350,
    toolbar_location = None,
    title = "Fruit Counts"
    )

r_vbar = p.vbar(
    x = 'fruits', top = 'counts', width=0.9,
    source = source, legend_field = "fruits",
    line_color = 'white',
    fill_color = factor_cmap('fruits', palette=Bright6, factors=fruits)
    )

p.xgrid.grid_line_color = None
p.y_range.start = 0
p.y_range.end = 9
p.legend.orientation = "horizontal"
p.legend.location = "top_center"

select = Select(
    title = 'Fruit',
    value = fruits[0],
    options = fruits
    )

color_picker = ColorPicker(
    title = 'Bar color specific fruit',
    color = r_vbar.glyph.fill_color.transform.palette[fruits.index(select.value)]
    )

# add callbacks to widgets
# update color picker with current color of selected fruit
select.js_on_change(
    "value",
    CustomJS(
        args = {
            'vbar': r_vbar,
            'color_picker': color_picker
        },
        code="""
          const idx = this.options.indexOf(this.value);
          const color = vbar.glyph.fill_color.transform.palette[idx];
          color_picker.color = color;
        """
    )
)

# update vbar color mapper
color_picker.js_on_change(
    'color',
    CustomJS(
        args = {
            'select': select,
            'vbar': r_vbar,
            'plot': p
        },
        code="""
          const idx = select.options.indexOf(select.value);
          const {transform} = vbar.glyph.fill_color;
          transform.palette[idx] = this.color;
          vbar.glyph.fill_color = {field: 'fruits', transform: transform};
          plot.reset.emit();
        """
    )
)

show(column(p, row(select, color_picker)))
⌁   Link to post

End of archived discussion · Replies are disabled