☰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

Use Inverted Colormaps on Select

Community Support
rdzudzar
rdzudzar

Hi,
I am trying to implement inverted colormap from existing Bokeh colormaps into Select (or import some others from matplotlib or e.g. CMasher package). In this example I used invert_viridis = Viridis256[::-1] to create inverted colormap.

When I start bokeh serve, with this defined colormap it shows up nicely, however, if I use Select widget to chose different colormap and then get back to invert_viridis it gives me this error:

ValueError: expected an element of Seq(Color), got 'invert_viridis'

I believe this is because invert_viridis is not defined within Bokeh, like Viridis256, Cividis256 etc. Is it possible and how to implement other colormaps into Select so that they are recognized?

Minimum working example (changing colormap to a different one and then back to ‘invert_viridis’) will give mentioned error:

import numpy as np

from bokeh.io import curdoc
from bokeh.layouts import column, row
from bokeh.models import ColorBar, LogTicker, HoverTool, ColumnDataSource, Select
from bokeh.plotting import figure
from bokeh.transform import log_cmap
from bokeh.util.hex import hexbin

from bokeh.palettes import Viridis256

data = {'x': np.random.randint(300, size=1000),
        'y': np.random.randint(200, size=1000),
        'z': np.random.randint(50, size=100)}


options = sorted(data.keys())

p = figure(tools='pan,box_zoom,box_select,reset,wheel_zoom, undo,redo,save',
           match_aspect=True, background_fill_color='white', toolbar_location="above")
p.grid.visible = False

source_bin = ColumnDataSource(data=dict(r=[], q=[], counts=[]))
hex_size = 10

    
bins = hexbin(data['x'], data['y'], hex_size)
source_bin.data = dict(r=bins.r, q=bins.q, counts=bins.counts)


invert_viridis = Viridis256[::-1]
cmap = log_cmap('counts', invert_viridis, 1, max(bins.counts))

# Colormaps
cbar = Select(title="Choose Colormap", value="invert_viridis",
              options=["invert_viridis", "Cividis256", "Viridis256"])

# Update colormap
def update_colorbar():
    cmap = log_cmap('counts', palette=cbar.value, low=1, high=max(bins.counts))
    color_bar.color_mapper.palette = cbar.value
    

cbar.on_change('value', lambda attr, old, new: update_colorbar())


h = p.hex_tile(q="q", r="r", size=hex_size, line_color=None,
           source=source_bin, fill_color=cmap)

color_bar = ColorBar(title="Counts", 
            color_mapper=cmap['transform'],
            location=(0, 0),
            ticker=LogTicker(),
            label_standoff=12,
            )

p.add_tools(HoverTool(tooltips=[('Counts', '@counts')],
                      mode='mouse',
                      point_policy='follow_mouse',
                      renderers=[h]))

p.add_layout(color_bar, 'right')

curdoc().add_root(row(column(cbar), p))
⌁   Link to post
rdzudzar
rdzudzar

Thank you for the reply.

If I place invert_viridis[:] into value and options then I get ValueError that it accepts strings:

ValueError: expected a value of type str, got ('#FDE724', '#FAE622', '#F8E621', '#F6E61F', '#F3E51E', '#F1E51C', '#EEE51B', '#ECE41A', '#E9E419', '#E7E419', '#E4E318', '#E1E318', '#DFE318', '#DCE218', '#DAE218', '#D7E219', '#D4E11A', '#D2E11
⌁   Link to post
Bryan
Bryan

The select values can only be strings. Your will have to use a conditional inside the callback to check for special color map name and then pass the actual color sequence.

⌁   Link to post
rdzudzar
rdzudzar

Understood. I changed the function to do exactly that and it works.

Change made:

invert_viridis = Viridis256[::-1]

cmap = log_cmap('counts', invert_viridis[:], 1, max(bins.counts))


# Perceptually Uniform Sequential Colormaps - available in Bokeh
cbar = Select(title="Choose Colormap", value='test',
              options=['test', "Cividis256", "Viridis256"])


def update_colorbar():
    
    if cbar.value == 'test':
        cmap = log_cmap('counts', palette=invert_viridis[:], low=1, high=max(bins.counts))
        color_bar.color_mapper.palette = invert_viridis[:]

    else:
        cmap = log_cmap('counts', palette=cbar.value, low=1, high=max(bins.counts))
        color_bar.color_mapper.palette = cbar.value

Thank you.

⌁   Link to post

End of archived discussion · Replies are disabled