Skip to content
This repository

Added savefig.bbox option to matplotlibrc #1004

Merged
merged 6 commits into from over 1 year ago

3 participants

Amy Benjamin Root Phil Elson
Amy
oxling commented July 10, 2012

This is from wishlist issue #988. It allows the user to default the bounding box to 'tight.'

Amy Added savefig.bbox option to matplotlibrc
Allows the user to set the bounding box to 'tight,' which will override the defaults when saving from the interface.
4047815
lib/matplotlib/rcsetup.py
@@ -325,6 +325,16 @@ def validate_hinting(s):
325 325
 validate_movie_frame_fmt = ValidateInStrings('animation.frame_format',
326 326
     ['png', 'jpeg', 'tiff', 'raw', 'rgba'])
327 327
 
  328
+def validate_bbox(s):
  329
+    if type(s) is str:
  330
+        s = s.lower()
  331
+    if s in ('tight'):
  332
+        return s
  333
+    if s in ('auto'):
3
Phil Elson Collaborator
pelson added a note July 12, 2012

I don't think this line does as you intended:

>>> 'a' in ('hello world')
False
>>> 'hello' in ('hello world')
True
>>> 'w' in ('hello world')
True

Adding a trailing comma to turn the thing into a tuple was probably your intention:

>>> 'w' in ('hello world', )
False
>>> 'hello world' in ('hello world', )
True
Phil Elson Collaborator
pelson added a note July 12, 2012

But really, you may as well just use string equality:

if s == 'auto'
Amy
oxling added a note July 13, 2012

Thanks for the correction, I'll use string equality.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Benjamin Root
Collaborator

The current behavior for the savefig function is to save the visible canvas area if "bbox_inches" was not given or was None. This does not change with the new code. However, there is a slight symantical collision here, as it is a general rule that passing None for a kwarg value means "perform the default behavior", which, in turn, typically means, use the rc default. So, if I set "bbox_inches" to "tight", and pass bbox_inches=None to the savefig kwargs, I get a different result than intended. (Note, this is not a new problem. It has been a growing issue with kwarg handling that really needs to be addressed throughout matplotlib).

I also don't like "auto", because there is nothing automatic about it. In other words, when no bbox is specified, it just uses the existing bbox of the figure. Of course this is a minor quible, and I am probably being too pedantic.

Next, having "auto" as a possible value for bbox_inches implies that one could use "auto" for input to savefig(). This might actually be a good thing in that it might help address my first point.

Finally, there are other kwargs that get activated when bbox_inches is "tight". Adding "pad_inches" should be trivial, but I don't see how we could implement bbox_extra_artists. I guess we would just have to do without bbox_extra_artists, but pad_inches should definitely be included.

Amy
oxling commented July 13, 2012

@WeatherGod OK, I made most of your suggested changes. I changed 'auto' to 'default,' added savefig.pad_inches, and changed the behavior so that passing 'None' will use the value set in the defaults.

Amy

Whitespace change here

