Thanks to visit codestin.com
Credit goes to github.com

Skip to content

blocking UI functions cause figure size to change #10566

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

Closed
taiya opened this issue Feb 22, 2018 · 2 comments · Fixed by #16929
Closed

blocking UI functions cause figure size to change #10566

taiya opened this issue Feb 22, 2018 · 2 comments · Fixed by #16929
Labels
Milestone

Comments

@taiya
Copy link

taiya commented Feb 22, 2018

Bug report

Bug summary
when the GUI blocks (either via plt.pause(...) or plt.show(block=True)) the size of the figure changes, and when it is saved to file the dimensions are mismatched to the ones set by set_size_inches(..)

Code for reproduction

import imageio
import numpy as np

FORCE_IMAGE_RESIZE_ON_PAUSE = False

# Switch backends
import matplotlib
if False:
  matplotlib.use("Qt5Agg")
else:
  matplotlib.use("TkAgg")

import matplotlib.pyplot as plt

import matplotlib
from sys import platform, version
print("backend     ", matplotlib.get_backend() )
print("matplotlib  ", matplotlib.__version__)
print("python      ", version.split(" ")[0])
print("OS          ", platform)


class Figure:
  size_figure_inches = 8.0 #< size of full figure
  size_world_half = 2 #< size of world (centered 0)

  def __init__(self, fid):
    self.fig = plt.figure(fid)
    self.canvas = self.fig.canvas

    #--- specify figure
    sfi = self.size_figure_inches
    self.fig.set_size_inches(sfi, sfi)
    self.fig.set_dpi(100)

    # --- specify axis
    self.ax = self.fig.add_axes([0, 0, 1, 1])  # < (full image)

  # TODO bug https://github.com/matplotlib/matplotlib/issues/10566
  def pause(self, time):
    plt.pause(time)
    if FORCE_IMAGE_RESIZE_ON_PAUSE:
      sfi = self.size_figure_inches
      self.fig.set_size_inches(sfi, sfi)

  def plot2(self, P):
    x = P[:, 0]
    y = P[:, 1]
    self.ax.plot(x, y)

#------------------------------------------------------------------------------------------

t = np.arange(0.0, 2.0, 0.01)
s = 1 + np.sin(2*np.pi*t)
x = np.cos(2*np.pi*t)
y = np.sin(2*np.pi*t)
M_restpose = np.vstack([x,y]).transpose()

fig = Figure(1)
offs = np.arange(-1, +1, 1)
for i, off in enumerate(offs):
  print("(1) Figure size for test%d " % i, fig.fig.get_size_inches())
  fig.ax.cla()
  print("(2) Figure size for test%d " % i, fig.fig.get_size_inches())
  fig.plot2(M_restpose)
  print("(3) Figure size for test%d " % i, fig.fig.get_size_inches())
  fig.fig.savefig("./test%d.png" % i)
  print("    Png size:", imageio.imread("./test%d.png"%i).shape)
  print("(4) Figure size for test%d " % i, fig.fig.get_size_inches())
  fig.pause(1)
  print("(5) Figure size for test%d " % i, fig.fig.get_size_inches())
  print("\n")

Actual outcome

backend      TkAgg
matplotlib   2.2.0rc1
python       3.5.3
OS           linux
(1) Figure size for test0  [8. 8.]
(2) Figure size for test0  [8. 8.]
(3) Figure size for test0  [8. 8.]
    Png size: (800, 800, 4)
(4) Figure size for test0  [8. 8.]
(5) Figure size for test0  [8.   7.66]

(1) Figure size for test1  [8.   7.66]
(2) Figure size for test1  [8.   7.66]
(3) Figure size for test1  [8.   7.66]
    Png size: (766, 800, 4)
(4) Figure size for test1  [8.   7.66]
(5) Figure size for test1  [8.   7.66]

note: using Qt5 as backend doesn't cause problem:

backend      Qt5Agg
matplotlib   2.2.0rc1
python       3.5.3
OS           linux
(1) Figure size for test0  [8. 8.]
(2) Figure size for test0  [8. 8.]
(3) Figure size for test0  [8. 8.]
    Png size: (800, 800, 4)
(4) Figure size for test0  [8. 8.]
(5) Figure size for test0  [8. 8.]


(1) Figure size for test1  [8. 8.]
(2) Figure size for test1  [8. 8.]
(3) Figure size for test1  [8. 8.]
    Png size: (800, 800, 4)
