From d81353572438bad2e6561a403aa3385b4d98ab87 Mon Sep 17 00:00:00 2001 From: robertoffmoura Date: Sun, 15 Jun 2025 18:21:35 +0100 Subject: [PATCH 1/2] Add support for overriding x tick with non arithmetic progression values --- plotly/matplotlylib/mpltools.py | 13 +++++++++-- plotly/matplotlylib/tests/test_renderer.py | 25 ++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 plotly/matplotlylib/tests/test_renderer.py diff --git a/plotly/matplotlylib/mpltools.py b/plotly/matplotlylib/mpltools.py index 4268136003..bd0fc50db4 100644 --- a/plotly/matplotlylib/mpltools.py +++ b/plotly/matplotlylib/mpltools.py @@ -451,9 +451,9 @@ def prep_ticks(ax, index, ax_type, props): tick0 = tickvalues[0] dticks = [ round(tickvalues[i] - tickvalues[i - 1], 12) - for i in range(1, len(tickvalues) - 1) + for i in range(1, len(tickvalues)) ] - if all([dticks[i] == dticks[i - 1] for i in range(1, len(dticks) - 1)]): + if all([dticks[i] == dticks[i - 1] for i in range(1, len(dticks))]): dtick = tickvalues[1] - tickvalues[0] else: warnings.warn( @@ -463,6 +463,8 @@ def prep_ticks(ax, index, ax_type, props): raise TypeError except (IndexError, TypeError): axis_dict["nticks"] = props["axes"][index]["nticks"] + if props["axes"][index]["tickvalues"] is not None: + axis_dict["tickvals"] = props["axes"][index]["tickvalues"] else: axis_dict["tick0"] = tick0 axis_dict["dtick"] = dtick @@ -511,6 +513,13 @@ def prep_ticks(ax, index, ax_type, props): if formatter == "LogFormatterMathtext": axis_dict["exponentformat"] = "e" + elif formatter == "FuncFormatter" and props["axes"][index]["tickformat"] is not None: + to_remove = ["dtick" "tickmode"] + for key in to_remove: + if key in axis_dict: + axis_dict.pop(key) + axis_dict["ticktext"] = props["axes"][index]["tickformat"] + axis_dict["tickvals"] = props["axes"][index]["tickvalues"] return axis_dict diff --git a/plotly/matplotlylib/tests/test_renderer.py b/plotly/matplotlylib/tests/test_renderer.py new file mode 100644 index 0000000000..7ea7559f80 --- /dev/null +++ b/plotly/matplotlylib/tests/test_renderer.py @@ -0,0 +1,25 @@ +import plotly.tools as tls + +from . import plt + +def test_non_arithmetic_progression_xtickvals(): + xticks = [0.01, 0.53, 0.75] + plt.figure() + plt.plot([0, 1], [0, 1]) + plt.xticks(xticks) + + plotly_fig = tls.mpl_to_plotly(plt.gcf()) + + assert plotly_fig.layout.xaxis.tickvals == tuple(xticks) + +def test_non_arithmetic_progression_xticktext(): + xtickvals = [0.01, 0.53, 0.75] + xticktext = ["Baseline", "param = 1", "param = 2"] + plt.figure() + plt.plot([0, 1], [0, 1]) + plt.xticks(xtickvals, xticktext) + + plotly_fig = tls.mpl_to_plotly(plt.gcf()) + + assert plotly_fig.layout.xaxis.tickvals == tuple(xtickvals) + assert plotly_fig.layout.xaxis.ticktext == tuple(xticktext) From 128dd25b8b6c577d223c5500e65950923c7cc369 Mon Sep 17 00:00:00 2001 From: robertoffmoura Date: Tue, 12 Aug 2025 10:02:08 +0100 Subject: [PATCH 2/2] Run ruff format --- plotly/matplotlylib/mpltools.py | 6 ++++-- plotly/matplotlylib/tests/test_renderer.py | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/plotly/matplotlylib/mpltools.py b/plotly/matplotlylib/mpltools.py index bd0fc50db4..5aaf1e5c89 100644 --- a/plotly/matplotlylib/mpltools.py +++ b/plotly/matplotlylib/mpltools.py @@ -513,8 +513,10 @@ def prep_ticks(ax, index, ax_type, props): if formatter == "LogFormatterMathtext": axis_dict["exponentformat"] = "e" - elif formatter == "FuncFormatter" and props["axes"][index]["tickformat"] is not None: - to_remove = ["dtick" "tickmode"] + elif ( + formatter == "FuncFormatter" and props["axes"][index]["tickformat"] is not None + ): + to_remove = ["dticktickmode"] for key in to_remove: if key in axis_dict: axis_dict.pop(key) diff --git a/plotly/matplotlylib/tests/test_renderer.py b/plotly/matplotlylib/tests/test_renderer.py index 7ea7559f80..d895514027 100644 --- a/plotly/matplotlylib/tests/test_renderer.py +++ b/plotly/matplotlylib/tests/test_renderer.py @@ -2,6 +2,7 @@ from . import plt + def test_non_arithmetic_progression_xtickvals(): xticks = [0.01, 0.53, 0.75] plt.figure() @@ -12,6 +13,7 @@ def test_non_arithmetic_progression_xtickvals(): assert plotly_fig.layout.xaxis.tickvals == tuple(xticks) + def test_non_arithmetic_progression_xticktext(): xtickvals = [0.01, 0.53, 0.75] xticktext = ["Baseline", "param = 1", "param = 2"]