lib/matplotlib/backend_bases.py
@@ -2012,6 +2014,9 @@ def print_figure(self, filename, dpi=None, facecolor='w', edgecolor='w',
2012 2014
         self.figure.set_edgecolor(edgecolor)
2013 2015
 
2014 2016
         bbox_inches = kwargs.pop("bbox_inches", None)
  2017
+        if bbox_inches == None:
1
Benjamin Root Collaborator
WeatherGod added a note July 13, 2012

Don't use '==' when testing for None. Always use "is" and "is not".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/matplotlib/backend_bases.py
@@ -2052,8 +2057,10 @@ def print_figure(self, filename, dpi=None, facecolor='w', edgecolor='w',
2052 2057
 
2053 2058
                     bbox_inches = Bbox.union([bbox_inches, bbox_inches1])
2054 2059
 
  2060
+                pad = kwargs.pop("pad_inches", None)
  2061
+                if pad == None:
2
Benjamin Root Collaborator
WeatherGod added a note July 13, 2012

use "is". Never use '==' for testing for None.

Amy
oxling added a note July 13, 2012

Thanks, fixed in 88b3661

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Benjamin Root
Collaborator

I dislike "default" even more than "auto" because which default does it refer to? How about "standard", "keep" or maybe "unchanged"?

Amy
oxling commented July 13, 2012

How about just passing in None instead? That's what the savefig() function expects anyways, and it seems to keep with the same style of passing True or False in the defaults file.

Benjamin Root
Collaborator

I would rather avoid clouding the distinction between "None" and None. We already have enough problems as is with that. We already do have None's in the rc file, but those mean the string "None" which is entirely different from the python None. In the rc file, we can not distinguish between the two since everything comes in as strings.

Amy
oxling commented July 13, 2012

OK. Changed to 'standard.'

Benjamin Root
Collaborator

ok, remind me if there were anything left holding up this PR? I think all my qualms have been addressed.

Amy
oxling commented July 18, 2012
Benjamin Root
Collaborator

Oh, right, can you please add a note to docs/users/whats_new.rst?

Benjamin Root
Collaborator

Be sure to ping me when you make that last change so I can go ahead and merge this in. Thanks for your work!

Amy
oxling commented July 23, 2012

OK, done. Let me me know if I didn't get the formatting in that file right.

Benjamin Root

Move this line to be below your addition.

Fixed

Benjamin Root
Collaborator

Ok, looks good to me. Merging it in now. Thanks!

Benjamin Root WeatherGod merged commit 561d0da into from July 23, 2012
Benjamin Root WeatherGod closed this July 23, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
8  doc/users/whats_new.rst
Source Rendered
@@ -57,6 +57,14 @@ minimum and maximum colorbar extensions.
57 57
 
58 58
     plt.show()
59 59
 
  60
+
  61
+Set default bounding box in matplotlibrc
  62
+------------------------------------------
  63
+
  64
+Two new defaults are available in the matplotlibrc configuration file.
  65
+These are savefig.bbox, which can be set to 'standard' or 'tight,' and 
  66
+savefig.pad_inches, which controls the bounding box padding.
  67
+
60 68
 .. _whats-new-1-1:
61 69
 
62 70
 new in matplotlib-1.1
13  lib/matplotlib/backend_bases.py
@@ -230,6 +230,7 @@ def draw_quad_mesh(self, gc, master_transform, meshWidth, meshHeight,
230 230
         :meth:`draw_quad_mesh` that generates paths and then calls
231 231
         :meth:`draw_path_collection`.
232 232
         """
  233
+
233 234
         from matplotlib.collections import QuadMesh
234 235
         paths = QuadMesh.convert_mesh_to_paths(
235 236
             meshWidth, meshHeight, coordinates)
@@ -1977,11 +1978,11 @@ def print_figure(self, filename, dpi=None, facecolor='w', edgecolor='w',
1977 1978
         *bbox_inches*
1978 1979
             Bbox in inches. Only the given portion of the figure is
1979 1980
             saved. If 'tight', try to figure out the tight bbox of
1980  
-            the figure.
  1981
+            the figure. If None, use savefig.bbox
1981 1982
 
1982 1983
         *pad_inches*
1983 1984
             Amount of padding around the figure when bbox_inches is
1984  
-            'tight'.
  1985
+            'tight'. If None, use savefig.pad_inches
1985 1986
 
1986 1987
         *bbox_extra_artists*
1987 1988
             A list of extra artists that will be considered when the
@@ -2003,6 +2004,7 @@ def print_figure(self, filename, dpi=None, facecolor='w', edgecolor='w',
2003 2004
         if dpi is None:
2004 2005
             dpi = rcParams['savefig.dpi']
2005 2006
 
  2007
+
2006 2008
         origDPI = self.figure.dpi
2007 2009
         origfacecolor = self.figure.get_facecolor()
2008 2010
         origedgecolor = self.figure.get_edgecolor()
@@ -2012,6 +2014,9 @@ def print_figure(self, filename, dpi=None, facecolor='w', edgecolor='w',
2012 2014
         self.figure.set_edgecolor(edgecolor)
2013 2015
 
2014 2016
         bbox_inches = kwargs.pop("bbox_inches", None)
  2017
+        if bbox_inches is None:
  2018
+            bbox_inches = rcParams['savefig.bbox']
  2019
+
2015 2020
 
2016 2021
         if bbox_inches:
2017 2022
             # call adjust_bbox to save only the given area
@@ -2052,8 +2057,10 @@ def print_figure(self, filename, dpi=None, facecolor='w', edgecolor='w',
2052 2057
 
2053 2058
                     bbox_inches = Bbox.union([bbox_inches, bbox_inches1])
2054 2059
 
  2060
+                pad = kwargs.pop("pad_inches", None)
  2061
+                if pad is None:
  2062
+                    pad = rcParams['savefig.pad_inches']
2055 2063
 
2056  
-                pad = kwargs.pop("pad_inches", 0.1)
2057 2064
                 bbox_inches = bbox_inches.padded(pad)
2058 2065
 
2059 2066
             restore_bbox = tight_bbox.adjust_bbox(self.figure, format,
12  lib/matplotlib/rcsetup.py
@@ -325,6 +325,16 @@ def validate_hinting(s):
325 325
 validate_movie_frame_fmt = ValidateInStrings('animation.frame_format',
326 326
     ['png', 'jpeg', 'tiff', 'raw', 'rgba'])
327 327
 
  328
+def validate_bbox(s):
  329
+    if type(s) is str:
  330
+        s = s.lower()
  331
+        if s == 'tight':
  332
+            return s
  333
+        if s == 'standard':
  334
+            return None
  335
+        raise ValueError("bbox should be 'tight' or 'standard'")
  336
+
  337
+
328 338
 
329 339
 class ValidateInterval:
330 340
     """
@@ -549,6 +559,8 @@ def __call__(self, s):
549 559
     'savefig.orientation' : ['portrait', validate_orientation],  # edgecolor; white
550 560
     'savefig.extension'   : ['png', deprecate_savefig_extension], # what to add to extensionless filenames
551 561
     'savefig.format'      : ['png', str], # value checked by backend at runtime
  562
+    'savefig.bbox'        : [None, validate_bbox], # options are 'tight', or 'standard'. 'standard' validates to None.
  563
+    'savefig.pad_inches'  : [0.1, validate_float],
552 564
 
553 565
     'tk.window_focus'    : [False, validate_bool],  # Maintain shell focus for TkAgg
554 566
     'tk.pythoninspect'   : [False, validate_tkpythoninspect],  # obsolete
10  matplotlibrc.template
@@ -346,10 +346,12 @@ text.hinting_factor : 8 # Specifies the amount of softness for hinting in the
346 346
 # the default savefig params can be different from the display params
347 347
 # Eg, you may want a higher resolution, or to make the figure
348 348
 # background white
349  
-#savefig.dpi       : 100      # figure dots per inch
350  
-#savefig.facecolor : white    # figure facecolor when saving
351  
-#savefig.edgecolor : white    # figure edgecolor when saving
352  
-#savefig.format    : png      # png, ps, pdf, svg
  349
+#savefig.dpi        : 100      # figure dots per inch
  350
+#savefig.facecolor  : white    # figure facecolor when saving
  351
+#savefig.edgecolor  : white    # figure edgecolor when saving
  352
+#savefig.format     : png      # png, ps, pdf, svg
  353
+#savefig.bbox       : standard # 'tight' or 'standard'.
  354
+#savefig.pad_inches : 0.1      # Padding to be used when bbox is set to 'tight'
353 355
 
354 356
 # tk backend params
355 357
 #tk.window_focus   : False    # Maintain shell focus for TkAgg
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.