Fix #4855: Blacklist rcParams that aren't style #5440

Merged
merged 6 commits into from Dec 31, 2015
@@ -0,0 +1,11 @@
+Style parameter blacklist
+-------------------------
+
+In order to prevent unexpected consequences from using a style, style
+files are no longer able to set parameters that affect things
+unrelated to style. These parameters include::
+
+ 'interactive', 'backend', 'backend.qt4', 'webagg.port',
+ 'webagg.port_retries', 'webagg.open_in_browser', 'backend_fallback',
+ 'toolbar', 'timezone', 'datapath', 'figure.max_open_warning',
+ 'savefig.directory', 'tk.window_focus', 'hardcopy.docstring'
@@ -278,9 +278,6 @@ figure.facecolor : 0.75 # figure facecolor; 0.75 is scalar gray
figure.edgecolor : w # figure edgecolor
figure.autolayout : False # When True, automatically adjust subplot
# parameters to make the plot fit the figure
-figure.max_open_warning : 20 # The maximum number of figures to open through
- # the pyplot interface before emitting a warning.
- # If less than one this feature is disabled.
figure.frameon : True
# The figure subplot parameters. All dimensions are a fraction of the
@@ -385,18 +382,13 @@ 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.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
savefig.frameon : True
savefig.orientation : portrait
nbagg.transparent: True
-# tk backend params
-tk.window_focus : False # Maintain shell focus for TkAgg
-
# ps backend params
ps.papersize : letter # auto, letter, legal, ledger, A0-A10, B0-B10
ps.useafm : False # use of afm fonts, results in small files
@@ -418,7 +410,7 @@ pdf.use14corefonts : False
pgf.debug : False
pgf.texsystem : xelatex
pgf.rcfonts : True
-pgf.preamble :
+pgf.preamble :
# svg backend params
svg.image_inline : True # write raster image data directly into the svg file
@@ -467,8 +459,6 @@ keymap.yscale : l # toggle scaling of y-axes ('log'/'linear')
keymap.xscale : k, L # toggle scaling of x-axes ('log'/'linear')
keymap.all_axes : a # enable all axes
-toolbar: toolbar2
-
###ANIMATION settings
animation.writer : ffmpeg # MovieWriter 'backend' to use
animation.codec : mpeg4 # Codec to use for writing movie
@@ -18,10 +18,11 @@
import os
import re
import contextlib
+import warnings
import matplotlib as mpl
from matplotlib import cbook
-from matplotlib import rc_params_from_file
+from matplotlib import rc_params_from_file, rcParamsDefault
__all__ = ['use', 'context', 'available', 'library', 'reload_library']
@@ -34,11 +35,35 @@
STYLE_FILE_PATTERN = re.compile('([\S]+).%s$' % STYLE_EXTENSION)
+# A list of rcParams that should not be applied from styles
+STYLE_BLACKLIST = set([
+ 'interactive', 'backend', 'backend.qt4', 'webagg.port',
+ 'webagg.port_retries', 'webagg.open_in_browser', 'backend_fallback',
+ 'toolbar', 'timezone', 'datapath', 'figure.max_open_warning',
+ 'savefig.directory', 'tk.window_focus', 'hardcopy.docstring'])
@WeatherGod

WeatherGod Nov 17, 2015

Member

what about the default keymappings?

@mdboom

mdboom Nov 17, 2015

Owner

In that case, I thought using style might be handy, e.g. an Emacs key style (not that one could do that given our current framework, but you get the idea).

+
+
+def _remove_blacklisted_style_params(d):
+ o = {}
+ for key, val in d.items():
+ if key in STYLE_BLACKLIST:
+ warnings.warn(
+ "Style includes a parameter, '{0}', that is not related to "
+ "style. Ignoring".format(key))
+ else:
+ o[key] = val
+ return o
+
+
def is_style_file(filename):
"""Return True if the filename looks like a style file."""
return STYLE_FILE_PATTERN.match(filename) is not None
+def _apply_style(d):
+ mpl.rcParams.update(_remove_blacklisted_style_params(d))
+
+
def use(style):
"""Use matplotlib style settings from a style specification.
@@ -71,18 +96,15 @@ def use(style):
for style in styles:
if not cbook.is_string_like(style):
- mpl.rcParams.update(style)
- continue
+ _apply_style(style)
elif style == 'default':
- mpl.rcdefaults()
- continue
-
- if style in library:
- mpl.rcParams.update(library[style])
+ _apply_style(rcParamsDefault)
+ elif style in library:
+ _apply_style(library[style])
else:
try:
rc = rc_params_from_file(style, use_default_template=False)
- mpl.rcParams.update(rc)
+ _apply_style(rc)
except IOError:
msg = ("'%s' not found in the style library and input is "
"not a valid URL or path. See `style.available` for "