(4) Figure size for test1  [8. 8.]
(5) Figure size for test1  [8. 8.]

note: replacing plt.pause(.1) with plt.show(block=False) gives:

backend:  TkAgg
(1) Figure size for test0  [8. 8.]
(2) Figure size for test0  [8. 8.]
(3) Figure size for test0  [8. 8.]
    Png size: (800, 800, 4)
(4) Figure size for test0  [8. 8.]
(5) Figure size for test0  [8. 8.]


(1) Figure size for test1  [8. 8.]
(2) Figure size for test1  [8. 8.]
(3) Figure size for test1  [8. 8.]
    Png size: (800, 800, 4)
(4) Figure size for test1  [8. 8.]
(5) Figure size for test1  [8. 8.]

Image size should not change.
Matplotlib version

  • Operating system: debian
  • Matplotlib version: 2.2.0rc1 (installed w/ pip)
  • Matplotlib backend (print(matplotlib.get_backend())): TkAgg
  • Python version: 3.5
  • Jupyter version (if applicable): N/A
  • Other libraries:
@taiya taiya changed the title blocking UI functions cause image size to change blocking UI functions cause figure size to change Feb 22, 2018
@tacaswell
Copy link
Member

The issue is that when the window is drawn to the screen we are not making the tk window big enough to fit the figure + the toolbar and the figure is getting slightly shrunk. Do you see this with Qt or Wx?

@tacaswell tacaswell added this to the v2.2.0 milestone Feb 23, 2018
@taiya
Copy link
Author

taiya commented Feb 26, 2018

Hi @tacaswell indeed it does not seem to be a problem with Qt5.
I have updated the code example + output with a backend switcher in the original issue

@tacaswell tacaswell modified the milestones: v2.2.0, v2.2.1 Feb 26, 2018
@jklymak jklymak modified the milestones: v2.2.1, v3.0 Mar 12, 2018
@tacaswell tacaswell modified the milestones: v3.0, v3.1 Aug 11, 2018
@tacaswell tacaswell modified the milestones: v3.1.0, v3.2.0 Mar 18, 2019
@tacaswell tacaswell modified the milestones: v3.2.0, needs sorting Sep 10, 2019
QuLogic added a commit to QuLogic/matplotlib that referenced this issue Mar 27, 2020
Resizing the figure directly does not account for the toolbar, so
figures are actually a little shorter than they should be. The recent
change to `Text.get_window_extent` some how causes this to actually get
reflected in the Matplotlib figure size, which cycles back to Tk and
shrinks the window. However, this can be triggered by other calls to
`Figure.set_size_inches` as noted in the fixed issues.

Fixes matplotlib#10083.
Fixes matplotlib#10566.
Fixes matplotlib#16926.
@QuLogic QuLogic modified the milestones: needs sorting, v3.2.2 Mar 27, 2020
QuLogic added a commit to QuLogic/matplotlib that referenced this issue Mar 31, 2020
Previously, it was the window that was resized to the intended size,
thus making the canvas smaller by the toolbar height.

Fixes matplotlib#10083 for GTK3.
Fixes matplotlib#10566 for GTK3.
@QuLogic QuLogic mentioned this issue Mar 31, 2020
2 tasks
QuLogic added a commit to QuLogic/matplotlib that referenced this issue Mar 31, 2020
Previously, it was the window that was resized to the intended size,
thus making the canvas smaller by the toolbar height.

Fixes matplotlib#10083 for GTK3.
Fixes matplotlib#10566 for GTK3.
QuLogic added a commit to QuLogic/matplotlib that referenced this issue Mar 31, 2020
Previously, it was the window that was resized to the intended size,
thus making the canvas smaller by the toolbar height.

Fixes matplotlib#10083 for GTK3.
Fixes matplotlib#10566 for GTK3.
toddrjen pushed a commit to toddrjen/matplotlib that referenced this issue Apr 6, 2020
Resizing the figure directly does not account for the toolbar, so
figures are actually a little shorter than they should be. The recent
change to `Text.get_window_extent` some how causes this to actually get
reflected in the Matplotlib figure size, which cycles back to Tk and
shrinks the window. However, this can be triggered by other calls to
`Figure.set_size_inches` as noted in the fixed issues.

Fixes matplotlib#10083.
Fixes matplotlib#10566.
Fixes matplotlib#16926.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants