diff --git a/doc/api/api_changes/2017-12-16-AL.rst b/doc/api/api_changes/2017-12-16-AL.rst new file mode 100644 index 000000000000..21d0b65549d4 --- /dev/null +++ b/doc/api/api_changes/2017-12-16-AL.rst @@ -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. diff --git a/lib/matplotlib/__init__.py b/lib/matplotlib/__init__.py index 9f777dedcf7e..d73bb7ee01f5 100644 --- a/lib/matplotlib/__init__.py +++ b/lib/matplotlib/__init__.py @@ -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)) @@ -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 @@ -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() @@ -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']) @@ -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(): diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index 9909634b89e2..8a4c3b53a60a 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -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 @@ -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() diff --git a/lib/matplotlib/backends/backend_agg.py b/lib/matplotlib/backends/backend_agg.py index 16ffdbbf8aac..e7c5634aafc5 100644 --- a/lib/matplotlib/backends/backend_agg.py +++ b/lib/matplotlib/backends/backend_agg.py @@ -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'] diff --git a/lib/matplotlib/backends/web_backend/nbagg_uat.ipynb b/lib/matplotlib/backends/web_backend/nbagg_uat.ipynb index 83e8235d187b..aa6b582fe3a1 100644 --- a/lib/matplotlib/backends/web_backend/nbagg_uat.ipynb +++ b/lib/matplotlib/backends/web_backend/nbagg_uat.ipynb @@ -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", @@ -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", diff --git a/lib/matplotlib/figure.py b/lib/matplotlib/figure.py index b56c67b3c054..c95e2b025395 100644 --- a/lib/matplotlib/figure.py +++ b/lib/matplotlib/figure.py @@ -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 @@ -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 @@ -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']) @@ -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() diff --git a/lib/matplotlib/mpl-data/stylelib/_classic_test.mplstyle b/lib/matplotlib/mpl-data/stylelib/_classic_test.mplstyle index 70071b47b41e..bad3c778fe2d 100644 --- a/lib/matplotlib/mpl-data/stylelib/_classic_test.mplstyle +++ b/lib/matplotlib/mpl-data/stylelib/_classic_test.mplstyle @@ -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 @@ -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 @@ -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 diff --git a/lib/matplotlib/mpl-data/stylelib/classic.mplstyle b/lib/matplotlib/mpl-data/stylelib/classic.mplstyle index 493cc15d7f28..ba9dae72d097 100644 --- a/lib/matplotlib/mpl-data/stylelib/classic.mplstyle +++ b/lib/matplotlib/mpl-data/stylelib/classic.mplstyle @@ -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 @@ -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 diff --git a/lib/matplotlib/mpl-data/stylelib/dark_background.mplstyle b/lib/matplotlib/mpl-data/stylelib/dark_background.mplstyle index a8b754005bfd..6ab5a28b8b2c 100644 --- a/lib/matplotlib/mpl-data/stylelib/dark_background.mplstyle +++ b/lib/matplotlib/mpl-data/stylelib/dark_background.mplstyle @@ -17,7 +17,3 @@ grid.color: white figure.facecolor: black figure.edgecolor: black - -savefig.facecolor: black -savefig.edgecolor: black - diff --git a/lib/matplotlib/mpl-data/stylelib/fivethirtyeight.mplstyle b/lib/matplotlib/mpl-data/stylelib/fivethirtyeight.mplstyle index 738db39f5f80..00df066544b8 100644 --- a/lib/matplotlib/mpl-data/stylelib/fivethirtyeight.mplstyle +++ b/lib/matplotlib/mpl-data/stylelib/fivethirtyeight.mplstyle @@ -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 diff --git a/lib/matplotlib/mpl-data/stylelib/grayscale.mplstyle b/lib/matplotlib/mpl-data/stylelib/grayscale.mplstyle index 6a1114e40698..d65ddccfee07 100644 --- a/lib/matplotlib/mpl-data/stylelib/grayscale.mplstyle +++ b/lib/matplotlib/mpl-data/stylelib/grayscale.mplstyle @@ -23,7 +23,3 @@ figure.facecolor: 0.75 figure.edgecolor: white image.cmap: gray - -savefig.facecolor: white -savefig.edgecolor: white - diff --git a/lib/matplotlib/tests/test_image.py b/lib/matplotlib/tests/test_image.py index ca3443a78445..4ab9b20b69df 100644 --- a/lib/matplotlib/tests/test_image.py +++ b/lib/matplotlib/tests/test_image.py @@ -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(): diff --git a/matplotlibrc.template b/matplotlibrc.template index 7ac32f71cf8d..e1518d1d23a6 100644 --- a/matplotlibrc.template +++ b/matplotlibrc.template @@ -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 @@ -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 diff --git a/tutorials/intermediate/tight_layout_guide.py b/tutorials/intermediate/tight_layout_guide.py index b3cbb0861113..f938d2a16c90 100644 --- a/tutorials/intermediate/tight_layout_guide.py +++ b/tutorials/intermediate/tight_layout_guide.py @@ -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):