Hello! I'm a huge fan of plotly and especially plotly.express, but there's something that's bothers me a lot...
Problem
There's no way to make a template use different color sequences for different trace types in plotly express. Currently it always uses template.layout.colorway (unless explicitly overridden) and ignores per-trace defaults in template.data.<trace_type>.
Example
I'll use histogram and scatter here as an example but it applies very generally.
Let's say I want to use colors ["orange", "purple", "grey"] for a histogram. These are different from the default qualitative palette template.layout.colorway. Plotly enables you to give trace-specific colors like the below but it doesn't work: Plotly express ignores template.data.histogram and uses the same template.layout.colorway palette for both plots.
import plotly.express as px
import plotly.io as pio
import plotly.graph_objects as go
histogram_colors = ["orange", "purple", "grey"]
# Set histogram-specific colors in the template
histogram_template = go.layout.Template(
data={"histogram": [{"marker": {"color": histogram_colors}}]}
)
template = pio.templates.merge_templates("plotly", histogram_template)
df = px.data.iris()
# Expectation: scatter uses global layout.colorway; histogram uses ["orange","purple","grey"]
# Actual behaviour: both use global layout.colorway
fig1 = px.scatter(df, x="sepal_length", y="petal_length", color="species", template=template)
fig2 = px.histogram(df, color="species", template=template)
Current workarounds
- supply
color_discrete_sequence or color_discrete_map to each px call
- use multiple templates with different
layout.colorway and apply a different template to each chart
Why this matters
In reality I don't actually want to completely change colors between histogram and scatter. Actually what I'd like to do is apply the same palette but desaturated to the histogram. Seaborn supports this e.g. barplot(saturation=0.75).
I would like to be able to achieve this with a single template and without manually supplying arguments on per-figure basis.
Proposed solution
Extend plotly express's discrete color resolution to look at trace-specific colors in preference to template.layout.colorway. A single Plotly template already has space to supply a different color palette on each trace by using template.data, and Plotly express does look in template.data but only for a very limited number of things, e.g. it looks at template.data.scatter for line_dash_sequence. But color_discrete_sequence is always taken from template.layout.colorway rather than looking at template.data.
Instead, plotly could take color_discrete_sequence from the relevant template.data trace and then, if that's not defined, fall back on the current mechanism to default to template.layout.colorway.
Alternative solutions
- a new
saturation argument in plotly schema, like there's already opacity. This wouldn't allow arbitrary changes between different trace types but just to desaturate
- a new
saturation argument in plotly.express that would automatically apply the color transformation, like in seaborn. No need to modify the plotly figure schema
- ability to define different color sequences for different trace types in plotly express.
plotly.express.defaults currently defines a single color_discrete_sequence, but there could be a new color_discrete_sequence_by_trace = {"histogram": ..., ...} or similar
Hello! I'm a huge fan of plotly and especially plotly.express, but there's something that's bothers me a lot...
Problem
There's no way to make a template use different color sequences for different trace types in plotly express. Currently it always uses
template.layout.colorway(unless explicitly overridden) and ignores per-trace defaults intemplate.data.<trace_type>.Example
I'll use histogram and scatter here as an example but it applies very generally.
Let's say I want to use colors
["orange", "purple", "grey"]for a histogram. These are different from the default qualitative palettetemplate.layout.colorway. Plotly enables you to give trace-specific colors like the below but it doesn't work: Plotly express ignorestemplate.data.histogramand uses the sametemplate.layout.colorwaypalette for both plots.Current workarounds
color_discrete_sequenceorcolor_discrete_mapto eachpxcalllayout.colorwayand apply a differenttemplateto each chartWhy this matters
In reality I don't actually want to completely change colors between histogram and scatter. Actually what I'd like to do is apply the same palette but desaturated to the histogram. Seaborn supports this e.g.
barplot(saturation=0.75).I would like to be able to achieve this with a single template and without manually supplying arguments on per-figure basis.
Proposed solution
Extend plotly express's discrete color resolution to look at trace-specific colors in preference to
template.layout.colorway. A single Plotly template already has space to supply a different color palette on each trace by usingtemplate.data, and Plotly express does look intemplate.databut only for a very limited number of things, e.g. it looks attemplate.data.scatterforline_dash_sequence. Butcolor_discrete_sequenceis always taken fromtemplate.layout.colorwayrather than looking attemplate.data.Instead, plotly could take
color_discrete_sequencefrom the relevanttemplate.datatrace and then, if that's not defined, fall back on the current mechanism to default totemplate.layout.colorway.Alternative solutions
saturationargument in plotly schema, like there's alreadyopacity. This wouldn't allow arbitrary changes between different trace types but just to desaturatesaturationargument in plotly.express that would automatically apply the color transformation, like in seaborn. No need to modify the plotly figure schemaplotly.express.defaultscurrently defines a singlecolor_discrete_sequence, but there could be a newcolor_discrete_sequence_by_trace = {"histogram": ..., ...}or similar