I wanted to diaplay my customized colorbar as discrete fashion but plotly just interpolates. How do I simulate the same result in matplotlib in plotly. I tried using fake trace and only show colorscale but have no success.
Below is the colorscale I am aiming for, matplotlib handles this super gracefully
Here’s’ the code I used to generate the colorbar. No matter what I do, I can’t stop plotly from interpolating.
import plotly.graph_objects as go
import plotly.io as pio
import plotly.express as px
import plotly.colors as pc
import pandas as pd
import numpy as np
fig = go.Figure()
# construct a colorscale
reds = px.colors.sequential.Reds
blues = pc.sequential.Blues
reds_interp = pc.sample_colorscale(reds, [i/4 for i in range(5)])
blues_interp = pc.sample_colorscale(blues, [i/5 for i in range(6)])
ccmap=[]
ccmap = blues_interp[::-1] + reds_interp
customized_cscale = [[v,c] for v,c in zip(np.linspace(0,1,11),ccmap)]
# create duplicate color stop for each color range
color_bar_discrete = [sub_l.copy() for sub_l in customized_cscale for item in (sub_l,sub_l)]
ticks = np.linspace(0,1,12,dtype=np.float64)
fake_trace = go.Scatter(x=[None], y=[None],
showlegend=False,mode = 'markers',
marker = dict(
# showscale = True,
color = ccmap ,
colorscale = color_bar_discrete[1:-1],
cmin=0,
cmax=1,
colorbar=dict(
tickfont=dict(size=10),
thickness=15,
orientation='h',
x=0.65,
y=-0.05,
xanchor="center",
yanchor="top",
len=0.7,
tickformat=".2f",
tickvals=ticks,
ticktext=[f"{t:.2f}" for t in ticks],
ticks="outside",
ticklen=2
)
),
)
fig.add_trace(fake_trace)
fig.show()
I wanted a non-interpolated version. In matplotlib, all it takes is just a fig.colorbar() call. But since plotly ties colorbar to trace so it adds work and confusion.
In my case, my colorbar is comprised of two built-in plotly color scales. One is from
plotly.colors.sequential.Reds
Another is from
plotly.colors.sequential.Blues
Because my bar chart updates color dynamically so I can’t let plotly derive a default colorbar from my data input. I have to use a seprerate colorbar to demonstrate the scale of colors on my bars.
I used a “fake” or someone call it “dummy trace” to simulate this colorbar. To escape plotly’s automatic color interpolation(like I demonstrated in my original post), I have to create artificial color stops in colorbar list.
The problem or my mistake tripped me here is — in my original post, the colorbar list looks like this:
I noticed that the color stops were misaligned with their numeric positions. For example, between np.float64(0.0) and np.float64(0.1), the two RGB strings should be identical so that when plotly interpolates them, they got collapsed into a single color value rather than displaying an unwanted gradient visual effect from interpolation.
In other words, I need to “nudge “ the left numeric values upward by one position so that adjacent but different numeric postions get the same RGB color value. It looks like this:
I originally used Matplotlib to handle the colorbar so I didn’t encounter this issue before. The transition to Plotly Dash took me a little by surprise.
I hope it helps for people who run into the same problem when using Plotly.
This is a personal project simulating an interactive annotation chart based on a scientific paper that discusses how to improve the interpretation of overlapping confidence intervals in probabilistic tasks.
The github repo link is here. I host the Dash app on Render too.
Welcome to try it and contribute.
Special thanks to @AIMPED for digging up the old links. I found some relevant ones but yours make me understand this issue much clearer.