-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Resize canvas when changing figure size #15045
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
What is the mechanism by which this breaks? It is also possible that this "just works" on master, @anntzer recently put in some PRs to tweak how we handle the window sizing. |
See the example in #15040, which shows how it breaks, even on master. |
I mean, why does setting the size twice confuse it? |
Currently the resize code in def resize(self, width, height):
# these are Qt methods so they return sizes in 'virtual' pixels
# so we do not need to worry about dpi scaling here.
extra_width = self.window.width() - self.canvas.width()
extra_height = self.window.height() - self.canvas.height()
self.window.resize(width + extra_width, height + extra_height) After one resize the window gets resized, but the canvas doesn't. This means when it comes to the second resize, My guess as to why it works fine in the usual case with one resize and a draw is because at draw time the canvas is automatically resized to fit the window. |
I've just pushed a test that fails without the change in this PR. |
I'm not totally convinced this is the correct fix? For example, perhaps set_size_inches should be the one doing the canvas resize, e.g. with
otherwise, I would guess the other backends also need updating:
which appear to all suffer from the same issue? (FigureManagerMac doesn't even seem to define resize()?) |
Yes, I think you're right that
|
Is there a way to parameterize the test with different backends? |
Not sure. You can always generate the functions dynamically in a for loop. I think something like this should work:
|
They basically need to run in different subprocesses (because a given process can only ever use a single interactive backend) -- see tests_backends_interactive.py. (Probably stashing all the tests in a single process invocation, as is done right now, is better for performance.) |
With #14703 merged do we still need this? |
Can take a look soon-ish, but I think it's worth putting the test in even if it does pass on current master. |
Yep, this fix is still needed even with #14703 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think, this code breaks the resizing.
window = fig.canvas.manager.window | ||
|
||
fig.set_size_inches(2, 2) | ||
old_width = window.width() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my test of this code, the example window is always 640x480 no matter what I pass to set_size_inches
. Maybe explicitly test for 200 here (or rcParams['figure.dpi'] * 2
if you want to be very explicit).
I've changed my mind and think that it's reasonable for the backend I've also added an explict check for figure width as @timhoffm suggests. |
When the figure size is resized, as well as the window being manually resized the canvas needs to be resized too. Usually the canvas is resized automatically to the window at draw time, but this handles the case where the figure size is changed more than once before drawing (ie. #15040).
This might not be the right thing to do though, maybe others know better?
Fixes #15040