Skip to content
Advertisement

Bokeh: how to custom scale of ColorBar?

I make a figure (empty to simplify the code but I will add many elements), and a ColorBar to designate the color of different elements.

from bokeh.models import LinearColorMapper, ColorBar, BasicTicker, PrintfTickFormatter
from bokeh.plotting import figure, show, output_file

output_file('image.html')

p = figure(x_range=(0,1), y_range=(0,1), toolbar_location=None)
p.toolbar.active_drag = None

data_heatmap = [-647, 25756, -7600, -1235, -1345]

colors = ["#465a55", "#75968f", "#a5bab7", "#c9d9d3", "#e2e2e2", "#dfccce", "#ddb7b1", "#cc7878", "#933b41", "#550b1d"]
mapper = LinearColorMapper(palette=colors, low=min(data_heatmap), high=max(data_heatmap))

color_bar = ColorBar(
            color_mapper=mapper,
            major_label_text_font_size="15px",
            ticker=BasicTicker(desired_num_ticks=len(colors)),
            formatter=PrintfTickFormatter(format="%d"),
            label_standoff=6, border_line_color=None
)
p.add_layout(color_bar, 'right')

show(p)

Now the color bar gives this result:

enter image description here

But I’m not satisfied because I’d like to have a different scale of colors where all positive values are red and all negative values are green. Moreover, I’d like to have defined ticks that will be customized in advance.

  • #465a55: x < -5000
  • #75968f: -5000 < x < -2500
  • #a5bab7: -2500 < x < -1000
  • #c9d9d3: -1000 < x < -500
  • #e2e2e2: -500 < x < 0
  • #dfccce: 0 < x < 500
  • #ddb7b1: 500 < x < 1000
  • #cc7878: 1000 < x < 2500
  • #933b41: 2500 < x < 5000
  • #550b1d: x > 5000

The result would look like this:

enter image description here

Thank you!

Advertisement

Answer

Finally, I found how to custom the ColorBar with predefined values. I changed color palette by multiplying each color by the number corresponding to the interval of the color (for example: #75968f between -5000 and -2500 = 2500):

colors = ["#465a55"]*5000 + ["#75968f"]*2500 + ["#a5bab7"]*1500 + ["#c9d9d3"]*500 + ["#e2e2e2"]*500 + ["#dfccce"]*500 + ["#ddb7b1"]*500 + ["#cc7878"]*1500 + ["#933b41"]*2500 + ["#550b1d"]*5000

The mapper is now delimited by defined values, not by min and max elements:

mapper = LinearColorMapper(palette=colors, low=-10000, high=10000)

And I changed BasicTicker for FixedTicker so that the ticks correspond well to the limit of each color:

from bokeh.models import FixedTicker
ticker = FixedTicker(ticks=[-5000, -2500, -1000, -500, 0, 500, 1000, 2500, 5000])

The result:

enter image description here

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement