3

This Python 3.13 script with Matplotlib 3.10.3 run on 1200x1600 display:

import matplotlib.pyplot as plt, numpy as np

fig, ax = plt.subplots()
plt.tight_layout(pad=0.01)
fig.canvas.manager.full_screen_toggle()
img = np.random.randint(5, size=(4, 3))

while True:
  ax.imshow(img)
  print(fig.get_size_inches(), *ax.get_xlim())
  plt.waitforbuttonpress()

initially outputs wrong dimensions [6.4 4.8] 0.0 1.0, but after a click anywhere on the figure

enter image description here

it outputs physically correct values [12. 15.58] -0.5 2.5. What is a way to get correct dimensions before the first click, i.e. at the first call to print(fig.get_size_inches(), *ax.get_xlim())? My goal is to get the number of display pixels per unit square of img, so if there is an alternative to ax.get_position().width*fig.get_size_inches()[0]*fig.dpi/(xMax-xMin), which doesn't suffer from this problem, I would like to know.


An ugly solution is to insert these lines before the loop:

ax.imshow(img)
plt.pause(0.1)  

Is there a better option?

4
  • Did you try fig.canvas.draw(), which is supposed to force layout computation without showing the figure? See also matplotlib's brief documentation. Commented Nov 18 at 9:03
  • @JohanC Yes, I tried with and without preceding ax.imshow(img) and it didn't work. Commented Nov 18 at 9:04
  • is that the most minimal example for which does the issue manifest? Commented Nov 18 at 15:33
  • @cards Depends on how you define minimal. You can reproduce it with a simple line plot, eliminating numpy dependence. Commented Nov 18 at 23:44

1 Answer 1

0

If I had to guess, I’d call plt.show(block=False) followed by plt.pause(0) before your first measurement.

This forces the GUI backend to finalize the window and apply fullscreen, so fig.get_size_inches() is correct immediately.

fig.canvas.manager.full_screen_toggle()

plt.show(block=False)

plt.pause(0)   # forces one GUI event cycle

The figure does not have its true on-screen size until the GUI event loop runs once. Fullscreen mode is only applied during that first event cycle. plt.pause(0) is the clean way to let the backend process pending events without adding delays, so the correct size is available at the first measurement.

(PS: All comments are appreciated, I’m new around here)

Sign up to request clarification or add additional context in comments.

4 Comments

After adding these lines, the script does not proceed to the while loop.
plt.pause(0.001) produces wrong dimensions, plt.pause(0.1) produces correct dimensions on my PC.
Out of interest, what about plt.pause(0.01)?
The same as plt.pause(0.001) - produces wrong dimensions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.