You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
savefig() saves different aspect ratio than show() #3139
The following script (using matplotlib 1.3.1) should create a 1-row, 3 column subplot with only one panel. The figure is displayed with show (which looks as desired) and also saved as a pdf using savefig. However, savefig has squeezed the wide figure into the normal aspect ratio, which it should not do.
Somehow the call to setGeometry is not realized by matplotlib. My only workaround right now is to first set the position and size with setGeometry and then to set the size again with set_size_inches like so
f=gcf()
f.set_size_inches(800./f.dpi,200./f.dpi)
This works fine, but I still need the call to setGeometry because I want to specify where on the screen the figure appears.
dpi: [ None | scalar > 0 ]
The resolution in dots per inch. If None it will default to the value savefig.dpi in the matplotlibrc file.
Which essentially is saying, savefig ignores figure.dpi and instead uses the global rc param. I don't like it (I have a reputation for not liking much when it comes to rcParams) but it is documented so I'm going to go ahead and close the issue. It might be worth sparking a discussion on the mailing list about the behaviour if we want to change it, though the breakage that it may cause might make that a hard sell.
@tacaswell is correct, this is not a question of dpi at all.
If the example is run using ipython --pylab=qt, then it works for me on 1.3.1. Or, even without the --pylab, using a call to ion() is enough. When the figure is rendered on the screen, the geometry does change the output of fig.get_size_inches(), and savefig uses the modified dimensions.
It's not clear that there is anything we should change here.
I would also add that fig.set_size_inches(forward=True) will resize the figure on-screen as well. Another alternative is to set the figure size when you create the figure ex
fig, ax = plt.subplots(1, 3, figsize=(3, 6))
I think that this should be closed as the problem is the OP doing and end-run around the mpl gui management layer but there are already ways for the management layer to push back down to the gui.
There is also a call-back already in place (I only tested Qt) that updates the figure size in inches if you resize the window with the mouse. Interestingly, if you run this as a script, it does not work, but if you run the same commands in ipython (with their matplotlib magic), the change in size does propagate back up. This smells like another case of gui/interactive stuff barely working out side of ipython/interactive session.
Activity
efiring commentedon Jun 16, 2014
Does it do what you intend if you insert
plt.draw()before the savefig?a6073758 commentedon Jun 16, 2014
Tried it - didn't help.
Somehow the call to
setGeometryis not realized bymatplotlib. My only workaround right now is to first set the position and size withsetGeometryand then to set the size again withset_size_incheslike soThis works fine, but I still need the call to
setGeometrybecause I want to specify where on the screen the figure appears.Tillsten commentedon Jun 16, 2014
Could you try calling the
repaintmethod()?a6073758 commentedon Jun 17, 2014
where do I find that
repaintmethod?pelson commentedon Jun 17, 2014
This is a documented "feature" of savefig: http://matplotlib.org/api/figure_api.html#matplotlib.figure.Figure.savefig
Which essentially is saying, savefig ignores
figure.dpiand instead uses the global rc param. I don't like it (I have a reputation for not liking much when it comes to rcParams) but it is documented so I'm going to go ahead and close the issue. It might be worth sparking a discussion on the mailing list about the behaviour if we want to change it, though the breakage that it may cause might make that a hard sell.Thanks for raising the issue @a6073758.
tacaswell commentedon Jun 17, 2014
@pelson not sure I agree. I think the problem is the use of the qt geometry calls which rdint get propagate back to mpl from the gui layer.
efiring commentedon Jun 17, 2014
@tacaswell is correct, this is not a question of dpi at all.
If the example is run using
ipython --pylab=qt, then it works for me on 1.3.1. Or, even without the--pylab, using a call toion()is enough. When the figure is rendered on the screen, the geometry does change the output offig.get_size_inches(), andsavefiguses the modified dimensions.It's not clear that there is anything we should change here.
pelson commentedon Jun 18, 2014
My apologies.
tacaswell commentedon Jun 25, 2014
I would also add that
fig.set_size_inches(forward=True)will resize the figure on-screen as well. Another alternative is to set the figure size when you create the figure exI think that this should be closed as the problem is the OP doing and end-run around the mpl gui management layer but there are already ways for the management layer to push back down to the gui.
There is also a call-back already in place (I only tested Qt) that updates the figure size in inches if you resize the window with the mouse. Interestingly, if you run this as a script, it does not work, but if you run the same commands in ipython (with their matplotlib magic), the change in size does propagate back up. This smells like another case of gui/interactive stuff barely working out side of ipython/interactive session.
solarjoe commentedon Jan 18, 2016
I also came across this issue, but for a much simpler case.
The workaround plt.draw() suggested by @efiring worked for me.
Also is calling the Axes method ax.apply_aspect()
I am pretty sure that this issue it related to #1104,
maybe some callback function is not triggered correctly.
nikosT commentedon Nov 1, 2017
Any solution to this?
jklymak commentedon Nov 1, 2017
@nikosT Its a closed issue. Were you arguing it should be re-opened for some reason?
BugCheck141 commentedon Apr 23, 2020
found it: call fig.tight_layout() before plt.savefig
maybe plt.show triggers it automatically but savefig does not