From 965b3bdc18a6e2fa10fbbded0751a83d2fce8812 Mon Sep 17 00:00:00 2001 From: Antony Milne Date: Wed, 26 Nov 2025 17:01:55 +0000 Subject: [PATCH 01/12] Add trace-specific color sequence support from template.data - Check template.data. for marker.color or line.color before falling back to template.layout.colorway - Handle timeline special case (maps to bar trace type) - Use marker colors first, fall back to line colors if no markers found - Fixes issue #5416 --- plotly/express/_core.py | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/plotly/express/_core.py b/plotly/express/_core.py index d2dbc84c0e7..85c406f7c88 100644 --- a/plotly/express/_core.py +++ b/plotly/express/_core.py @@ -1003,7 +1003,7 @@ def one_group(x): return "" -def apply_default_cascade(args): +def apply_default_cascade(args, constructor=None): # first we apply px.defaults to unspecified args for param in defaults.__slots__: @@ -1038,6 +1038,25 @@ def apply_default_cascade(args): args["color_continuous_scale"] = sequential.Viridis if "color_discrete_sequence" in args: + if args["color_discrete_sequence"] is None and constructor is not None: + if constructor == "timeline": + trace_type = "bar" + else: + trace_type = constructor().type + if trace_data_list := getattr(args["template"].data, trace_type, None): + collected_colors = [ + trace_data.marker.color + for trace_data in trace_data_list + if hasattr(trace_data, "marker") + ] + if not collected_colors: + collected_colors = [ + trace_data.line.color + for trace_data in trace_data_list + if hasattr(trace_data, "line") + ] + if collected_colors: + args["color_discrete_sequence"] = collected_colors if args["color_discrete_sequence"] is None and args["template"].layout.colorway: args["color_discrete_sequence"] = args["template"].layout.colorway if args["color_discrete_sequence"] is None: @@ -2486,7 +2505,7 @@ def get_groups_and_orders(args, grouper): def make_figure(args, constructor, trace_patch=None, layout_patch=None): trace_patch = trace_patch or {} layout_patch = layout_patch or {} - apply_default_cascade(args) + apply_default_cascade(args, constructor=constructor) args = build_dataframe(args, constructor) if constructor in [go.Treemap, go.Sunburst, go.Icicle] and args["path"] is not None: From 83faec8d91591c768799dce0b9083b74fff88369 Mon Sep 17 00:00:00 2001 From: Antony Milne Date: Wed, 26 Nov 2025 17:30:47 +0000 Subject: [PATCH 02/12] Support trace-specific color sequences in Plotly Express via templates - Modify apply_default_cascade to check template.data. for marker.color or line.color - Fallback to template.layout.colorway if trace-specific colors not found - Add comprehensive tests for trace-specific color sequences - Handle timeline special case (maps to bar trace type) - Follow existing patterns for symbol_sequence and line_dash_sequence Fixes #5416 --- plotly/express/_core.py | 18 ++++-- tests/test_optional/test_px/test_px.py | 81 ++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 5 deletions(-) diff --git a/plotly/express/_core.py b/plotly/express/_core.py index 85c406f7c88..fb6f57d7d9e 100644 --- a/plotly/express/_core.py +++ b/plotly/express/_core.py @@ -1037,6 +1037,9 @@ def apply_default_cascade(args, constructor=None): if args["color_continuous_scale"] is None: args["color_continuous_scale"] = sequential.Viridis + # if color_discrete_sequence not set explicitly or in px.defaults, + # see if we can defer to template. Try trace-specific colors first, + # then layout.colorway, then set reasonable defaults if "color_discrete_sequence" in args: if args["color_discrete_sequence"] is None and constructor is not None: if constructor == "timeline": @@ -1044,21 +1047,26 @@ def apply_default_cascade(args, constructor=None): else: trace_type = constructor().type if trace_data_list := getattr(args["template"].data, trace_type, None): - collected_colors = [ + # try marker.color first + args["color_discrete_sequence"] = [ trace_data.marker.color for trace_data in trace_data_list if hasattr(trace_data, "marker") ] - if not collected_colors: - collected_colors = [ + # fallback to line.color if marker.color not available + if not args["color_discrete_sequence"] or not any(args["color_discrete_sequence"]): + args["color_discrete_sequence"] = [ trace_data.line.color for trace_data in trace_data_list if hasattr(trace_data, "line") ] - if collected_colors: - args["color_discrete_sequence"] = collected_colors + # if no trace-specific colors found, reset to None to allow fallback + if not args["color_discrete_sequence"] or not any(args["color_discrete_sequence"]): + args["color_discrete_sequence"] = None + # fallback to layout.colorway if trace-specific colors not available if args["color_discrete_sequence"] is None and args["template"].layout.colorway: args["color_discrete_sequence"] = args["template"].layout.colorway + # final fallback to default qualitative palette if args["color_discrete_sequence"] is None: args["color_discrete_sequence"] = qualitative.D3 diff --git a/tests/test_optional/test_px/test_px.py b/tests/test_optional/test_px/test_px.py index 3a8ddabcd0a..7e7612dc0e2 100644 --- a/tests/test_optional/test_px/test_px.py +++ b/tests/test_optional/test_px/test_px.py @@ -226,6 +226,87 @@ def test_px_templates(backend): pio.templates.default = "plotly" +def test_px_templates_trace_specific_colors(backend): + import plotly.graph_objects as go + + tips = px.data.tips(return_type=backend) + + # read trace-specific colors from template.data.histogram + histogram_template = go.layout.Template() + histogram_template.data.histogram = [ + go.Histogram(marker=dict(color="orange")), + go.Histogram(marker=dict(color="purple")), + ] + fig = px.histogram(tips, x="total_bill", color="sex", template=histogram_template) + assert fig.data[0].marker.color == "orange" + assert fig.data[1].marker.color == "purple" + + # scatter uses template.data.scatter colors, not histogram colors + scatter_template = go.layout.Template() + scatter_template.data.scatter = [ + go.Scatter(marker=dict(color="cyan")), + go.Scatter(marker=dict(color="magenta")), + ] + scatter_template.data.histogram = [ + go.Histogram(marker=dict(color="orange")), + ] + fig = px.scatter(tips, x="total_bill", y="tip", color="sex", template=scatter_template) + assert fig.data[0].marker.color == "cyan" + assert fig.data[1].marker.color == "magenta" + + # histogram still uses histogram colors even when scatter colors exist + fig = px.histogram(tips, x="total_bill", color="sex", template=scatter_template) + assert fig.data[0].marker.color == "orange" + + # fallback to layout.colorway when trace-specific colors don't exist + fig = px.histogram( + tips, x="total_bill", color="sex", template=dict(layout_colorway=["yellow", "green"]) + ) + assert fig.data[0].marker.color == "yellow" + assert fig.data[1].marker.color == "green" + + # timeline special case (maps to bar) + timeline_template = go.layout.Template() + timeline_template.data.bar = [ + go.Bar(marker=dict(color="red")), + go.Bar(marker=dict(color="blue")), + ] + timeline_data = { + "Task": ["Job A", "Job B"], + "Start": ["2009-01-01", "2009-03-05"], + "Finish": ["2009-02-28", "2009-04-15"], + "Resource": ["Alex", "Max"], + } + # Use same backend as tips for consistency + df_timeline = px.data.tips(return_type=backend) + df_timeline = nw.from_native(df_timeline).with_columns( + nw.lit("Job A").alias("Task"), + nw.lit("2009-01-01").alias("Start"), + nw.lit("2009-02-28").alias("Finish"), + nw.lit("Alex").alias("Resource"), + ).head(1).to_native() + # Add second row + df_timeline2 = nw.from_native(df_timeline).with_columns( + nw.lit("Job B").alias("Task"), + nw.lit("2009-03-05").alias("Start"), + nw.lit("2009-04-15").alias("Finish"), + nw.lit("Max").alias("Resource"), + ).head(1).to_native() + # Combine - actually, this is getting too complex. Let me just use a simpler approach + import pandas as pd + df_timeline = pd.DataFrame(timeline_data) + fig = px.timeline( + df_timeline, + x_start="Start", + x_end="Finish", + y="Task", + color="Resource", + template=timeline_template, + ) + assert fig.data[0].marker.color == "red" + assert fig.data[1].marker.color == "blue" + + def test_px_defaults(): px.defaults.labels = dict(x="hey x") px.defaults.category_orders = dict(color=["b", "a"]) From 7bdec7ffa17c93ea7992f8ffcaab973615c4929b Mon Sep 17 00:00:00 2001 From: Antony Milne Date: Wed, 26 Nov 2025 21:21:58 +0000 Subject: [PATCH 03/12] Add trace-specific color sequences in Plotly Express via templates - Modify apply_default_cascade to read colors from template.data. - Prioritize trace-specific colors over layout.colorway - Add special case for timeline constructor (maps to bar trace type) - Add comprehensive tests for trace-specific color sequences - Test trace type isolation, fallback behavior, and timeline special case --- plotly/express/_core.py | 8 --- tests/test_optional/test_px/test_px.py | 85 ++++++++------------------ 2 files changed, 25 insertions(+), 68 deletions(-) diff --git a/plotly/express/_core.py b/plotly/express/_core.py index fb6f57d7d9e..55a4ca3da18 100644 --- a/plotly/express/_core.py +++ b/plotly/express/_core.py @@ -1047,19 +1047,11 @@ def apply_default_cascade(args, constructor=None): else: trace_type = constructor().type if trace_data_list := getattr(args["template"].data, trace_type, None): - # try marker.color first args["color_discrete_sequence"] = [ trace_data.marker.color for trace_data in trace_data_list if hasattr(trace_data, "marker") ] - # fallback to line.color if marker.color not available - if not args["color_discrete_sequence"] or not any(args["color_discrete_sequence"]): - args["color_discrete_sequence"] = [ - trace_data.line.color - for trace_data in trace_data_list - if hasattr(trace_data, "line") - ] # if no trace-specific colors found, reset to None to allow fallback if not args["color_discrete_sequence"] or not any(args["color_discrete_sequence"]): args["color_discrete_sequence"] = None diff --git a/tests/test_optional/test_px/test_px.py b/tests/test_optional/test_px/test_px.py index 7e7612dc0e2..7b7218f07c1 100644 --- a/tests/test_optional/test_px/test_px.py +++ b/tests/test_optional/test_px/test_px.py @@ -227,81 +227,46 @@ def test_px_templates(backend): def test_px_templates_trace_specific_colors(backend): - import plotly.graph_objects as go + import pandas as pd tips = px.data.tips(return_type=backend) - # read trace-specific colors from template.data.histogram - histogram_template = go.layout.Template() - histogram_template.data.histogram = [ - go.Histogram(marker=dict(color="orange")), - go.Histogram(marker=dict(color="purple")), - ] - fig = px.histogram(tips, x="total_bill", color="sex", template=histogram_template) + # trace-specific colors: each trace type uses its own template colors + template = { + "data_histogram": [ + {"marker": {"color": "orange"}}, + {"marker": {"color": "purple"}}, + ], + "data_bar": [ + {"marker": {"color": "red"}}, + {"marker": {"color": "blue"}}, + ], + "layout_colorway": ["yellow", "green"], + } + # histogram uses histogram colors + fig = px.histogram(tips, x="total_bill", color="sex", template=template) assert fig.data[0].marker.color == "orange" assert fig.data[1].marker.color == "purple" - - # scatter uses template.data.scatter colors, not histogram colors - scatter_template = go.layout.Template() - scatter_template.data.scatter = [ - go.Scatter(marker=dict(color="cyan")), - go.Scatter(marker=dict(color="magenta")), - ] - scatter_template.data.histogram = [ - go.Histogram(marker=dict(color="orange")), - ] - fig = px.scatter(tips, x="total_bill", y="tip", color="sex", template=scatter_template) - assert fig.data[0].marker.color == "cyan" - assert fig.data[1].marker.color == "magenta" - - # histogram still uses histogram colors even when scatter colors exist - fig = px.histogram(tips, x="total_bill", color="sex", template=scatter_template) - assert fig.data[0].marker.color == "orange" - # fallback to layout.colorway when trace-specific colors don't exist - fig = px.histogram( - tips, x="total_bill", color="sex", template=dict(layout_colorway=["yellow", "green"]) - ) + fig = px.box(tips, x="day", y="total_bill", color="sex", template=template) assert fig.data[0].marker.color == "yellow" assert fig.data[1].marker.color == "green" - # timeline special case (maps to bar) - timeline_template = go.layout.Template() - timeline_template.data.bar = [ - go.Bar(marker=dict(color="red")), - go.Bar(marker=dict(color="blue")), - ] - timeline_data = { - "Task": ["Job A", "Job B"], - "Start": ["2009-01-01", "2009-03-05"], - "Finish": ["2009-02-28", "2009-04-15"], - "Resource": ["Alex", "Max"], - } - # Use same backend as tips for consistency - df_timeline = px.data.tips(return_type=backend) - df_timeline = nw.from_native(df_timeline).with_columns( - nw.lit("Job A").alias("Task"), - nw.lit("2009-01-01").alias("Start"), - nw.lit("2009-02-28").alias("Finish"), - nw.lit("Alex").alias("Resource"), - ).head(1).to_native() - # Add second row - df_timeline2 = nw.from_native(df_timeline).with_columns( - nw.lit("Job B").alias("Task"), - nw.lit("2009-03-05").alias("Start"), - nw.lit("2009-04-15").alias("Finish"), - nw.lit("Max").alias("Resource"), - ).head(1).to_native() - # Combine - actually, this is getting too complex. Let me just use a simpler approach - import pandas as pd - df_timeline = pd.DataFrame(timeline_data) + df_timeline = pd.DataFrame( + { + "Task": ["Job A", "Job B"], + "Start": ["2009-01-01", "2009-03-05"], + "Finish": ["2009-02-28", "2009-04-15"], + "Resource": ["Alex", "Max"], + } + ) fig = px.timeline( df_timeline, x_start="Start", x_end="Finish", y="Task", color="Resource", - template=timeline_template, + template=template, ) assert fig.data[0].marker.color == "red" assert fig.data[1].marker.color == "blue" From befea7dab369f3ba62d6d4602b442b8ab805ccdd Mon Sep 17 00:00:00 2001 From: Antony Milne Date: Thu, 27 Nov 2025 11:39:35 +0000 Subject: [PATCH 04/12] Minor --- plotly/express/_core.py | 1 - 1 file changed, 1 deletion(-) diff --git a/plotly/express/_core.py b/plotly/express/_core.py index 55a4ca3da18..5c8789a3728 100644 --- a/plotly/express/_core.py +++ b/plotly/express/_core.py @@ -1052,7 +1052,6 @@ def apply_default_cascade(args, constructor=None): for trace_data in trace_data_list if hasattr(trace_data, "marker") ] - # if no trace-specific colors found, reset to None to allow fallback if not args["color_discrete_sequence"] or not any(args["color_discrete_sequence"]): args["color_discrete_sequence"] = None # fallback to layout.colorway if trace-specific colors not available From d578ab434615ba6007f2b61c74a11f4920dd77d1 Mon Sep 17 00:00:00 2001 From: Antony Milne Date: Thu, 27 Nov 2025 15:57:59 +0000 Subject: [PATCH 05/12] Format code with ruff --- plotly/express/_core.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plotly/express/_core.py b/plotly/express/_core.py index 5c8789a3728..04449a186e3 100644 --- a/plotly/express/_core.py +++ b/plotly/express/_core.py @@ -1051,8 +1051,11 @@ def apply_default_cascade(args, constructor=None): trace_data.marker.color for trace_data in trace_data_list if hasattr(trace_data, "marker") + and hasattr(trace_data.marker, "color") ] - if not args["color_discrete_sequence"] or not any(args["color_discrete_sequence"]): + if not args["color_discrete_sequence"] or not any( + args["color_discrete_sequence"] + ): args["color_discrete_sequence"] = None # fallback to layout.colorway if trace-specific colors not available if args["color_discrete_sequence"] is None and args["template"].layout.colorway: From a2dc4901108af86a684d1c099c9837a9ef492536 Mon Sep 17 00:00:00 2001 From: Antony Milne Date: Mon, 1 Dec 2025 11:49:43 +0000 Subject: [PATCH 06/12] Add CHANGELOG entry for trace-specific color sequences fix --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index afd0a77ebc8..79661d636eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## Unreleased +### Fixed +- Fix issue where Plotly Express ignored trace-specific color sequences defined in templates via `template.data.`. Plotly Express now respects trace-specific marker colors before falling back to `template.layout.colorway` [[#5437](https://github.com/plotly/plotly.py/pull/5437)]. Fixes [#5416](https://github.com/plotly/plotly.py/issues/5416). + ### Updated - Speed up `validate_gantt` function [[#5386](https://github.com/plotly/plotly.py/pull/5386)], with thanks to @misrasaurabh1 for the contribution! From 74543f301be86ab121a8069a506ced9aba2a2d53 Mon Sep 17 00:00:00 2001 From: Antony Milne Date: Mon, 1 Dec 2025 13:27:23 +0000 Subject: [PATCH 07/12] Update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79661d636eb..d408cc2ad56 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## Unreleased ### Fixed -- Fix issue where Plotly Express ignored trace-specific color sequences defined in templates via `template.data.`. Plotly Express now respects trace-specific marker colors before falling back to `template.layout.colorway` [[#5437](https://github.com/plotly/plotly.py/pull/5437)]. Fixes [#5416](https://github.com/plotly/plotly.py/issues/5416). +- Fix issue where Plotly Express ignored trace-specific color sequences defined in templates via `template.data.` [[#5437](https://github.com/plotly/plotly.py/pull/5437)] ### Updated - Speed up `validate_gantt` function [[#5386](https://github.com/plotly/plotly.py/pull/5386)], with thanks to @misrasaurabh1 for the contribution! From 675c668fcfefab9b4b3b1a0ed81a36ac22e807d4 Mon Sep 17 00:00:00 2001 From: Antony Milne Date: Thu, 4 Dec 2025 16:44:34 +0000 Subject: [PATCH 08/12] Refactor trace-specific color handling in apply_default_cascade - Make constructor parameter required (was optional with None default) - Refactor trace-specific color extraction to only assign when colors are found - Improve code clarity by checking for non-empty color list before assignment --- plotly/express/_core.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/plotly/express/_core.py b/plotly/express/_core.py index 04449a186e3..a1f54fc98de 100644 --- a/plotly/express/_core.py +++ b/plotly/express/_core.py @@ -1003,7 +1003,7 @@ def one_group(x): return "" -def apply_default_cascade(args, constructor=None): +def apply_default_cascade(args, constructor): # first we apply px.defaults to unspecified args for param in defaults.__slots__: @@ -1047,12 +1047,16 @@ def apply_default_cascade(args, constructor=None): else: trace_type = constructor().type if trace_data_list := getattr(args["template"].data, trace_type, None): - args["color_discrete_sequence"] = [ + trace_specific_colors = [ trace_data.marker.color for trace_data in trace_data_list if hasattr(trace_data, "marker") and hasattr(trace_data.marker, "color") ] + # If template contains at least one color for this trace type, assign to color_discrete_sequence + if any(trace_specific_colors): + args["color_discrete_sequence"] = trace_specific_colors + if not args["color_discrete_sequence"] or not any( args["color_discrete_sequence"] ): From c24b05c513a8212f10623a50c0107e8b585daaf5 Mon Sep 17 00:00:00 2001 From: Antony Milne Date: Thu, 4 Dec 2025 21:23:17 +0000 Subject: [PATCH 09/12] Remove redundant color_discrete_sequence check in apply_default_cascade - Remove redundant check that was setting color_discrete_sequence to None - The check is unnecessary since we only assign trace_specific_colors when any() is True - Fallback logic to layout.colorway and qualitative.D3 remains intact --- plotly/express/_core.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/plotly/express/_core.py b/plotly/express/_core.py index a1f54fc98de..4564d645eb3 100644 --- a/plotly/express/_core.py +++ b/plotly/express/_core.py @@ -1056,11 +1056,6 @@ def apply_default_cascade(args, constructor): # If template contains at least one color for this trace type, assign to color_discrete_sequence if any(trace_specific_colors): args["color_discrete_sequence"] = trace_specific_colors - - if not args["color_discrete_sequence"] or not any( - args["color_discrete_sequence"] - ): - args["color_discrete_sequence"] = None # fallback to layout.colorway if trace-specific colors not available if args["color_discrete_sequence"] is None and args["template"].layout.colorway: args["color_discrete_sequence"] = args["template"].layout.colorway From 076ff14c0de942f5a0cf9979075592c181d41f7a Mon Sep 17 00:00:00 2001 From: Antony Milne <49395058+antonymilne@users.noreply.github.com> Date: Thu, 4 Dec 2025 21:23:29 +0000 Subject: [PATCH 10/12] Update tests/test_optional/test_px/test_px.py Co-authored-by: Emily KL <4672118+emilykl@users.noreply.github.com> --- tests/test_optional/test_px/test_px.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/tests/test_optional/test_px/test_px.py b/tests/test_optional/test_px/test_px.py index 7b7218f07c1..cbeb74e08e9 100644 --- a/tests/test_optional/test_px/test_px.py +++ b/tests/test_optional/test_px/test_px.py @@ -233,15 +233,19 @@ def test_px_templates_trace_specific_colors(backend): # trace-specific colors: each trace type uses its own template colors template = { - "data_histogram": [ - {"marker": {"color": "orange"}}, - {"marker": {"color": "purple"}}, - ], - "data_bar": [ - {"marker": {"color": "red"}}, - {"marker": {"color": "blue"}}, - ], - "layout_colorway": ["yellow", "green"], + "data": { + "histogram": [ + {"marker": {"color": "orange"}}, + {"marker": {"color": "purple"}}, + ], + "bar": [ + {"marker": {"color": "red"}}, + {"marker": {"color": "blue"}}, + ], + }, + "layout": { + "colorway": ["yellow", "green"], + }, } # histogram uses histogram colors fig = px.histogram(tips, x="total_bill", color="sex", template=template) From a3853d2afc113cea2fda3ab98b435e745823abfd Mon Sep 17 00:00:00 2001 From: Antony Milne Date: Thu, 4 Dec 2025 21:25:03 +0000 Subject: [PATCH 11/12] Ruff --- plotly/express/_core.py | 6 +++--- tests/test_optional/test_px/test_px.py | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/plotly/express/_core.py b/plotly/express/_core.py index 4564d645eb3..9fbf526cdeb 100644 --- a/plotly/express/_core.py +++ b/plotly/express/_core.py @@ -1053,9 +1053,9 @@ def apply_default_cascade(args, constructor): if hasattr(trace_data, "marker") and hasattr(trace_data.marker, "color") ] - # If template contains at least one color for this trace type, assign to color_discrete_sequence - if any(trace_specific_colors): - args["color_discrete_sequence"] = trace_specific_colors + # If template contains at least one color for this trace type, assign to color_discrete_sequence + if any(trace_specific_colors): + args["color_discrete_sequence"] = trace_specific_colors # fallback to layout.colorway if trace-specific colors not available if args["color_discrete_sequence"] is None and args["template"].layout.colorway: args["color_discrete_sequence"] = args["template"].layout.colorway diff --git a/tests/test_optional/test_px/test_px.py b/tests/test_optional/test_px/test_px.py index cbeb74e08e9..6c65925a727 100644 --- a/tests/test_optional/test_px/test_px.py +++ b/tests/test_optional/test_px/test_px.py @@ -1,6 +1,7 @@ from itertools import permutations import warnings +import pandas as pd import plotly.express as px import plotly.io as pio import narwhals.stable.v1 as nw @@ -227,8 +228,6 @@ def test_px_templates(backend): def test_px_templates_trace_specific_colors(backend): - import pandas as pd - tips = px.data.tips(return_type=backend) # trace-specific colors: each trace type uses its own template colors From e8339e036674c3fda3a1009fc5b33a14d248a62b Mon Sep 17 00:00:00 2001 From: Antony Milne Date: Fri, 5 Dec 2025 14:03:01 +0000 Subject: [PATCH 12/12] Fix imshow --- plotly/express/_imshow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plotly/express/_imshow.py b/plotly/express/_imshow.py index ce6ddb84286..7a3dd8a6df9 100644 --- a/plotly/express/_imshow.py +++ b/plotly/express/_imshow.py @@ -233,7 +233,7 @@ def imshow( axes labels and ticks. """ args = locals() - apply_default_cascade(args) + apply_default_cascade(args, constructor=None) labels = labels.copy() nslices_facet = 1 if facet_col is not None: