Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Added savefig.bbox option to matplotlibrc #1004

Merged
merged 6 commits into from

3 participants

@oxling

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

@oxling oxling 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):
validate_movie_frame_fmt = ValidateInStrings('animation.frame_format',
['png', 'jpeg', 'tiff', 'raw', 'rgba'])
+def validate_bbox(s):
+ if type(s) is str:
+ s = s.lower()
+ if s in ('tight'):
+ return s
+ if s in ('auto'):
@pelson Collaborator
pelson added a note

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
@pelson Collaborator
pelson added a note

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

if s == 'auto'
@oxling
oxling added a note

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
@WeatherGod
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.

@oxling

@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.

@oxling

Whitespace change here

lib/matplotlib/backend_bases.py
@@ -2012,6 +2014,9 @@ def print_figure(self, filename, dpi=None, facecolor='w', edgecolor='w',
self.figure.set_edgecolor(edgecolor)
bbox_inches = kwargs.pop("bbox_inches", None)
+ if bbox_inches == None:
@WeatherGod Collaborator

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',
bbox_inches = Bbox.union([bbox_inches, bbox_inches1])
+ pad = kwargs.pop("pad_inches", None)
+ if pad == None:
@WeatherGod Collaborator

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

@oxling
oxling added a note

Thanks, fixed in 88b3661

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

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

@oxling

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.

@WeatherGod
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.

@oxling

OK. Changed to 'standard.'

@WeatherGod
Collaborator

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

@oxling
@WeatherGod
Collaborator

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

@WeatherGod
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!

@oxling

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

@WeatherGod

Move this line to be below your addition.

Fixed

@WeatherGod
Collaborator

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

@WeatherGod WeatherGod merged commit 561d0da into matplotlib:master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jul 10, 2012
  1. @oxling

    Added savefig.bbox option to matplotlibrc

    oxling authored
    Allows the user to set the bounding box to 'tight,' which will override the defaults when saving from the interface.
Commits on Jul 13, 2012
  1. @oxling
  2. @oxling

    Changed "== None" to "is None"

    oxling authored
  3. @oxling
Commits on Jul 23, 2012
  1. @oxling
  2. @oxling
This page is out of date. Refresh to see the latest.
View
8 doc/users/whats_new.rst
@@ -57,6 +57,14 @@ minimum and maximum colorbar extensions.
plt.show()
+
+Set default bounding box in matplotlibrc
+------------------------------------------
+
+Two new defaults are available in the matplotlibrc configuration file.
+These are savefig.bbox, which can be set to 'standard' or 'tight,' and
+savefig.pad_inches, which controls the bounding box padding.
+
.. _whats-new-1-1:
new in matplotlib-1.1
View
13 lib/matplotlib/backend_bases.py
@@ -230,6 +230,7 @@ def draw_quad_mesh(self, gc, master_transform, meshWidth, meshHeight,
:meth:`draw_quad_mesh` that generates paths and then calls
:meth:`draw_path_collection`.
"""
+
from matplotlib.collections import QuadMesh
paths = QuadMesh.convert_mesh_to_paths(
meshWidth, meshHeight, coordinates)
@@ -1977,11 +1978,11 @@ def print_figure(self, filename, dpi=None, facecolor='w', edgecolor='w',
*bbox_inches*
Bbox in inches. Only the given portion of the figure is
saved. If 'tight', try to figure out the tight bbox of
- the figure.
+ the figure. If None, use savefig.bbox
*pad_inches*
Amount of padding around the figure when bbox_inches is
- 'tight'.
+ 'tight'. If None, use savefig.pad_inches
*bbox_extra_artists*
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',
if dpi is None:
dpi = rcParams['savefig.dpi']
+
origDPI = self.figure.dpi
origfacecolor = self.figure.get_facecolor()
origedgecolor = self.figure.get_edgecolor()
@@ -2012,6 +2014,9 @@ def print_figure(self, filename, dpi=None, facecolor='w', edgecolor='w',
self.figure.set_edgecolor(edgecolor)
bbox_inches = kwargs.pop("bbox_inches", None)
+ if bbox_inches is None:
+ bbox_inches = rcParams['savefig.bbox']
+
if bbox_inches:
# call adjust_bbox to save only the given area
@@ -2052,8 +2057,10 @@ def print_figure(self, filename, dpi=None, facecolor='w', edgecolor='w',
bbox_inches = Bbox.union([bbox_inches, bbox_inches1])
+ pad = kwargs.pop("pad_inches", None)
+ if pad is None:
+ pad = rcParams['savefig.pad_inches']
- pad = kwargs.pop("pad_inches", 0.1)
bbox_inches = bbox_inches.padded(pad)
restore_bbox = tight_bbox.adjust_bbox(self.figure, format,
View
12 lib/matplotlib/rcsetup.py
@@ -325,6 +325,16 @@ def validate_hinting(s):
validate_movie_frame_fmt = ValidateInStrings('animation.frame_format',
['png', 'jpeg', 'tiff', 'raw', 'rgba'])
+def validate_bbox(s):
+ if type(s) is str:
+ s = s.lower()
+ if s == 'tight':
+ return s
+ if s == 'standard':
+ return None
+ raise ValueError("bbox should be 'tight' or 'standard'")
+
+
class ValidateInterval:
"""
@@ -549,6 +559,8 @@ def __call__(self, s):
'savefig.orientation' : ['portrait', validate_orientation], # edgecolor; white
'savefig.extension' : ['png', deprecate_savefig_extension], # what to add to extensionless filenames
'savefig.format' : ['png', str], # value checked by backend at runtime
+ 'savefig.bbox' : [None, validate_bbox], # options are 'tight', or 'standard'. 'standard' validates to None.
+ 'savefig.pad_inches' : [0.1, validate_float],
'tk.window_focus' : [False, validate_bool], # Maintain shell focus for TkAgg
'tk.pythoninspect' : [False, validate_tkpythoninspect], # obsolete
View
10 matplotlibrc.template
@@ -346,10 +346,12 @@ text.hinting_factor : 8 # Specifies the amount of softness for hinting in the
# the default savefig params can be different from the display params
# Eg, you may want a higher resolution, or to make the figure
# background white
-#savefig.dpi : 100 # figure dots per inch
-#savefig.facecolor : white # figure facecolor when saving
-#savefig.edgecolor : white # figure edgecolor when saving
-#savefig.format : png # png, ps, pdf, svg
+#savefig.dpi : 100 # figure dots per inch
+#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'.
+#savefig.pad_inches : 0.1 # Padding to be used when bbox is set to 'tight'
# tk backend params
#tk.window_focus : False # Maintain shell focus for TkAgg
Something went wrong with that request. Please try again.