Skip to content

fig.savefig alters the dimensions of the figure #10560

@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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions