Skip to content

fig.savefig alters the dimensions of the figure #10560

Closed
@taiya

Description

@taiya

Bug report

Bug summary
fig.savefig(...) changes the size of the figure it is trying to save to file
minor note: problem doesn't occur when size_figure_inches<=5

Code for reproduction

import numpy as np
import matplotlib
import matplotlib.pyplot as plt

FORCE_RESIZE_WINDOW = False

class Figure:
  size_figure_inches = 10.0 #< size of full figure
  size_world_half = 5 #< 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)
    self.cla()

  def cla(self):
    if FORCE_RESIZE_WINDOW:
      sfi = self.size_figure_inches
      self.fig.set_size_inches(sfi, sfi)
      self.fig.set_dpi(100)

    # --- clear axis (resets limits)
    plt.cla()
    # --- set limits
    swh = self.size_world_half
    self.ax.set_ylim(-swh, +swh)
    self.ax.set_xlim(-swh, +swh)

    #--- setup grid
    self.ax.set_xticks(range(-swh, +swh))
    self.ax.set_yticks(range(-swh, +swh))
    self.ax.grid(color='k')
    self.ax.grid(True)

  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()

print("backend: ", matplotlib.get_backend() )

fig = Figure(1)
offs = np.arange(-1, +1, .25)
for i, off in enumerate(offs):
  fig.cla()
  fig.plot2(M_restpose)
  fig.fig.savefig("./test%d.png" % i)
  plt.pause(.1)
  print("Figure size for test%d " % i, fig.fig.get_size_inches())

Actual outcome

backend:  TkAgg
Figure size for test0  [10.    9.66]
Figure size for test1  [10.    9.32]
Figure size for test2  [10.    8.98]
Figure size for test3  [10.    8.64]
Figure size for test4  [10.   8.3]
Figure size for test5  [10.    7.96]
Figure size for test6  [10.    7.62]
Figure size for test7  [10.    7.28]

Below the images generated by test0 and test7
test0
test7

Expected outcome

Image size should not change.
Result can be achieved by setting FORCE_RESIZE_WINDOW=True in the code above.
The terminal output is then:

backend:  TkAgg
Figure size for test0  [10.    9.66]
Figure size for test1  [10.    9.66]
Figure size for test2  [10.    9.66]
Figure size for test3  [10.    9.66]
Figure size for test4  [10.    9.66]
Figure size for test5  [10.    9.66]
Figure size for test6  [10.    9.66]
Figure size for test7  [10.    9.66]

While the script reports 9.66in in height, note the outputted files are correctly 1000x1000 as shown below:
test0
test7

Matplotlib version

  • Operating system: debian
  • Matplotlib version: 2.1.2 (installed w/ pip)
  • Matplotlib backend (print(matplotlib.get_backend())): TkAgg
  • Python version: 3.5
  • Jupyter version (if applicable): N/A
  • Other libraries:

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions