Search code examples
pythonmatplotlibpyqt4

How to embed matplotlib in pyqt


I want to embed a graph in a pyqt4 user interface. I do not understand how people did the embedding in the examples I found - this one (at the bottom) and that one.

Could anyone post a step-by-step explanation or at least a very small, very simple code only creating e.g. a graph and a button in one pyqt4 GUI.


Solution

  • It is not that complicated actually. Relevant Qt widgets are in matplotlib.backends.backend_qt4agg. FigureCanvasQTAgg and NavigationToolbar2QT are usually what you need. These are regular Qt widgets. You treat them as any other widget. Below is a very simple example with a Figure, Navigation and a single button that draws some random data. I've added comments to explain things.

    import sys
    from PyQt4 import QtGui
    
    from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
    from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar
    from matplotlib.figure import Figure
    
    import random
    
    class Window(QtGui.QDialog):
        def __init__(self, parent=None):
            super(Window, self).__init__(parent)
    
            # a figure instance to plot on
            self.figure = Figure()
    
            # this is the Canvas Widget that displays the `figure`
            # it takes the `figure` instance as a parameter to __init__
            self.canvas = FigureCanvas(self.figure)
    
            # this is the Navigation widget
            # it takes the Canvas widget and a parent
            self.toolbar = NavigationToolbar(self.canvas, self)
    
            # Just some button connected to `plot` method
            self.button = QtGui.QPushButton('Plot')
            self.button.clicked.connect(self.plot)
    
            # set the layout
            layout = QtGui.QVBoxLayout()
            layout.addWidget(self.toolbar)
            layout.addWidget(self.canvas)
            layout.addWidget(self.button)
            self.setLayout(layout)
    
        def plot(self):
            ''' plot some random stuff '''
            # random data
            data = [random.random() for i in range(10)]
    
            # create an axis
            ax = self.figure.add_subplot(111)
    
            # discards the old graph
            ax.clear()
    
            # plot data
            ax.plot(data, '*-')
    
            # refresh canvas
            self.canvas.draw()
    
    if __name__ == '__main__':
        app = QtGui.QApplication(sys.argv)
    
        main = Window()
        main.show()
    
        sys.exit(app.exec_())
    

    Edit:

    Updated to reflect comments and API changes.

    • NavigationToolbar2QTAgg changed with NavigationToolbar2QT
    • Directly import Figure instead of pyplot
    • Replace deprecated ax.hold(False) with ax.clear()