Skip to content

Qt4Agg backend changes figure size #9913

Closed

Description

@ImportanceOfBeingErnest

Edit: Note that this issue is also still present with Qt5Agg and matplotlib 3.0.1

Showing a figure with Qt4Agg backend changes the figure size. This is observed with Windows 8.1, python 2.7, matplotlib 2.1.

import matplotlib
matplotlib.use("Qt4Agg")
import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.plot([1,2,4])

def update(evt):
    print(fig.get_size_inches())
       
cid = fig.canvas.mpl_connect("key_press_event", update)

print(fig.get_size_inches())
plt.show()

The original figure is [ 6.4 4.8]. After the figure is drawn (and in this case you press a key), it is only [ 6.4 4.78].
One could argue that this is only a small amount, but saving the figure from within the event loop now gives a different figure size of the saved figure. To make this more obvious, consider the following code which saves a new image after each press of space.

import matplotlib
matplotlib.use("Qt4Agg")
import matplotlib.pyplot as plt
import numpy as np

class NextPlotter(object):
    def __init__(self, fig, func, n):
        self.__dict__.update(locals())
        self.i = 0
        self.cid = self.fig.canvas.mpl_connect("key_press_event", self.adv)
        
    def adv(self, evt):
        if evt.key == " " and self.i < self.n:
            self.func(self.i)
            self.i+=1
        elif self.i >= self.n:
            plt.close("all")

# Create data
pos = range(8)
scatterdata = np.random.normal(0, 5, size=(50,len(pos)))

#Create plot
fig, ax = plt.subplots()
ax.axis([-10,10,-10,10])
scatter = ax.scatter([], [], c="crimson", s=60)

# define updating function
def update(i):
    print("++ update " + str(i))
    scatter.set_offsets(np.c_[pos,scatterdata[i,:]])
    fig.canvas.draw()
    print(fig.get_size_inches())
    plt.savefig("plot_{i}.png".format(i=i))
    print(fig.get_size_inches())

# instantiate NextPlotter; press <space> to advance to the next image        
c = NextPlotter(fig, update, len(scatterdata))

plt.show()

resulting in
nextplotter_qtagg3

Is this a problem of PyQt4? Can anyone reproduce this outside of Windows 8?

