From e405fe0b34ea2f7e8ff294b1ca6729eeb089e46a Mon Sep 17 00:00:00 2001 From: Roberto Moura Date: Tue, 11 Aug 2026 10:25:15 +0000 Subject: [PATCH] Only show a legend when the matplotlib figure has one --- plotly/matplotlylib/renderer.py | 15 ++++++++++----- plotly/matplotlylib/tests/test_renderer.py | 9 +++++++++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/plotly/matplotlylib/renderer.py b/plotly/matplotlylib/renderer.py index a282c67cec..a015f1248b 100644 --- a/plotly/matplotlylib/renderer.py +++ b/plotly/matplotlylib/renderer.py @@ -100,6 +100,10 @@ def open_figure(self, fig, props): height=int(props["figheight"] * props["dpi"]), autosize=False, hovermode="closest", + # plotly.js auto-names unnamed traces "trace N" and shows them + # in the legend; the legend is only enabled when the mpl figure + # actually has one (see open_legend) + showlegend=False, ) self.mpl_x_bounds, self.mpl_y_bounds = mpltools.get_axes_bounds(fig) margin = go.layout.Margin( @@ -437,13 +441,14 @@ def draw_marked_line(self, **props): ), ) if props["coordinates"] == "data": + label = props["label"] + # matplotlib uses "_nolegend_" and auto-generated "_childN" + # labels for artists that must not appear in a legend + if isinstance(label, str) and label.startswith("_"): + label = None marked_line = go.Scatter( mode=mode, - name=( - str(props["label"]) - if isinstance(props["label"], str) - else props["label"] - ), + name=label, x=[xy_pair[0] for xy_pair in props["data"]], y=[xy_pair[1] for xy_pair in props["data"]], xaxis="x{0}".format(self.axis_ct), diff --git a/plotly/matplotlylib/tests/test_renderer.py b/plotly/matplotlylib/tests/test_renderer.py index f56d830917..4750a4be6b 100644 --- a/plotly/matplotlylib/tests/test_renderer.py +++ b/plotly/matplotlylib/tests/test_renderer.py @@ -199,3 +199,12 @@ def test_filled_path_collection_date_xaxis(): filled = [t for t in plotly_fig.data if t.fill == "toself"] assert len(filled) >= 1 assert all(isinstance(x, str) for x in filled[0].x) + + +def test_no_legend_entries_for_internal_mpl_labels(): + """mpl internal labels (_nolegend_, _childN) must not become legend entries.""" + fig, ax = plt.subplots() + ax.plot([0, 1, 2, 3], [0, 1, 0, 1], "b", [0, 1, 2, 3], [1, 0, 1, 0], "r--") + plotly_fig = tls.mpl_to_plotly(fig) + assert plotly_fig.layout.showlegend == False + assert all(t.name is None for t in plotly_fig.data)