From 2a42707b083a19b8f3e6c5cfc12e957c3552bbde Mon Sep 17 00:00:00 2001 From: robertoffmoura Date: Sun, 15 Jun 2025 14:40:37 +0100 Subject: [PATCH 1/2] Fix issue when converting matplotlib lines+markers legend to plotly --- plotly/matplotlylib/renderer.py | 8 +++++++- plotly/matplotlylib/tests/__init__.py | 4 ++++ plotly/matplotlylib/tests/test_renderer.py | 18 ++++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 plotly/matplotlylib/tests/__init__.py create mode 100644 plotly/matplotlylib/tests/test_renderer.py diff --git a/plotly/matplotlylib/renderer.py b/plotly/matplotlylib/renderer.py index c95de522477..deb7c1a1055 100644 --- a/plotly/matplotlylib/renderer.py +++ b/plotly/matplotlylib/renderer.py @@ -370,6 +370,12 @@ def draw_legend_shapes(self, mode, shape, **props): x1 = props["data"][1][0] y1 = props["data"][1][1] + lines_shape = shape.copy() + ignored_props = ["symbol", "size"] + for prop in ignored_props: + if prop in lines_shape: + lines_shape.pop(prop) + legend_shape = go.layout.Shape( type=mode, xref="paper", @@ -378,7 +384,7 @@ def draw_legend_shapes(self, mode, shape, **props): y0=y + 0.02, x1=x1, y1=y1 + 0.02, - **shape, + **lines_shape, ) else: self.msg += "not sure how to handle this element\n" diff --git a/plotly/matplotlylib/tests/__init__.py b/plotly/matplotlylib/tests/__init__.py new file mode 100644 index 00000000000..c29e9896d61 --- /dev/null +++ b/plotly/matplotlylib/tests/__init__.py @@ -0,0 +1,4 @@ +import matplotlib + +matplotlib.use("Agg") +import matplotlib.pyplot as plt diff --git a/plotly/matplotlylib/tests/test_renderer.py b/plotly/matplotlylib/tests/test_renderer.py new file mode 100644 index 00000000000..2c82f07de51 --- /dev/null +++ b/plotly/matplotlylib/tests/test_renderer.py @@ -0,0 +1,18 @@ +import plotly.tools as tls + +from . import plt + +def test_lines_markers_legend_plot(): + x = [0, 1] + y = [0, 1] + label = "label" + plt.figure() + plt.plot(x, y, "o-", label=label) + plt.legend() + + plotly_fig = tls.mpl_to_plotly(plt.gcf()) + + assert plotly_fig.data[0].mode == "lines+markers" + assert plotly_fig.data[0].x == tuple(x) + assert plotly_fig.data[0].y == tuple(y) + assert plotly_fig.data[0].name == "label" From da3723940a96dc8928b97fc4e0327a7ec45fdccc Mon Sep 17 00:00:00 2001 From: robertoffmoura Date: Tue, 12 Aug 2025 10:00:46 +0100 Subject: [PATCH 2/2] Run ruff format --- plotly/matplotlylib/renderer.py | 4 ++-- plotly/matplotlylib/tests/test_renderer.py | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/plotly/matplotlylib/renderer.py b/plotly/matplotlylib/renderer.py index deb7c1a1055..cdda2aaa94f 100644 --- a/plotly/matplotlylib/renderer.py +++ b/plotly/matplotlylib/renderer.py @@ -299,7 +299,7 @@ def draw_bar(self, coll): ) # TODO ditto if len(bar["x"]) > 1: self.msg += " Heck yeah, I drew that bar chart\n" - (self.plotly_fig.add_trace(bar),) + self.plotly_fig.add_trace(bar) if bar_gap is not None: self.plotly_fig["layout"]["bargap"] = bar_gap else: @@ -503,7 +503,7 @@ def draw_marked_line(self, **props): marked_line["x"] = mpltools.mpl_dates_to_datestrings( marked_line["x"], formatter ) - (self.plotly_fig.add_trace(marked_line),) + self.plotly_fig.add_trace(marked_line) self.msg += " Heck yeah, I drew that line\n" elif props["coordinates"] == "axes": # dealing with legend graphical elements diff --git a/plotly/matplotlylib/tests/test_renderer.py b/plotly/matplotlylib/tests/test_renderer.py index 2c82f07de51..019e96da390 100644 --- a/plotly/matplotlylib/tests/test_renderer.py +++ b/plotly/matplotlylib/tests/test_renderer.py @@ -2,6 +2,7 @@ from . import plt + def test_lines_markers_legend_plot(): x = [0, 1] y = [0, 1]