Activity

  1. afvincent commented on Dec 2, 2017

    @afvincent
    Contributor

    @ImportanceOfBeingErnest Thanks for the neat illustrations of the issue :).

    I cannot reproduce this on Linux (Arch 4.13.12), with Python 2.7.11 (from conda) and Matplotlib 2.1.0 and master (from git), with the Qt5Agg and Qt4Agg backends. Would this suggest the problem to be a platform specific issue?

  2. ImportanceOfBeingErnest commented on Dec 2, 2017

    @ImportanceOfBeingErnest
    MemberAuthor

    I've done some further tests:

    • Windows 10, python 2.7, PyQt4 ("Qt4Agg"), matplotlib 2.1: The issue is completely the same. Figure is [ 6.4 4.78] and shrinks itself upon saving repeatedly.
    • Windows 8.1, python 2.7, PyQt4 ("Qt4Agg"), matplotlib 1.5.3: The first issue persists; the figure is smaller than expected [ 8. 5.975] instead of [8. 6.]. But it does not shrink itself continuously using the second code from above.
    • Windows 10, python 2.7, PyQt4 ("Qt4Agg"), matplotlib 1.5.3: exact same as with Windows 8 and mpl 1.5.3: Figure is smaller, but no continuous shrinking.

    So there are actually 2 issues here: The fact that the figure is smaller in PyQt window is present throughout matplotlib versions. The fact that it shrinks each time it is saved is an issue with matplotlib 2 compared to matplotlib 1.5.
    In any case it may be specific to Windows. (Unfortunately I can currently neither test with Linux, nor with PyQt5.)

  3. jklymak commented on Dec 2, 2017

    @jklymak
    Member

    Not an issue macOS python3, QT5 or macosx backends. (Sorry, can't test QT4 ;-). I've labelled as above...

  4. tacaswell commented on Dec 3, 2017

    @tacaswell
    Member

    There is a feedback loop in the GUI code that resizes the MPL-figure to fit into the window (ex if you drag the window bigger) and if you resize the figure from python the size is forwarded to the GUI (which then may slightly re-size the Figure to fit if there are rounding issues (ie, the requested size + dpi do not result in an integer number of pixels).

  5. modified the milestones: v2.1.1, on Dec 3, 2017
  6. bidhya commented on Jan 1, 2018

    @bidhya

    I am not exactly sure, but I just started noticing the figures that were normal size now shrinks in Jupyter Notebook. I run this command to set figure size
    %matplotlib inline import matplotlib.pyplot as plt plt.rcParams.update({'figure.figsize': (14, 6)})

    When I run this suite of code again, it seems to give the right sized figure as before. I am on Windows 10 with 32-bit Python 2.7 (Anaconda), and Matplotlib 2.1

  7. tacaswell commented on Jan 1, 2018

    @tacaswell
    Member

    @bidhya Issues with the inline backend are probably un-related to this issue.

  8. bidhya commented on Jan 1, 2018

    @bidhya

    Thank you @tacaswell . I think the problem could be related new Pandas 0.22.0 which I updated this morning. Started noticing this change in plot size with Pandas plot functions.

  9. kklmn commented on Feb 10, 2018

    @kklmn

    I confirm the bug exists, it is Windows- and Qt-backend specific.
    In Ubuntu 17.10 I don't have it with any backend and in Windows 10 with Tk backend I don't have it either.

    In both Windows 10 and Ubuntu 17.10 I have

    • PyQt5 5.10.0
    • mpl 2.1.2

    The problem is not directly related to Jupyter/Ipython. I typically run my scripts from Spyder (currently 3.2.6) in its IPython console, where I experience the problem. If I run a script from Spyder but in an external system terminal I do have the shrinkage with Qt5agg backend and don't have it with TkAgg.

    A workaround for me is to do
    fig.set_size_inches(size_inches)
    after each fig.savefig. The size I save at the creation time as
    size_inches = fig.get_size_inches()

  10. added a commit that references this issue on Feb 10, 2018
  11. anntzer commented on Feb 10, 2018

    @anntzer
    Contributor

    I think this may be effectively fixed (at least the repeated size changes upon savefig) by #10292?

  12. 7 remaining items

  13. added this to the v3.1 milestone on Nov 3, 2018
  14. added
    Release criticalFor bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions.
    and removed
    Release criticalFor bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions.
    on Feb 24, 2019
  15. modified the milestones: v3.1.0, v3.2.0 on Mar 18, 2019
  16. QuLogic commented on Mar 27, 2020

    @QuLogic
    Member

    Is this still a problem?

  17. ImportanceOfBeingErnest commented on Mar 27, 2020

    @ImportanceOfBeingErnest
    MemberAuthor

    While some of the tangential problems have been fixed in the meantime, the original problem is still present, that is, a figure that should be (6.4, 4.8) inches becomes (6.4, 4.78) inches when drawn with the QT backend on windows.

  18. QuLogic commented on Mar 28, 2020

    @QuLogic
    Member

    At 100 dpi, 4-8-4.78 == 22 pixels, which is the size of the statusbar. We only check the size hint for that, and then calculate a window size from it; I'd guess that if you check https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/backends/backend_qt5.py#L573 the sbs.height() would be 0.

  19. QuLogic commented on May 15, 2020

    @QuLogic
    Member

    The statusbar is removed in the default setup on master, so perhaps this is fixed now?

  20. QuLogic commented on Jun 3, 2021

    @QuLogic
    Member

    Either way, we no longer support Qt4.

  21. removed this from the future releases milestone on Oct 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions