8000 FigureCanvas.draw() with tight_layout () needs to be called twice with Matplotlib 2.1.0 · Issue #10361 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

Skip to content
FigureCanvas.draw() with tight_layout () needs to be called twice with Matplotlib 2.1.0 #10361
Closed
@chipmuenk

Description

@chipmuenk

Bug report

Bug summary
PyQt widgets with a Matplotlib (versions 2.1.0 and 2.1.2) canvas don't respect tight_layout() unless a redraw is triggered for the second time. The class shown below (excerpt) is instantiated in all plotting widgets in the app under https://github.com/chipmuenk/pyfda .

The full code can be found under
https://github.com/chipmuenk/pyFDA/blob/develop/pyfda/plot_widgets/mpl_widget.py

In the pyfda project, the bug is referenced as chipmuenk/pyfda#113 .

Code for reproduction

from matplotlib.figure import Figure
# the other imports are from PyQt4 / PyQt5 via a compatibility wrapper
class MplWidget(QWidget):
    """
    Construct a subwidget from pyQt Matplotlib canvas and a modified NavigationToolbar.
    """
    def __init__(self, parent):
        super(MplWidget, self).__init__(parent)
        self.fig = Figure()

        self.pltCanv = FigureCanvas(self.fig)
        self.pltCanv.setSizePolicy(QSizePolicy.Expanding,
                                   QSizePolicy.Expanding)
        self.pltCanv.setFocusPolicy(QtCore.Qt.ClickFocus)
        self.pltCanv.setFocus()
        self.pltCanv.updateGeometry()
        self.mplToolbar = MplToolbar(self.pltCanv, self) # customized toolbar

        #=============================================
        # Main plot widget layout
        #=============================================
        self.layVMainMpl = QVBoxLayout()
        self.layVMainMpl.addWidget(self.mplToolbar)
        self.layVMainMpl.addWidget(self.pltCanv)
        self.setLayout(self.layVMainMpl)
        
    def redraw(self):
        """
        Redraw the figure with new properties (grid, linewidth etc.)
        """
        # only execute when at least one axis exists -> tight_layout crashes otherwise
        if self.fig.axes:
            for ax in self.fig.axes:
                if self.mplToolbar.lock_zoom:
                    ax.axis(self.limits) # restore old limits
                else:
                    self.limits = ax.axis() # save limits
            try:
                # tight_layout() crashes with small figure sizes e.g. when upper
                # and lower limits are swapped
               self.fig.tight_layout(pad = 0.1)
            except(ValueError, np.linalg.linalg.LinAlgError):
                pass

            self.pltCanv.draw() # now (re-)draw the figure

Actual outcome
The plot is surrounded by a lot of whitespace

Expected outcome
The plot should be formatted with a tight_layout() layout. This was the case with matplotlib 1.4.2, 1.5.2, 1.5.4 and 2.0

Matplotlib version

  • Operating system: Win 7, Linux 32 and 64 bit
  • Matplotlib version: 2.1.0, 2.1.2
  • Matplotlib backend: Qt4Agg and Qt5Agg
  • Python version: 2.7, 3.5, 3.6
  • Jupyter version (if applicable): ---
  • Other libraries:

Installation via conda (default channel)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0