Skip to content

Commit 73f86fd

Browse files
authored
Merge pull request #5716 from robertoffmoura/rm/export-tick-label-color
Export tick label colors to the plotly tickfont
2 parents 9447f1c + e29313f commit 73f86fd

5 files changed

Lines changed: 63 additions & 14 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
77
### Fixed
88
- Fix concurrent first access to lazily initialized graph object properties, which could raise `ValueError("Invalid value")` [[#5691](https://github.com/plotly/plotly.py/pull/5691)], with thanks to @hb1915 for the contribution!
99
- Fix `mpl_to_plotly` crashing on touching bars (such as `plt.hist`) due to floating-point noise producing negative `bargap` values by clamping `bargap` to `[0, 1]` [[#5696](https://github.com/plotly/plotly.py/pull/5696)], with thanks to @robertoffmoura for the contribution!
10+
- Export tick label colors to the plotly tickfont in `mpl_to_plotly` [[#5716](https://github.com/plotly/plotly.py/pull/5716)], with thanks to @robertoffmoura for the contribution!
1011
- Fix `px.sunburst`, `px.treemap` and `px.icicle` listing sectors in a different order on every run when `path` is used with a Polars DataFrame; sectors now follow their order of first appearance for all dataframe backends [[#5766](https://github.com/plotly/plotly.py/pull/5766)], with thanks to @Irahan2 for the contribution!
1112

1213
## [7.1.0] - 2026-09-15

‎plotly/matplotlylib/mplexporter/utils.py‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,12 +239,15 @@ def get_axis_properties(axis):
239239
# Get axis scale
240240
props["scale"] = axis.get_scale()
241241

242-
# Get major tick label size (assumes that's all we really care about!)
242+
# Get major tick label size and color (assumes that's all we really
243+
# care about!)
243244
labels = axis.get_ticklabels()
244245
if labels:
245246
props["fontsize"] = labels[0].get_fontsize()
247+
props["fontcolor"] = export_color(labels[0].get_color())
246248
else:
247249
props["fontsize"] = None
250+
props["fontcolor"] = None
248251

249252
# Get associated grid
250253
props["grid"] = get_grid_style(axis)

‎plotly/matplotlylib/mpltools.py‎

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -516,14 +516,32 @@ def prep_ticks(ax, index, ax_type, props):
516516
return axis_dict
517517

518518

519+
def _export_color(color):
520+
"""Export a matplotlib color for use as a plotly color.
521+
522+
matplotlib uses "none" for fully transparent colors, which plotly does not
523+
accept, so transparent colors are exported as transparent black.
524+
Colors already exported by the mplexporter (hex or rgba strings) are
525+
passed through unchanged.
526+
"""
527+
if color is None:
528+
return None
529+
if isinstance(color, str):
530+
return color if color != "none" else "rgba(0,0,0,0)"
531+
return [_export_color(c) for c in color]
532+
533+
519534
def prep_xy_axis(ax, props, x_bounds, y_bounds):
520535
xaxis = dict(
521536
type=props["axes"][0]["scale"],
522537
range=list(props["xlim"]),
523538
showgrid=props["axes"][0]["grid"]["gridOn"],
524539
domain=convert_x_domain(props["bounds"], x_bounds),
525540
side=props["axes"][0]["position"],
526-
tickfont=dict(size=props["axes"][0]["fontsize"]),
541+
tickfont=dict(
542+
size=props["axes"][0]["fontsize"],
543+
color=_export_color(props["axes"][0]["fontcolor"]),
544+
),
527545
)
528546
xaxis.update(prep_ticks(ax, 0, "x", props))
529547
yaxis = dict(
@@ -532,7 +550,10 @@ def prep_xy_axis(ax, props, x_bounds, y_bounds):
532550
showgrid=props["axes"][1]["grid"]["gridOn"],
533551
domain=convert_y_domain(props["bounds"], y_bounds),
534552
side=props["axes"][1]["position"],
535-
tickfont=dict(size=props["axes"][1]["fontsize"]),
553+
tickfont=dict(
554+
size=props["axes"][1]["fontsize"],
555+
color=_export_color(props["axes"][1]["fontcolor"]),
556+
),
536557
)
537558
yaxis.update(prep_ticks(ax, 1, "y", props))
538559
return xaxis, yaxis

‎plotly/matplotlylib/renderer.py‎

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,7 @@
1414
from plotly.matplotlylib import mpltools
1515

1616

17-
def _export_color(color):
18-
"""Export a matplotlib color for use as a plotly color.
19-
20-
matplotlib uses "none" for fully transparent colors, which plotly does not
21-
accept, so transparent colors are exported as transparent black.
22-
Colors already exported by the mplexporter (hex or rgba strings) are
23-
passed through unchanged.
24-
"""
25-
if isinstance(color, str):
26-
return "rgba(0,0,0,0)" if color == "none" else color
27-
return [_export_color(c) for c in color]
17+
from plotly.matplotlylib.mpltools import _export_color
2818

2919

3020
class PlotlyRenderer(Renderer):

‎plotly/matplotlylib/tests/test_renderer.py‎

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,3 +366,37 @@ def test_custom_date_xtickvals_given_as_numbers_are_converted():
366366
"2023-01-07 00:00:00",
367367
"2023-01-10 00:00:00",
368368
)
369+
370+
371+
def test_tick_label_color_exports():
372+
"""Tick label colors are exported to the plotly tickfont."""
373+
fig, ax = plt.subplots()
374+
ax.plot([0, 1], [0, 1])
375+
376+
plotly_fig = tls.mpl_to_plotly(fig)
377+
378+
assert plotly_fig.layout.xaxis.tickfont.color == "#000000"
379+
380+
381+
def test_dark_tick_label_color_exports():
382+
"""Dark-background tick label colors are exported to the plotly
383+
tickfont."""
384+
with plt.style.context("dark_background"):
385+
fig, ax = plt.subplots()
386+
ax.plot([0, 1], [0, 1])
387+
388+
plotly_fig = tls.mpl_to_plotly(fig)
389+
390+
assert plotly_fig.layout.xaxis.tickfont.color == "#FFFFFF"
391+
392+
393+
def test_transparent_tick_label_color_exports():
394+
"""Transparent tick label colors ('none') export as transparent rgba."""
395+
fig, ax = plt.subplots()
396+
ax.plot([0, 1], [0, 1])
397+
ax.tick_params(labelcolor="none")
398+
399+
plotly_fig = tls.mpl_to_plotly(fig)
400+
401+
assert plotly_fig.layout.xaxis.tickfont.color == "rgba(0,0,0,0)"
402+
assert plotly_fig.layout.yaxis.tickfont.color == "rgba(0,0,0,0)"

0 commit comments

Comments
 (0)