Skip to content

Commit b865431

Browse files
Set plot_bgcolor and paper_bgcolor from matplotlib figure backgrounds
1 parent 15f33d2 commit b865431

2 files changed

Lines changed: 46 additions & 2 deletions

File tree

plotly/matplotlylib/renderer.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
import plotly.graph_objs as go
1313
from plotly.matplotlylib.mplexporter import Renderer
14+
from plotly.matplotlylib.mplexporter.utils import export_color
1415
from plotly.matplotlylib import mpltools
1516

1617

@@ -20,11 +21,15 @@ def _export_color(color):
2021
matplotlib uses "none" for fully transparent colors, which plotly does not
2122
accept, so transparent colors are exported as transparent black.
2223
Colors already exported by the mplexporter (hex or rgba strings) are
23-
passed through unchanged.
24+
passed through unchanged; raw matplotlib colors are converted with the
25+
mplexporter's export_color.
2426
"""
2527
if isinstance(color, str):
2628
return "rgba(0,0,0,0)" if color == "none" else color
27-
return [_export_color(c) for c in color]
29+
if isinstance(color, (list, tuple)) and all(isinstance(c, str) for c in color):
30+
return [_export_color(c) for c in color]
31+
bgcolor = export_color(color)
32+
return "rgba(0,0,0,0)" if bgcolor == "none" else bgcolor
2833

2934

3035
class PlotlyRenderer(Renderer):
@@ -101,6 +106,9 @@ def open_figure(self, fig, props):
101106
autosize=False,
102107
hovermode="closest",
103108
)
109+
self.plotly_fig["layout"].paper_bgcolor = _export_color(
110+
fig.patch.get_facecolor()
111+
)
104112
self.mpl_x_bounds, self.mpl_y_bounds = mpltools.get_axes_bounds(fig)
105113
margin = go.layout.Margin(
106114
l=int(self.mpl_x_bounds[0] * self.plotly_fig["layout"]["width"]),
@@ -166,6 +174,8 @@ def open_axes(self, ax, props):
166174
]
167175
self.current_bars = []
168176
self.axis_ct += 1
177+
# update plot background with the axes background from mpl
178+
self.plotly_fig["layout"].plot_bgcolor = _export_color(props["axesbg"])
169179
# set defaults in axes
170180
xaxis = go.layout.XAxis(
171181
anchor="y{0}".format(self.axis_ct), zeroline=False, ticks="inside"

plotly/matplotlylib/tests/test_renderer.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,3 +199,37 @@ def test_filled_path_collection_date_xaxis():
199199
filled = [t for t in plotly_fig.data if t.fill == "toself"]
200200
assert len(filled) >= 1
201201
assert all(isinstance(x, str) for x in filled[0].x)
202+
203+
204+
def test_background_colors_from_matplotlib_defaults():
205+
fig, ax = plt.subplots()
206+
ax.plot([0, 1], [0, 1])
207+
208+
plotly_fig = tls.mpl_to_plotly(fig)
209+
210+
assert plotly_fig.layout.plot_bgcolor == "#FFFFFF"
211+
assert plotly_fig.layout.paper_bgcolor == "#FFFFFF"
212+
213+
214+
def test_custom_background_colors_are_preserved():
215+
fig, ax = plt.subplots()
216+
fig.patch.set_facecolor("lightyellow")
217+
ax.set_facecolor("lightgray")
218+
ax.plot([0, 1], [0, 1])
219+
220+
plotly_fig = tls.mpl_to_plotly(fig)
221+
222+
assert plotly_fig.layout.plot_bgcolor == "#D3D3D3"
223+
assert plotly_fig.layout.paper_bgcolor == "#FFFFE0"
224+
225+
226+
def test_semitransparent_axes_background_preserved():
227+
"""Axes backgrounds with alpha export as mpl-style rgba strings, which
228+
must be passed through as-is, not re-parsed by export_color."""
229+
fig, ax = plt.subplots()
230+
ax.set_facecolor((0.1, 0.2, 0.3, 0.4))
231+
ax.plot([0, 1], [0, 1])
232+
233+
plotly_fig = tls.mpl_to_plotly(fig)
234+
235+
assert plotly_fig.layout.plot_bgcolor == "rgba(26, 51, 76, 0.4)"

0 commit comments

Comments
 (0)