Repository navigation
Description
In the discussion of this post: #3139 I found the following quote by @efiring :
When the figure is rendered on the screen, the geometry does change the output of
fig.get_size_inches(), andsavefiguses the modified dimensions. It's not clear that there is anything we should change here.
So here's an example where I explicitely set a certain figure size using rcParams:
import pandas as pd
import matplotlib as mp
import matplotlib.pyplot as mpp
import numpy as np
dpi = 200
mp.rcParams[u'figure.dpi'] = dpi
mp.rcParams[u'figure.figsize'] = (8.,12.)
mp.rcParams[u'savefig.dpi'] = dpi
df = pd.DataFrame({'A':np.random.rand(20),'B':np.random.rand(20)})
fig, axes = mpp.subplots(1,1)
axes.scatter(y=df.A, x=df.B)
print fig.get_size_inches()
fig.savefig("C:\\DataDir\\Output\\Test1.png")
print fig.get_size_inches()
fig.show()
print fig.get_size_inches()
fig.savefig("C:\\DataDir\\Output\\Test2.png")
print fig.get_size_inches()
mp.rcdefaults()
print statements output:
[ 8. 12.]
[ 8. 12.]
[ 8. 4.77]
[ 8. 4.77]
For my use-case having show() silently alter the figure size is unwanted behaviour, I'm expecting the figure size to only change when I'm explicitely changing it myself.
I can see how there are use-cases where this behaviour is expected, so I'm not saying to get rid of it, rather give the user a choice in some way, either by setting a global parameter, by telling savefig() to use rcParams[u'figure.figsize'] instead of fig.get_size_inches() when saving the figure, or however else this could be implemented nicely.
Invoking
fig.set_figwidth(mp.rcParams[u'figure.figsize'][0])
fig.set_figheight(mp.rcParams[u'figure.figsize'][1])
everytime after doing show() isn't a handy solution in any way.
Activity
efiring commentedon Oct 24, 2016
I think the best solution would be to have scrollbars appear when the screen window is not large enough to hold the figure at the specified size and dpi. The only problem is that this requires major work on all GUI backends, and we are short of developer time and expertise for this. Maybe it would be OK to start with a subset of the backends.
[-]Feature Request: Ability to keep original figure size after invoking show()[/-][+]Add scrollbars when needed to preserve specified figure size[/+]efiring commentedon Jan 7, 2017
@Khris777 I hope you don't mind my having changed your title; I think it will make it easier to find and track the issue.
Khris777 commentedon Jan 9, 2017
@efiring
No problem, thanks for adding this to the milestone.
jklymak commentedon Jan 18, 2018
This is a bit of an inconsistency in Qt5Agg, where its not giving the requested window size because it won't fit. If you do this in
MacOSxit just gives you a big window thats bigger than the screen. I think this is what Qt5Agg should do as well.I'm moving to 3.0 because I don't see this getting fixed in next month.
efiring commentedon Jan 18, 2018
On my machine with the macosx backend, it makes a window the size of the screen, not the specified size. And it cuts off the bottom a little bit (I think) because it is pushed down by the main menu bar.
Qt has a QScrollArea, but I don't understand the backend code well enough to have any idea of what would be required to use it.
The only alternative to scrollbars that I can imagine would be an option to automatically scale the dpi to make the window fit.
jklymak commentedon Jan 18, 2018
Really? I did:
and got (where my menubar is off the bottom of the screen):
anntzer commentedon Jan 18, 2018
I agree that using a scrollarea instead of resizing would be better. I can probably have a look at the Qt situation at some point...
efiring commentedon Jan 18, 2018
@jklymak, I simply did "pythonw
which ipython--pylab=osx" and thenand observed that the figure width exactly equals the screen width and I don't see the bottom of the the figure. I can wiggle the figure back and forth laterally, showing that its width does match the screen, but I couldn't move it higher to find out where the bottom is. All of this was the same if I used (20, 15), and it is on a 15" retina laptop.
9 remaining items
anntzer commentedon Jun 6, 2023
On Qt looks like the following gives a minimal working version:
(of course you need to hide that behind a switch based on an rcparam to decide which behavior to use).
Note that effectively there's another canvas size that needs to be defined (with all the bookkeeping associated -- here I just hardcoded the minimumSizeHint), which is the size below which scrollbars appear (the other choice would be to have an absolutely fixed canvas size and have it not increase in size if the window is made larger). @efiring Perhaps you can chime in on the exact desired behavior.
efiring commentedon Jun 6, 2023
The goal is to always render the figure at the specified figsize in inches based on the specified dpi, regardless of the size of the window. So for any window, if it is not large enough, the scrollbars would appear. The current behavior of enlarging the window as needed, up to the max that will fit the screen, could be kept; the difference would be that when in the current version the figsize would be reduced to keep the window size within the screen, in the new version the figsize would stay the same and scrollbars would allow one to view any part of the figure.
jklymak commentedon Jun 6, 2023
@efiring I'm a little confused by this as the "goal". Is there a toggle for this, because folks resize their figures manually all the time by resizing the window? If this didn't have to happen, layout would be a lot easier.
efiring commentedon Jun 6, 2023
Yes, I imagine the behavior I describe would have to be an optional alternative; preferably with an rcParam for the default, and an easy toggle. In many--perhaps most--cases the current behavior is what people will want. The use case for the alternative, with scrollbars, is for working with a figure that is to be printed or published. It ensures that the layout you get on the screen is what you will get in the pdf. Without this, one has to reduce the specified display dpi in order to get a larger figure (in terms of figsize in inches) to fit in a window that fits on the screen.
The most extreme version of the alternative, simplifying the implementation, would be to always have the scrollbars when they are toggled on. The two modes would be "adaptive figsize" (no scrollbars, current behavior) and "fixed figsize".
timhoffm commentedon Jun 6, 2023
I'd prefer either completely fixed (=exact pixels) or freely scaling up/down. A mixture is rather confusing.
anntzer commentedon Jun 6, 2023
In the proposed patch this can be achieved by removing the scrollarea.setWidgetResizable(True) line (and possibly additionally giving the whole window a FixedSize sizePolicy).
efiring commentedon Jun 6, 2023
Perhaps my proposal is not yet clear; I don't understand what "mixture" you are referring to. Have 2 modes:
The big change in 2 is that the window size becomes uncoupled from the figure size, apart from the initial default that matches them when possible.
anntzer commentedon Jun 6, 2023
I think this is essentially what I describe at
?
efiring commentedon Jun 6, 2023
Agreed. Does it make anything substantially simpler if the scrollbars are always provided, needed or not? Having them appear only when needed is a minor refinement not a requirement.
timhoffm commentedon Jun 7, 2023
Automatic hiding of unneeded scrollbars is typically a GUI framework feature that we should get for free (I know that for sure for Qt, but suppose it's similar for the others as well).
Not sure whether it's the same thing, but my approach would be: The Canvas widget can have two different modes: Fixed size based on the contained figure or resizable. - At least in Qt terms, we should be able to embed that in a QScrollArea and the layout mechanism should be able to do everyting else: For the fixed sizes, the ScrollArea handles the missing/excess space. For the scaling case, I think the ScrollArea can report its viewport to the Canvas, which then can size accordingly (but t.b.c.).
github-actions commentedon Jun 7, 2024
This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!
efiring commentedon Jun 8, 2024
This is still a valid feature request.