Skip to content

Deprecate savefig.facecolor, savefig.edgecolor, and savefig.transparent. #10023

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

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions doc/api/api_changes/2017-12-16-AL.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Deprecation of savefig-time modification of the figure patch face and edge colors
`````````````````````````````````````````````````````````````````````````````````

The ``facecolor``, ``edgecolor``, and ``transparent`` keyword arguments to
`~.Figure.savefig` and `~.FigureCanvasBase.print_figure`, and the associated
``savefig.facecolor``, ``savefig.edgecolor``, and ``savefig.transparent``
rcParams, have been deprecated. As a replacement for the first two
options, directly set the facecolor and edgecolor of the figure patch
(``figure.patch``), or set the ``figure.facecolor`` and ``figure.edgecolor``
rcParams. As a replacement for ``transparent``, set both the figure
patch color and the axes patch color to transparent, or likewise set the
corresponding rcParams.
36 changes: 25 additions & 11 deletions lib/matplotlib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -848,7 +848,13 @@ def gen_candidates():
_obsolete_set = {'plugins.directory', 'text.dvipnghack'}

# The following may use a value of None to suppress the warning.
_deprecated_set = {'axes.hold'} # do NOT include in _all_deprecated
# Do NOT include in _all_deprecated.
_deprecated_set = {
'axes.hold',
'savefig.facecolor',
'savefig.edgecolor',
'savefig.transparent',
}

_all_deprecated = set(itertools.chain(
_deprecated_ignore_map, _deprecated_map, _obsolete_set))
Expand Down Expand Up @@ -977,9 +983,11 @@ def rc_params(fail_on_error=False):
if not os.path.exists(fname):
# this should never happen, default in mpl-data should always be found
message = 'could not find rc file; returning defaults'
ret = RcParams([(key, default) for key, (default, _) in
six.iteritems(defaultParams)
if key not in _all_deprecated])
with warnings.catch_warnings():
warnings.filterwarnings("ignore", category=mplDeprecation)
ret = RcParams([(key, default) for key, (default, _) in
six.iteritems(defaultParams)
if key not in _all_deprecated])
warnings.warn(message)
return ret

Expand Down Expand Up @@ -1116,9 +1124,11 @@ def rc_params_from_file(fname, fail_on_error=False, use_default_template=True):
return config_from_file

iter_params = six.iteritems(defaultParams)
config = RcParams([(key, default) for key, (default, _) in iter_params
if key not in _all_deprecated])
config.update(config_from_file)
with warnings.catch_warnings():
warnings.filterwarnings("ignore", category=mplDeprecation)
config = RcParams([(key, default) for key, (default, _) in iter_params
if key not in _all_deprecated])
config.update(config_from_file)

if config['datapath'] is None:
config['datapath'] = get_data_path()
Expand Down Expand Up @@ -1155,9 +1165,11 @@ def rc_params_from_file(fname, fail_on_error=False, use_default_template=True):

rcParamsOrig = rcParams.copy()

rcParamsDefault = RcParams([(key, default) for key, (default, converter) in
six.iteritems(defaultParams)
if key not in _all_deprecated])
with warnings.catch_warnings():
warnings.filterwarnings("ignore", category=mplDeprecation)
rcParamsDefault = RcParams([(key, default) for key, (default, converter) in
six.iteritems(defaultParams)
if key not in _all_deprecated])

rcParams['ps.usedistiller'] = checkdep_ps_distiller(
rcParams['ps.usedistiller'])
Expand Down Expand Up @@ -1253,7 +1265,9 @@ def rcdefaults():
the default style.
"""
rcParams.clear()
rcParams.update(rcParamsDefault)
with warnings.catch_warnings():
warnings.filterwarnings("ignore", category=mplDeprecation)
rcParams.update(rcParamsDefault)


def rc_file_defaults():
Expand Down
16 changes: 10 additions & 6 deletions lib/matplotlib/backend_bases.py
Original file line number Diff line number Diff line change
Expand Up @@ -2125,12 +2125,6 @@ def print_figure(self, filename, dpi=None, facecolor=None, edgecolor=None,
dpi : scalar, optional
the dots per inch to save the figure in; if None, use savefig.dpi

facecolor : color spec or None, optional
the facecolor of the figure; if None, defaults to savefig.facecolor

edgecolor : color spec or None, optional
the edgecolor of the figure; if None, defaults to savefig.edgecolor

format : str, optional
when set, forcibly set the file format to save to

Expand Down Expand Up @@ -2172,8 +2166,18 @@ def print_figure(self, filename, dpi=None, facecolor=None, edgecolor=None,

if facecolor is None:
facecolor = rcParams['savefig.facecolor']
else:
cbook.warn_deprecated(
"2.2",
"The 'facecolor' kwarg is deprecated; set the figure's "
"facecolor ('figure.patch.facecolor') instead")
if edgecolor is None:
edgecolor = rcParams['savefig.edgecolor']
else:
cbook.warn_deprecated(
"2.2",
"The 'edgecolor' kwarg is deprecated; set the figure's "
"edgecolor ('figure.patch.edgecolor') instead")

origDPI = self.figure.dpi
origfacecolor = self.figure.get_facecolor()
Expand Down
7 changes: 2 additions & 5 deletions lib/matplotlib/backends/backend_agg.py
Original file line number Diff line number Diff line change
Expand Up @@ -562,12 +562,9 @@ def print_jpg(self, filename_or_obj, *args, **kwargs):
buf, size = self.print_to_buffer()
if kwargs.pop("dryrun", False):
return
# The image is "pasted" onto a white background image to safely
# handle any transparency
# Paste image onto a white background to handle transparency.
image = Image.frombuffer('RGBA', size, buf, 'raw', 'RGBA', 0, 1)
rgba = mcolors.to_rgba(rcParams['savefig.facecolor'])
color = tuple([int(x * 255.0) for x in rgba[:3]])
background = Image.new('RGB', size, color)
background = Image.new('RGB', size, (255, 255, 255))
background.paste(image, image)
options = {k: kwargs[k]
for k in ['quality', 'optimize', 'progressive', 'dpi']
Expand Down
6 changes: 2 additions & 4 deletions lib/matplotlib/backends/web_backend/nbagg_uat.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -399,8 +399,7 @@
"\n",
"### UAT 15 - Figure face colours\n",
"\n",
"The nbagg honours all colours appart from that of the figure.patch. The two plots below should produce a figure with a red background. There should be no yellow figure."
]
"The nbagg honours all colours appart from that of the figure.patch. The two plots below should produce a figure with a red background."
},
{
"cell_type": "code",
Expand All @@ -411,8 +410,7 @@
"outputs": [],
"source": [
"import matplotlib\n",
"matplotlib.rcParams.update({'figure.facecolor': 'red',\n",
" 'savefig.facecolor': 'yellow'})\n",
"matplotlib.rcParams.update({'figure.facecolor': 'red'})\n",
"plt.figure()\n",
"plt.plot([3, 2, 1])\n",
"\n",
Expand Down
36 changes: 18 additions & 18 deletions lib/matplotlib/figure.py
Original file line number Diff line number Diff line change
Expand Up @@ -1811,12 +1811,6 @@ def savefig(self, fname, **kwargs):
the value ``savefig.dpi`` in the matplotlibrc file. If 'figure'
it will set the dpi to be the value of the figure.

facecolor : color spec or None, optional
the facecolor of the figure; if None, defaults to savefig.facecolor

edgecolor : color spec or None, optional
the edgecolor of the figure; if None, defaults to savefig.edgecolor

orientation : {'landscape', 'portrait'}
not supported on all backends; currently only on postscript output

Expand All @@ -1829,15 +1823,6 @@ def savefig(self, fname, **kwargs):
One of the file extensions supported by the active
backend. Most backends support png, pdf, ps, eps and svg.

transparent : bool
If *True*, the axes patches will all be transparent; the
figure patch will also be transparent unless facecolor
and/or edgecolor are specified via kwargs.
This is useful, for example, for displaying
a plot on top of a colored background on a web page. The
transparency of these patches will be restored to their
original values upon exit of this function.

frameon : bool
If *True*, the figure patch will be colored, if *False*, the
figure background will be transparent. If not provided, the
Expand All @@ -1859,6 +1844,24 @@ def savefig(self, fname, **kwargs):
"""
kwargs.setdefault('dpi', rcParams['savefig.dpi'])
frameon = kwargs.pop('frameon', rcParams['savefig.frameon'])

if "transparent" in kwargs:
cbook.warn_deprecated(
"2.2",
"The 'transparent' kwarg is deprecated; set the figure's and "
"axes' facecolor ('figure.patch.facecolor', 'axes.patch."
"facecolor') to fully transparent ('none') instead")
if "facecolor" in kwargs:
cbook.warn_deprecated(
"2.2",
"The 'facecolor' kwarg is deprecated; set the figure's "
"facecolor ('figure.patch.facecolor') instead")
if "edgecolor" in kwargs:
cbook.warn_deprecated(
"2.2",
"The 'edgecolor' kwarg is deprecated; set the figure's "
"edgecolor ('figure.patch.edgecolor') instead")

transparent = kwargs.pop('transparent',
rcParams['savefig.transparent'])

Expand All @@ -1872,9 +1875,6 @@ def savefig(self, fname, **kwargs):
patch.get_edgecolor()))
patch.set_facecolor('none')
patch.set_edgecolor('none')
else:
kwargs.setdefault('facecolor', rcParams['savefig.facecolor'])
kwargs.setdefault('edgecolor', rcParams['savefig.edgecolor'])

if frameon:
original_frameon = self.get_frameon()
Expand Down
7 changes: 1 addition & 6 deletions lib/matplotlib/mpl-data/stylelib/_classic_test.mplstyle
Original file line number Diff line number Diff line change
Expand Up @@ -294,14 +294,13 @@ legend.facecolor : inherit # legend background color (when 'inherit' uses
legend.edgecolor : inherit # legend edge color (when 'inherit' uses axes.edgecolor)



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

Expand Down
4 changes: 0 additions & 4 deletions lib/matplotlib/mpl-data/stylelib/classic.mplstyle
Original file line number Diff line number Diff line change
Expand Up @@ -410,8 +410,6 @@ path.sketch : None # May be none, or a 3-tuple of the form (scale, length,
# e.g., you may want a higher resolution, or to make the figure
# background white
savefig.dpi : 100 # figure dots per inch
savefig.facecolor : w # figure facecolor when saving
savefig.edgecolor : w # figure edgecolor when saving
savefig.format : png # png, ps, pdf, svg
savefig.bbox : standard # 'tight' or 'standard'.
# 'tight' is incompatible with pipe-based animation
Expand All @@ -420,8 +418,6 @@ savefig.bbox : standard # 'tight' or 'standard'.
# use ffmpeg_file instead
savefig.pad_inches : 0.1 # Padding to be used when bbox is set to 'tight'
savefig.jpeg_quality: 95 # when a jpeg is saved, the default quality parameter.
savefig.transparent : False # setting that controls whether figures are saved with a
# transparent background by default
savefig.frameon : True
savefig.orientation : portrait

Expand Down
4 changes: 0 additions & 4 deletions lib/matplotlib/mpl-data/stylelib/dark_background.mplstyle
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,3 @@ grid.color: white

figure.facecolor: black
figure.edgecolor: black

savefig.facecolor: black
savefig.edgecolor: black

3 changes: 0 additions & 3 deletions lib/matplotlib/mpl-data/stylelib/fivethirtyeight.mplstyle
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@ ytick.minor.size: 0

font.size:14.0

savefig.edgecolor: f0f0f0
savefig.facecolor: f0f0f0

figure.subplot.left: 0.08
figure.subplot.right: 0.95
figure.subplot.bottom: 0.07
Expand Down
4 changes: 0 additions & 4 deletions lib/matplotlib/mpl-data/stylelib/grayscale.mplstyle
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,3 @@ figure.facecolor: 0.75
figure.edgecolor: white

image.cmap: gray

savefig.facecolor: white
savefig.edgecolor: white

22 changes: 9 additions & 13 deletions lib/matplotlib/tests/test_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -523,20 +523,16 @@ def test_jpeg_alpha():

plt.figimage(im)

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

buff.seek(0)
image = Image.open(buff)

# If this fails, there will be only one color (all black). If this
# is working, we should have all 256 shades of grey represented.
num_colors = len(image.getcolors(256))
assert 175 <= num_colors <= 185
# The fully transparent part should be red.
corner_pixel = image.getpixel((0, 0))
assert corner_pixel == (254, 0, 0)
# If this fails, there will be only one color (all black). If this is
# working, we should have all 256 shades of grey represented.
assert len(image.getcolors(256)) == 256
# The fully transparent part should be white.
assert image.getpixel((0, 0)) == (255, 255, 255)


def test_nonuniformimage_setdata():
Expand Down
4 changes: 0 additions & 4 deletions matplotlibrc.template
Original file line number Diff line number Diff line change
Expand Up @@ -507,8 +507,6 @@ backend : $TEMPLATE_BACKEND
# e.g., you may want a higher resolution, or to make the figure
# background white
#savefig.dpi : figure # figure dots per inch or 'figure'
#savefig.facecolor : white # figure facecolor when saving
#savefig.edgecolor : white # figure edgecolor when saving
#savefig.format : png # png, ps, pdf, svg
#savefig.bbox : standard # 'tight' or 'standard'.
# 'tight' is incompatible with pipe-based animation
Expand All @@ -519,8 +517,6 @@ backend : $TEMPLATE_BACKEND
#savefig.jpeg_quality: 95 # when a jpeg is saved, the default quality parameter.
#savefig.directory : ~ # default directory in savefig dialog box,
# leave empty to always use current working directory
#savefig.transparent : False # setting that controls whether figures are saved with a
# transparent background by default

# tk backend params
#tk.window_focus : False # Maintain shell focus for TkAgg
Expand Down
2 changes: 1 addition & 1 deletion tutorials/intermediate/tight_layout_guide.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
import matplotlib.pyplot as plt
import numpy as np

plt.rcParams['savefig.facecolor'] = "0.8"
plt.rcParams['figure.facecolor'] = "0.8"


def example_plot(ax, fontsize=12):
Expand Down