Skip to content

blocking UI functions cause figure size to change  #10566

Closed

Description

@taiya

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:

Activity

  1. changed the title [-]blocking UI functions cause image size to change [/-] [+]blocking UI functions cause figure size to change [/+] on Feb 22, 2018
  2. tacaswell commented on Feb 23, 2018

    @tacaswell
    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?

  3. added this to the v2.2.0 milestone on Feb 23, 2018
  4. taiya commented on Feb 26, 2018

    @taiya
    Author

    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

  5. modified the milestones: v2.2.0, v2.2.1 on Feb 26, 2018
  6. modified the milestones: v2.2.1, on Mar 12, 2018
  7. modified the milestones: v3.0, v3.1 on Aug 11, 2018
  8. modified the milestones: v3.1.0, v3.2.0 on Mar 18, 2019
  9. added a commit that references this issue on Mar 27, 2020
    1b82a96
  10. modified the milestones: needs sorting, v3.2.2 on Mar 27, 2020
  11. added 3 commits that reference this issue on Mar 31, 2020
    cc3a77d
    205e73f
    da078ca
  12. added a commit that references this issue on Apr 6, 2020
    deadb3d
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions