-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Brightness of 'plotly' template colorscale #1274
Comments
Hi @empet, Thanks for caring about the new plotly themes 🙂 And apologies to all of our color conscious users for not laying out the technical background for this choice of colormap. I'll try to remedy that now. This colormap is based on CET-L7 (aka linear_bmw_5-95_c86_n256) from Peter Kovesi's work on perceptually uniform colormaps (https://peterkovesi.com/projects/colourmaps/index.html). As you noticed in your analysis, this family of colormaps is not uniform in components of the hsl or hsv colorspaces (and also as your analysis shows, neither is viridis). Instead, they are uniform in the Lightness (L*) component of the CIELAB colorspace (https://en.wikipedia.org/wiki/CIELAB_color_space). From the wikipedia link
I say it's "based on" this colormap because we've clipped to upper and lower ends slightly so that the extremes aren't so close to black and white. This doesn't alter the perceptually uniform characteristics, but it improves the contrast of the extremes against both a white and black background, at the cost of a little bit of dynamic range. Here is a comparison of the plotly and viridis colormaps in CIELAB lightness space. # Imports
import plotly
import plotly.io as pio
import plotly.graph_objs as go
from colorspacious import cspace_convert
import numpy as np
# Get colormaps
plotly_cmap = pio.templates['plotly']['data']['bar'][0]['marker']['colorscale']
viridis_cmap = plotly.colors.PLOTLY_SCALES['Viridis']
# Build figure with subplots
fig = go.FigureWidget(plotly.tools.make_subplots(rows=1, cols=2, shared_yaxes=True, subplot_titles=['Plotly', 'Viridis']))
# Configure layout
fig.layout.yaxis.title = 'CIELAB lightness'
fig.layout.xaxis.title = 'Scale value'
fig.layout.xaxis2.title = 'Scale value'
fig.layout.showlegend = False
# Plot colormaps in CIELAB lightness space
for col, (cmap_name, cmap) in enumerate(zip(['plotly', 'viridis'],
[plotly_cmap, viridis_cmap])):
scale_vals, colors_hex = list(zip(*cmap))
colors_rgb = np.array([tuple(int(h[i:i+2], 16)/255.0 for i in (1, 3, 5)) for h in colors_hex])
colors_cielab = cspace_convert(colors_rgb, 'sRGB1', 'CIELab')
lightness_cielab = colors_cielab[:, 0]
fig.add_scatter(x=scale_vals,
y=lightness_cielab,
mode='markers+lines',
marker={'color': colors_hex, 'size': 20},
line={'color': 'black', 'width': 1},
name=cmap_name,
row=1,
col=col+1)
# Display figure
fig So you can see that they both scale linearly in this lightness space, and you can see that viridis has a bit more dynamic range due to the clipping discussed above. The actual calculation of the plotly.py/templategen/definitions.py Lines 216 to 223 in a8ae062
In terms of why we chose this colorscale rather than any of the other perceptually uniform options, that was purely a matter of taste. To my eye, it looks really nice within the context of the plotly brand colors that this theme is based on (https://brand.plot.ly/). The biggest limitation of this family of colorscales is that, as far as I understand, they don't take colorblindness into account. So I would still like to develop a new built-in theme that is more robust to various forms of color blindness. Volunteers welcome! I hope this helps shed some light on the rationale. Thanks again for taking the time to share your feedback. |
Thanks @jonmmease for the details. I referred to the brightness that is exaggerated in comparison with all known and used colormaps. That's why I converted each color to HSV. |
Hi all, just wanted to post an update that we are planning to use the I'm proposing that we change the default sequential scale from the This colorscale was developed alongside the more well know I like this scale because the bottom end has a very similar dark blue to purple transition to |
I plotted comparatively the Mt Bruno, with
and comparing with Magma and Inferno colorscales, too, https://plot.ly/~empet/15162 I decided to vote for Plasma. Update: I've just realized that the cover photo of |
Great, thanks for weighing in @empet! |
More arguments that the To get the first image of a blackhole an EHT team worked on searching the best color space and parameters that define a good colormap. The I cloned its repository https://github.com/liamedeiros/ehtplot, and calling a few functions I plotted comparatively the lines representing the basic parameters in the CAM02-UCS color space, that influence the quality of a colormap, for the following colormaps and their reversed versions: The colorful line represents the lightness J', the dashed line is chroma C', and the dotted one is the hue, h'. A PUC should have a linear lightness with respect to data values. We can see that the lightness of the In order to illustrate how non-uniform colormaps can lead to faulty feature extraction, ehtplot provides a function that defines the so called pyramid, i.e. a heatmap plotted with the inspected colormaps. In the case of a PUC, the viewer's eye should pick out only a cross X connecting the heatmap oposite corners, and obviously the color gradient. The pyramids associated to the above cmaps and their reversed versions are illustrated in this image: Following the comments in the ehtplot notebook, COLORMAPS.ipynb, for These squares are caused by the nonlinearity of lightness, J'. In The pyramids for other PUCs: exhibit similar patterns like To correct the lightness non-linearity (or non-uniformality) ehtplot implements an algorithm for colormap uniformization as well as for the so called lightness "symmetrization" (details in COLORMAPS.ipynb) |
I tested 'plotly' template, with different traces and concluded that the colorscale used in this template is too bright.
In this notebook https://plot.ly/~empet/15032 I compared its brightness, respectively lightness function, with the same functions associated to jet colormap (a bad colormap that was replaced as the default colormap in matplotlib, matlab; seaborn displays an error when a user chooses this colormap), as well as to four perceptual uniform colorscales (viridis, magma, cmocean ice and deep). The final conclusion is that plotly template colorscale is much more like the jet colormap than the perceptual uniform ones.
How was derived/defined this colorscale? Why it has 13 entries, instead of 11 (with 11 colors, the plotly scale is [0, 0.1, 0.2, ..., 1.]? With 13 colors the scale contains floats with many decimals.
The text was updated successfully, but these errors were encountered: