Repository navigation
Closed
Milestone
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)
Metadata
Metadata
Assignees
Labels
No labels
Activity
jklymak commentedon Feb 1, 2018
I have some guesses as to whats wrong, but a link to a self contained example (if its too long to post here) would help.
Have you tried
self.fig = Figure(tight_layout=True)That should call tight layout whenever draw is called.If you don't call
tight_layoutdoes the white space dramatically decrease in size? Possibly when tight_layout is called the first time its working with a layout that has been made on a virtual canvas that is much smaller than the canvas ends up being.chipmuenk commentedon Feb 2, 2018
Sorry for not providing a self-contained example, I haven't found the time yet to carve out a MWE from my code containing a matplotlib-widget and some dummy code. In the meantime - if you don't mind the trouble (don't hit me!) - pyfda can be installed/deinstalled easily via
pip install pyfdaorconda install -c Chipmuenk pyfda...I've tried your suggestions:
tight_layout()leaves the same (to my eye, not counting pixels) amount of white space with matplotlib 1.5 and 2.1Figure(tight_layout=True), but it shows exactly the same behaviour as callingtight_layout()manually for both mpl 1.5 and 2.1 in my case. However, now I can't catch the exceptions occurring when a user tries to shrink the window to a very small size, e.g.raise LinAlgError("Singular matrix")py.linalg.linalg.LinAlgError: Singular matrixThe problem seems to be around for a while though: https://stackoverflow.com/questions/18678306/matplotlib-qt-tight-layout-doesnt-work-on-the-first-draw#18702991
The proposed measure didn't help in my case though.
chipmuenk commentedon Apr 19, 2018
Dynamically updating the plots only when the tab has been made visible fixes this bug as well.
jklymak commentedon Feb 9, 2019
I'm closing this, unless there is a MWE for us to see what the problem is. Thanks!