Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mpl_to_plotly does not preserve axis labels (bar plots are useless) #5059

Open
krassowski opened this issue Feb 28, 2025 · 1 comment
Open
Labels
bug something broken P3 backlog

Comments

@krassowski
Copy link

While mpl_to_plotly is little known and receives little love, this bug is pretty easy to fix. Would you be open to a PR?

import matplotlib.pyplot as plt
from plotly.tools import mpl_to_plotly
from plotly.offline import plot

In matplotlib this produces a barplot with labels:

labels = ['a', 'b', 'c']
values = [1, 2, 3]

f = plt.figure(figsize=(6, 4))
plt.bar(labels, values)
plt.tight_layout()

Image

But conversion to plotly looses the labels:

plotly_fig = mpl_to_plotly(f)
plot(plotly_fig)

Image

A minimal fix would be to modify prep_ticks by appending:

    if axis_dict.get("type") == "date":
        return axis_dict
    
    vals = []
    texts = []
    for tick in axis.majorTicks:
        vals.append(tick.get_loc())
        texts.append(tick.label1.get_text())
    
    if texts:
        axis_dict = {}
        axis_dict['tickmode'] = 'array'
        axis_dict['tickvals'] = vals
        axis_dict['ticktext'] = texts
    
    return axis_dict

which produces:

Image

prep_ticks is defined in:

def prep_ticks(ax, index, ax_type, props):
"""Prepare axis obj belonging to axes obj.
positional arguments:
ax - the mpl axes instance
index - the index of the axis in `props`
ax_type - 'x' or 'y' (for now)
props - an mplexporter poperties dictionary
"""
axis_dict = dict()
if ax_type == "x":
axis = ax.get_xaxis()
elif ax_type == "y":
axis = ax.get_yaxis()
else:
return dict() # whoops!
scale = props["axes"][index]["scale"]
if scale == "linear":
# get tick location information
try:
tickvalues = props["axes"][index]["tickvalues"]
tick0 = tickvalues[0]
dticks = [
round(tickvalues[i] - tickvalues[i - 1], 12)
for i in range(1, len(tickvalues) - 1)
]
if all([dticks[i] == dticks[i - 1] for i in range(1, len(dticks) - 1)]):
dtick = tickvalues[1] - tickvalues[0]
else:
warnings.warn(
"'linear' {0}-axis tick spacing not even, "
"ignoring mpl tick formatting.".format(ax_type)
)
raise TypeError
except (IndexError, TypeError):
axis_dict["nticks"] = props["axes"][index]["nticks"]
else:
axis_dict["tick0"] = tick0
axis_dict["dtick"] = dtick
axis_dict["tickmode"] = None
elif scale == "log":
try:
axis_dict["tick0"] = props["axes"][index]["tickvalues"][0]
axis_dict["dtick"] = (
props["axes"][index]["tickvalues"][1]
- props["axes"][index]["tickvalues"][0]
)
axis_dict["tickmode"] = None
except (IndexError, TypeError):
axis_dict = dict(nticks=props["axes"][index]["nticks"])
base = axis.get_transform().base
if base == 10:
if ax_type == "x":
axis_dict["range"] = [
math.log10(props["xlim"][0]),
math.log10(props["xlim"][1]),
]
elif ax_type == "y":
axis_dict["range"] = [
math.log10(props["ylim"][0]),
math.log10(props["ylim"][1]),
]
else:
axis_dict = dict(range=None, type="linear")
warnings.warn(
"Converted non-base10 {0}-axis log scale to 'linear'" "".format(ax_type)
)
else:
return dict()
# get tick label formatting information
formatter = axis.get_major_formatter().__class__.__name__
if ax_type == "x" and "DateFormatter" in formatter:
axis_dict["type"] = "date"
try:
axis_dict["tick0"] = mpl_dates_to_datestrings(axis_dict["tick0"], formatter)
except KeyError:
pass
finally:
axis_dict.pop("dtick", None)
axis_dict.pop("tickmode", None)
axis_dict["range"] = mpl_dates_to_datestrings(props["xlim"], formatter)
if formatter == "LogFormatterMathtext":
axis_dict["exponentformat"] = "e"
return axis_dict

@gvwilson gvwilson added bug something broken P3 backlog labels Mar 3, 2025
@gvwilson
Copy link
Contributor

gvwilson commented Mar 3, 2025

thanks very much @krassowski - yes, we would be very happy to get a PR. thanks - @gvwilson

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug something broken P3 backlog
Projects
None yet
Development

No branches or pull requests

2 participants