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