From 0a9e050adf6327808914456f8f7bccf5ebb1af69 Mon Sep 17 00:00:00 2001 From: Roberto Moura Date: Sun, 15 Jun 2025 18:21:35 +0100 Subject: [PATCH] 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 641606b3182..003f6d245b8 100644 --- a/plotly/matplotlylib/mpltools.py +++ b/plotly/matplotlylib/mpltools.py @@ -452,9 +452,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( @@ -464,6 +464,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 @@ -512,6 +514,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 00000000000..7ea7559f800 --- /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)