3

I want to embed matplotlib plots in a PyQt5 UI -- with a dynamic count of subplots. Is there an efficient way to do this without constantly deleting and constructing new axes? Originally I thought using gridspec would be the right thing to do, but I couldn't find a way to update nrows/ncols, other than constructing a new gridspec object.

Example code:

import sys
from PyQt5 import QtWidgets
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas

class Plot(FigureCanvas):
    def __init__(self, parent=None, width=5.4, height=4, dpi=100):
        self.fig = Figure(figsize=(width, height), dpi=dpi)
        self.axes = [self.fig.add_subplot(211), self.fig.add_subplot(212)]
        self.fig.set_facecolor("none")
        self.fig.set_tight_layout(True)

        FigureCanvas.__init__(self, self.fig)
        self.setParent(parent)
        FigureCanvas.setSizePolicy(self, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)

    def update_subplot(self, count):
        [self.fig.delaxes(ax) for ax in self.axes]
        self.axes = [self.fig.add_subplot(count, 1, i+1) for i in range(count)]
        self.draw()

class PlotWidget(QtWidgets.QWidget):
    def __init__(self):
        super(PlotWidget, self).__init__()
        self.initPlot()
        self.initUI()

    def initPlot(self):
        self.plot = Plot()

    def initUI(self):
        self.setGeometry(100, 100, 800, 600)
        grid = QtWidgets.QGridLayout(self)
        grid.addWidget(self.plot, 3, 0, 1, 2)

        btn1 = QtWidgets.QPushButton('1 Subplot ', self)
        btn1.clicked.connect(lambda: self.plot.update_subplot(1))
        grid.addWidget(btn1, 5, 0)

        btn2 = QtWidgets.QPushButton('2 Subplots ', self)
        btn2.clicked.connect(lambda: self.plot.update_subplot(2))
        grid.addWidget(btn2, 5, 1)

        self.show()

app = QtWidgets.QApplication(sys.argv)
window = PlotWidget()
window.show()
sys.exit(app.exec_())
erocoar
  • 5,723
  • 3
  • 23
  • 45
  • 1
    Yes you can use two different gridspecs. Apart I'm not sure if I understand what the desired functionality is. – ImportanceOfBeingErnest Nov 30 '17 at 11:31
  • In my UI I have a plot window -- depending on some specified options, it needs to show 1, 2 or 3 graphs. Is it the best way then to initialize three gridspecs? – erocoar Nov 30 '17 at 11:35
  • 1
    As said I don't understand the desired functionality. Do you have 3 graphs and want to show one, two or all three at the same time? Or do you have different datasets and want to show dataset1 on 1 graph, dataset2 on two graphs etc.? – ImportanceOfBeingErnest Nov 30 '17 at 11:43
  • 1
    Independent of that, [this question](https://stackoverflow.com/questions/43937066/matplotlib-hide-subplot-and-fill-space-with-other-subplots) may point you towards a solution. We can mark as duplicate if it is the desired feature you're looking for. – ImportanceOfBeingErnest Nov 30 '17 at 11:50
  • Yes, data1, data2, data3 on separate subplots - but sometimes only data1 has to be shown. I think the question you refer to solves it :) Thanks! – erocoar Nov 30 '17 at 12:46
  • 1
    Ok, I have closed as duplicate. If you have a problem with the implementation, you can edit your question and notify me such that I can reopen it. – ImportanceOfBeingErnest Nov 30 '17 at 13:10

0 Answers0