Discrete colorbar with customized range

Hi all,

I am currently working on a map plot that has a wide range (0 - 5000) across different data sets. I need to have the colorbar to first be discrete, and show the full range even though in current dataset the max value may not be 5000, it might be 40. I have been following these three links

https://community.plotly.com/t/equal-size-buckets-on-discrete-color-scale-regardless-of-range/59184

https://stackoverflow.com/questions/71104827/plotly-express-choropleth-map-custom-color-continuous-scale

https://stackoverflow.com/questions/73603595/discrete-color-scale-for-plotly-graph-object

And was able to get the discrete colorbar. But my problem now is because of the such wide range of values, I need to somehow create the colorbar that has unequal bin size. So the colorbar might be something like

[‘0’, ‘0-10’, ‘10-20’, ‘20-50’, ‘50-300’, ‘300-1000’]

But when I specify range_color to be [0, 4000], it automatically creates equal sized buckets and all of my plots are shown as the same color when the overall values in the current dataset is small. So is there a way to specify “if the value is within this range, plot this color?” Thanks in advance.

Hi @sry89 welcome to the forums.

What I came up with is the following: bin values into “color clusters” and use these “color clusters” afterwards to assign a color via the chosen colorscale. Maybe it’s not the most elegant way to do it, but this might work for you.

import plotly.graph_objects as go
import plotly.express as px
import numpy as np

# define discrete colorscale
colorscale = px.colors.qualitative.Dark2

# custom colorscale
#colorscale = ['red', 'green', 'pink', 'blue', 'black']

# set ranges
ranges = [
    [0, 10], 
    [11, 20], 
    [21, 50], 
    [51, 300], 
    [301, 1000]
]

# create dummy data
x = np.random.randint(0,50,500)
y = np.random.randint(0,999,500)

# bin values into color clusters
def bin_colors(value):
    for color, r in enumerate(ranges):
        if r[0] <= value <= r[1]:
            return color

color_cluster = list(map(bin_colors, y))

# create figure
fig = go.Figure()
fig.add_scatter(
    x=x, 
    y=y, 
    mode='markers', 
    marker={
        'color': color_cluster, 
        'colorscale': colorscale
    }
)
fig.update_yaxes(type="log")

Which produces: