Skip to content

Commit ff4e297

Browse files
committed
Deprecate savefig.facecolor, savefig.edgecolor, and savefig.transparent.
They cause a number of complications for print_figure (which needs to temporarily switch the figure and axes face and edge colors) that are unnecessary (the user can directly set the color they wish (including transparent) on the figure patch instead; an rcParam is even available for that purpose).
1 parent 1928c38 commit ff4e297

14 files changed

+80
-82
lines changed

doc/api/api_changes/2017-12-16-AL.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Deprecation of savefig-time modification of the figure patch face and edge colors
2+
`````````````````````````````````````````````````````````````````````````````````
3+
4+
The ``facecolor``, ``edgecolor``, and ``transparent`` keyword arguments to
5+
`~.Figure.savefig` and `~.FigureCanvasBase.print_figure`, and the associated
6+
``savefig.facecolor``, ``savefig.edgecolor``, and ``savefig.transparent``
7+
rcParams, have been deprecated. As a replacement for the first two
8+
options, directly set the facecolor and edgecolor of the figure patch
9+
(``figure.patch``), or set the ``figure.facecolor`` and ``figure.edgecolor``
10+
rcParams. As a replacement for ``transparent``, set both the figure
11+
patch color and the axes patch color to transparent, or likewise set the
12+
corresponding rcParams.

lib/matplotlib/__init__.py

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -862,7 +862,13 @@ def gen_candidates():
862862
_obsolete_set = {'text.dvipnghack', 'legend.isaxes'}
863863

864864
# The following may use a value of None to suppress the warning.
865-
_deprecated_set = {'axes.hold'} # do NOT include in _all_deprecated
865+
# Do NOT include in _all_deprecated.
866+
_deprecated_set = {
867+
'axes.hold',
868+
'savefig.facecolor',
869+
'savefig.edgecolor',
870+
'savefig.transparent',
871+
}
866872

867873
_all_deprecated = set(itertools.chain(
868874
_deprecated_ignore_map, _deprecated_map, _obsolete_set))
@@ -991,9 +997,11 @@ def rc_params(fail_on_error=False):
991997
if not os.path.exists(fname):
992998
# this should never happen, default in mpl-data should always be found
993999
message = 'could not find rc file; returning defaults'
994-
ret = RcParams([(key, default) for key, (default, _) in
995-
six.iteritems(defaultParams)
996-
if key not in _all_deprecated])
1000+
with warnings.catch_warnings():
1001+
warnings.filterwarnings("ignore", category=mplDeprecation)
1002+
ret = RcParams([(key, default) for key, (default, _) in
1003+
six.iteritems(defaultParams)
1004+
if key not in _all_deprecated])
9971005
warnings.warn(message)
9981006
return ret
9991007

@@ -1130,9 +1138,11 @@ def rc_params_from_file(fname, fail_on_error=False, use_default_template=True):
11301138
return config_from_file
11311139

11321140
iter_params = six.iteritems(defaultParams)
1133-
config = RcParams([(key, default) for key, (default, _) in iter_params
1134-
if key not in _all_deprecated])
1135-
config.update(config_from_file)
1141+
with warnings.catch_warnings():
1142+
warnings.filterwarnings("ignore", category=mplDeprecation)
1143+
config = RcParams([(key, default) for key, (default, _) in iter_params
1144+
if key not in _all_deprecated])
1145+
config.update(config_from_file)
11361146

11371147
if config['datapath'] is None:
11381148
config['datapath'] = get_data_path()
@@ -1169,9 +1179,11 @@ def rc_params_from_file(fname, fail_on_error=False, use_default_template=True):
11691179

11701180
rcParamsOrig = rcParams.copy()
11711181

1172-
rcParamsDefault = RcParams([(key, default) for key, (default, converter) in
1173-
six.iteritems(defaultParams)
1174-
if key not in _all_deprecated])
1182+
with warnings.catch_warnings():
1183+
warnings.filterwarnings("ignore", category=mplDeprecation)
1184+
rcParamsDefault = RcParams([(key, default) for key, (default, converter) in
1185+
six.iteritems(defaultParams)
1186+
if key not in _all_deprecated])
11751187

11761188
rcParams['ps.usedistiller'] = checkdep_ps_distiller(
11771189
rcParams['ps.usedistiller'])
@@ -1267,7 +1279,9 @@ def rcdefaults():
12671279
the default style.
12681280
"""
12691281
rcParams.clear()
1270-
rcParams.update(rcParamsDefault)
1282+
with warnings.catch_warnings():
1283+
warnings.filterwarnings("ignore", category=mplDeprecation)
1284+
rcParams.update(rcParamsDefault)
12711285

12721286

12731287
def rc_file_defaults():

lib/matplotlib/backend_bases.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2132,12 +2132,6 @@ def print_figure(self, filename, dpi=None, facecolor=None, edgecolor=None,
21322132
dpi : scalar, optional
21332133
the dots per inch to save the figure in; if None, use savefig.dpi
21342134
2135-
facecolor : color spec or None, optional
2136-
the facecolor of the figure; if None, defaults to savefig.facecolor
2137-
2138-
edgecolor : color spec or None, optional
2139-
the edgecolor of the figure; if None, defaults to savefig.edgecolor
2140-
21412135
format : str, optional
21422136
when set, forcibly set the file format to save to
21432137
@@ -2179,8 +2173,18 @@ def print_figure(self, filename, dpi=None, facecolor=None, edgecolor=None,
21792173

21802174
if facecolor is None:
21812175
facecolor = rcParams['savefig.facecolor']
2176+
else:
2177+
cbook.warn_deprecated(
2178+
"2.2",
2179+
"The 'facecolor' kwarg is deprecated; set the figure's "
2180+
"facecolor ('figure.patch.facecolor') instead")
21822181
if edgecolor is None:
21832182
edgecolor = rcParams['savefig.edgecolor']
2183+
else:
2184+
cbook.warn_deprecated(
2185+
"2.2",
2186+
"The 'edgecolor' kwarg is deprecated; set the figure's "
2187+
"edgecolor ('figure.patch.edgecolor') instead")
21842188

21852189
origDPI = self.figure.dpi
21862190
origfacecolor = self.figure.get_facecolor()

lib/matplotlib/backends/backend_agg.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -569,12 +569,9 @@ def print_jpg(self, filename_or_obj, *args, **kwargs):
569569
buf, size = self.print_to_buffer()
570570
if kwargs.pop("dryrun", False):
571571
return
572-
# The image is "pasted" onto a white background image to safely
573-
# handle any transparency
572+
# Paste image onto a white background to handle transparency.
574573
image = Image.frombuffer('RGBA', size, buf, 'raw', 'RGBA', 0, 1)
575-
rgba = mcolors.to_rgba(rcParams['savefig.facecolor'])
576-
color = tuple([int(x * 255.0) for x in rgba[:3]])
577-
background = Image.new('RGB', size, color)
574+
background = Image.new('RGB', size, (255, 255, 255))
578575
background.paste(image, image)
579576
options = {k: kwargs[k]
580577
for k in ['quality', 'optimize', 'progressive', 'dpi']

lib/matplotlib/backends/web_backend/nbagg_uat.ipynb

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@
399399
"\n",
400400
"### UAT 15 - Figure face colours\n",
401401
"\n",
402-
"The nbagg honours all colours appart from that of the figure.patch. The two plots below should produce a figure with a transparent background and a red background respectively (check the transparency by closing the figure, and dragging the resulting image over other content). There should be no yellow figure."
402+
"The nbagg honours all colours appart from that of the figure.patch. The two plots below should produce a figure with a transparent background and a red background respectively (check the transparency by closing the figure, and dragging the resulting image over other content)."
403403
]
404404
},
405405
{
@@ -411,8 +411,7 @@
411411
"outputs": [],
412412
"source": [
413413
"import matplotlib\n",
414-
"matplotlib.rcParams.update({'figure.facecolor': 'red',\n",
415-
" 'savefig.facecolor': 'yellow'})\n",
414+
"matplotlib.rcParams.update({'figure.facecolor': 'red'})\n",
416415
"plt.figure()\n",
417416
"plt.plot([3, 2, 1])\n",
418417
"\n",

lib/matplotlib/figure.py

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1792,12 +1792,6 @@ def savefig(self, fname, **kwargs):
17921792
the value ``savefig.dpi`` in the matplotlibrc file. If 'figure'
17931793
it will set the dpi to be the value of the figure.
17941794
1795-
facecolor : color spec or None, optional
1796-
the facecolor of the figure; if None, defaults to savefig.facecolor
1797-
1798-
edgecolor : color spec or None, optional
1799-
the edgecolor of the figure; if None, defaults to savefig.edgecolor
1800-
18011795
orientation : {'landscape', 'portrait'}
18021796
not supported on all backends; currently only on postscript output
18031797
@@ -1810,15 +1804,6 @@ def savefig(self, fname, **kwargs):
18101804
One of the file extensions supported by the active
18111805
backend. Most backends support png, pdf, ps, eps and svg.
18121806
1813-
transparent : bool
1814-
If *True*, the axes patches will all be transparent; the
1815-
figure patch will also be transparent unless facecolor
1816-
and/or edgecolor are specified via kwargs.
1817-
This is useful, for example, for displaying
1818-
a plot on top of a colored background on a web page. The
1819-
transparency of these patches will be restored to their
1820-
original values upon exit of this function.
1821-
18221807
frameon : bool
18231808
If *True*, the figure patch will be colored, if *False*, the
18241809
figure background will be transparent. If not provided, the
@@ -1840,6 +1825,24 @@ def savefig(self, fname, **kwargs):
18401825
"""
18411826
kwargs.setdefault('dpi', rcParams['savefig.dpi'])
18421827
frameon = kwargs.pop('frameon', rcParams['savefig.frameon'])
1828+
1829+
if "transparent" in kwargs:
1830+
cbook.warn_deprecated(
1831+
"2.2",
1832+
"The 'transparent' kwarg is deprecated; set the figure's and "
1833+
"axes' facecolor ('figure.patch.facecolor', 'axes.patch."
1834+
"facecolor') to fully transparent ('none') instead")
1835+
if "facecolor" in kwargs:
1836+
cbook.warn_deprecated(
1837+
"2.2",
1838+
"The 'facecolor' kwarg is deprecated; set the figure's "
1839+
"facecolor ('figure.patch.facecolor') instead")
1840+
if "edgecolor" in kwargs:
1841+
cbook.warn_deprecated(
1842+
"2.2",
1843+
"The 'edgecolor' kwarg is deprecated; set the figure's "
1844+
"edgecolor ('figure.patch.edgecolor') instead")
1845+
18431846
transparent = kwargs.pop('transparent',
18441847
rcParams['savefig.transparent'])
18451848

@@ -1853,9 +1856,6 @@ def savefig(self, fname, **kwargs):
18531856
patch.get_edgecolor()))
18541857
patch.set_facecolor('none')
18551858
patch.set_edgecolor('none')
1856-
else:
1857-
kwargs.setdefault('facecolor', rcParams['savefig.facecolor'])
1858-
kwargs.setdefault('edgecolor', rcParams['savefig.edgecolor'])
18591859

18601860
if frameon:
18611861
original_frameon = self.get_frameon()

lib/matplotlib/mpl-data/stylelib/_classic_test.mplstyle

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -294,14 +294,13 @@ legend.facecolor : inherit # legend background color (when 'inherit' uses
294294
legend.edgecolor : inherit # legend edge color (when 'inherit' uses axes.edgecolor)
295295

296296

297-
298297
### FIGURE
299298
# See http://matplotlib.org/api/figure_api.html#matplotlib.figure.Figure
300299
figure.titlesize : medium # size of the figure title
301300
figure.titleweight : normal # weight of the figure title
302301
figure.figsize : 8, 6 # figure size in inches
303302
figure.dpi : 80 # figure dots per inch
304-
figure.facecolor : 0.75 # figure facecolor; 0.75 is scalar gray
303+
figure.facecolor : w # figure facecolor
305304
figure.edgecolor : w # figure edgecolor
306305
figure.autolayout : False # When True, automatically adjust subplot
307306
# parameters to make the plot fit the figure
@@ -408,8 +407,6 @@ path.sketch : None # May be none, or a 3-tuple of the form (scale, length,
408407
# e.g., you may want a higher resolution, or to make the figure
409408
# background white
410409
savefig.dpi : 100 # figure dots per inch
411-
savefig.facecolor : w # figure facecolor when saving
412-
savefig.edgecolor : w # figure edgecolor when saving
413410
savefig.format : png # png, ps, pdf, svg
414411
savefig.bbox : standard # 'tight' or 'standard'.
415412
# 'tight' is incompatible with pipe-based animation
@@ -418,8 +415,6 @@ savefig.bbox : standard # 'tight' or 'standard'.
418415
# use ffmpeg_file instead
419416
savefig.pad_inches : 0.1 # Padding to be used when bbox is set to 'tight'
420417
savefig.jpeg_quality: 95 # when a jpeg is saved, the default quality parameter.
421-
savefig.transparent : False # setting that controls whether figures are saved with a
422-
# transparent background by default
423418
savefig.frameon : True
424419
savefig.orientation : portrait
425420

lib/matplotlib/mpl-data/stylelib/classic.mplstyle

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -410,8 +410,6 @@ path.sketch : None # May be none, or a 3-tuple of the form (scale, length,
410410
# e.g., you may want a higher resolution, or to make the figure
411411
# background white
412412
savefig.dpi : 100 # figure dots per inch
413-
savefig.facecolor : w # figure facecolor when saving
414-
savefig.edgecolor : w # figure edgecolor when saving
415413
savefig.format : png # png, ps, pdf, svg
416414
savefig.bbox : standard # 'tight' or 'standard'.
417415
# 'tight' is incompatible with pipe-based animation
@@ -420,8 +418,6 @@ savefig.bbox : standard # 'tight' or 'standard'.
420418
# use ffmpeg_file instead
421419
savefig.pad_inches : 0.1 # Padding to be used when bbox is set to 'tight'
422420
savefig.jpeg_quality: 95 # when a jpeg is saved, the default quality parameter.
423-
savefig.transparent : False # setting that controls whether figures are saved with a
424-
# transparent background by default
425421
savefig.frameon : True
426422
savefig.orientation : portrait
427423

lib/matplotlib/mpl-data/stylelib/dark_background.mplstyle

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,3 @@ grid.color: white
1717

1818
figure.facecolor: black
1919
figure.edgecolor: black
20-
21-
savefig.facecolor: black
22-
savefig.edgecolor: black
23-

lib/matplotlib/mpl-data/stylelib/fivethirtyeight.mplstyle

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,6 @@ ytick.minor.size: 0
3131

3232
font.size:14.0
3333

34-
savefig.edgecolor: f0f0f0
35-
savefig.facecolor: f0f0f0
36-
3734
figure.subplot.left: 0.08
3835
figure.subplot.right: 0.95
3936
figure.subplot.bottom: 0.07

lib/matplotlib/mpl-data/stylelib/grayscale.mplstyle

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,3 @@ figure.facecolor: 0.75
2323
figure.edgecolor: white
2424

2525
image.cmap: gray
26-
27-
savefig.facecolor: white
28-
savefig.edgecolor: white
29-

lib/matplotlib/tests/test_image.py

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -504,20 +504,16 @@ def test_jpeg_alpha():
504504

505505
plt.figimage(im)
506506

507-
buff = io.BytesIO()
508-
with rc_context({'savefig.facecolor': 'red'}):
509-
plt.savefig(buff, transparent=True, format='jpg', dpi=300)
507+
buf = io.BytesIO()
508+
plt.savefig(buf, transparent=True, format='jpg', dpi=300)
509+
buf.seek(0)
510+
image = Image.open(buf)
510511

511-
buff.seek(0)
512-
image = Image.open(buff)
513-
514-
# If this fails, there will be only one color (all black). If this
515-
# is working, we should have all 256 shades of grey represented.
516-
num_colors = len(image.getcolors(256))
517-
assert 175 <= num_colors <= 185
518-
# The fully transparent part should be red.
519-
corner_pixel = image.getpixel((0, 0))
520-
assert corner_pixel == (254, 0, 0)
512+
# If this fails, there will be only one color (all black). If this is
513+
# working, we should have all 256 shades of grey represented.
514+
assert len(image.getcolors(256)) == 256
515+
# The fully transparent part should be white.
516+
assert image.getpixel((0, 0)) == (255, 255, 255)
521517

522518

523519
def test_nonuniformimage_setdata():

matplotlibrc.template

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -511,8 +511,6 @@ backend : $TEMPLATE_BACKEND
511511
# e.g., you may want a higher resolution, or to make the figure
512512
# background white
513513
#savefig.dpi : figure # figure dots per inch or 'figure'
514-
#savefig.facecolor : white # figure facecolor when saving
515-
#savefig.edgecolor : white # figure edgecolor when saving
516514
#savefig.format : png # png, ps, pdf, svg
517515
#savefig.bbox : standard # 'tight' or 'standard'.
518516
# 'tight' is incompatible with pipe-based animation
@@ -523,8 +521,6 @@ backend : $TEMPLATE_BACKEND
523521
#savefig.jpeg_quality: 95 # when a jpeg is saved, the default quality parameter.
524522
#savefig.directory : ~ # default directory in savefig dialog box,
525523
# leave empty to always use current working directory
526-
#savefig.transparent : False # setting that controls whether figures are saved with a
527-
# transparent background by default
528524

529525
# tk backend params
530526
#tk.window_focus : False # Maintain shell focus for TkAgg

tutorials/intermediate/tight_layout_guide.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
import matplotlib.pyplot as plt
2525
import numpy as np
2626

27-
plt.rcParams['savefig.facecolor'] = "0.8"
27+
plt.rcParams['figure.facecolor'] = "0.8"
2828

2929

3030
def example_plot(ax, fontsize=12):

0 commit comments

Comments
 (0)