everyone! I want to embed my data into Gui. Here I created 2 Plot button so that I showed my data one by one.Plot1 contained 2 subplot, Plot2 contained 1 plot.

But when I clicked Plot1 and then clicked Plot2, I can't see my data in Plot2, It looks like coordinate doesn't change. How should I fix this?

import matplotlib.pyplot as plt
import numpy as np 
import sys
from PyQt4 import QtGui
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar


class PrettyWidget(QtGui.QWidget):


    def __init__(self):
        super(PrettyWidget, self).__init__()
        self.initUI()


    def initUI(self):

        self.setGeometry(100,100,800,600)
        self.center()
        self.setWindowTitle('S Plot')

        grid = QtGui.QGridLayout()
        self.setLayout(grid)

        btn1 = QtGui.QPushButton('Plot 1 ',self)
        btn1.resize(btn1.sizeHint())
        btn1.clicked.connect(self.plot1)
        grid.addWidget(btn1,5,0)

        btn2 = QtGui.QPushButton('Plot 2 ',self)
        btn2.resize(btn2.sizeHint())
        btn2.clicked.connect(self.plot2)
        grid.addWidget(btn2,5,1)

        self.figure = plt.figure(figsize = (15,5))
        self.canvas = FigureCanvas(self.figure)
        self.toolbar = NavigationToolbar(self.canvas, self)
        grid.addWidget(self.canvas, 3,0,1,2)
        grid.addWidget(self.canvas, 3,0,1,2)

        self.show()

    def plot1(self):
        plt.cla()
        ax1 = self.figure.add_subplot(211)
        x1 = [i for i in range(100)]
        y1 = [i**0.5 for i in x1]
        ax1.plot(x1,y1,'b.-')

        ax2 = self.figure.add_subplot(212)
        x2 = [i for i in range(100)]
        y2 = [i for i in x2]
        ax2.plot(x2,y2,'b.-')
        self.canvas.draw()

    def plot2(self):
        plt.cla()
        ax3 = self.figure.add_subplot(111)
        x = [i for i in range(100)]
        y = [i**0.5 for i in x]
        ax3.plot(x,y,'r.-')
        ax3.set_title('Square Root Plot')
        self.canvas.draw()    

    def center(self):
        qr = self.frameGeometry()
        cp = QtGui.QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

app = QtGui.QApplication(sys.argv)
app.aboutToQuit.connect(app.deleteLater)
GUI = PrettyWidget()
sys.exit(app.exec_())
up vote 1 down vote accepted

I strongly advise against using pyplot whe doing embedding, the global state management and the FigureManager classes will get in your way.

import sys
from PyQt4 import QtGui
import matplotlib
import matplotlib.figure
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar


class PrettyWidget(QtGui.QWidget):
    def __init__(self):
        super(PrettyWidget, self).__init__()
        self.initUI()

    def initUI(self):

        self.setGeometry(100, 100, 800, 600)
        self.center()
        self.setWindowTitle('S Plot')

        grid = QtGui.QGridLayout()
        self.setLayout(grid)

        btn1 = QtGui.QPushButton('Plot 1 ', self)
        btn1.resize(btn1.sizeHint())
        btn1.clicked.connect(self.plot1)
        grid.addWidget(btn1, 5, 0)

        btn2 = QtGui.QPushButton('Plot 2 ', self)
        btn2.resize(btn2.sizeHint())
        btn2.clicked.connect(self.plot2)
        grid.addWidget(btn2, 5, 1)

        self.figure = matplotlib.figure.Figure()
        self.canvas = FigureCanvas(self.figure)
        self.toolbar = NavigationToolbar(self.canvas, self)
        grid.addWidget(self.canvas, 3, 0, 1, 2)
        # grid.addWidget(self.toolbar, ??)

        self.show()

    def plot1(self):
        self.figure.clf()
        ax1 = self.figure.add_subplot(211)
        x1 = [i for i in range(100)]
        y1 = [i**0.5 for i in x1]
        ax1.plot(x1, y1, 'b.-')

        ax2 = self.figure.add_subplot(212)
        x2 = [i for i in range(100)]
        y2 = [i for i in x2]
        ax2.plot(x2, y2, 'b.-')
        self.canvas.draw_idle()

    def plot2(self):
        self.figure.clf()
        ax3 = self.figure.add_subplot(111)
        x = [i for i in range(100)]
        y = [i**0.5 for i in x]
        ax3.plot(x, y, 'r.-')
        ax3.set_title('Square Root Plot')
        self.canvas.draw_idle()

    def center(self):
        qr = self.frameGeometry()
        cp = QtGui.QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

app = QtGui.QApplication(sys.argv)
app.aboutToQuit.connect(app.deleteLater)
GUI = PrettyWidget()
sys.exit(app.exec_())
  • That's what I want! Thanks for your generous help. – radiosan Mar 19 '16 at 6:32
  • What is difference between pyplot and matplotlib.figure you used? And self.canvas.draw_idle() is... – radiosan Mar 19 '16 at 7:40
  • 1
    draw_idle is a deferred draw (it asks Qt to schedule a paint which will in turn call draw which runs the Agg rasterization). If you call draw multiple times between paint events the figure will be rasterized (but never shown) which is a waste of CPU. Using draw_idle you only spend the CPU to render the image when you need to – tacaswell Mar 19 '16 at 14:49