简体   繁体   中英

Problems on embedding matplotlib in PyQt4

Here is the code:

from matplotlib.backends.qt_compat import QtCore, QtGui
from matplotlib.backends.backend_qt4agg import (FigureCanvasQTAgg as FigureCanvas)
from matplotlib.figure import Figure
import sys

class MyCanvas(FigureCanvas):
    def __init__(self, parent=None, key="case 1"):

        self.case_dict = {"case 1": [2, 4, 6, 8, 10],
                        "case 2": [3, 4, 5, 6, 7]}

        self.key = key

        self.fig = Figure()
        self.axes = self.fig.add_subplot(111)

        self.compute_initial_figure()

        FigureCanvas.__init__(self, self.fig)
        self.setParent(parent)

        FigureCanvas.updateGeometry(self)

    def compute_initial_figure(self):
        x = [1, 2, 3, 4, 5]
        y = self.case_dict[self.key]
        self.axes.set_title("%s" % self.key)
        self.axes.scatter(x, y)

class MainWindow(QtGui.QWidget):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        self.canvas_widget = MyCanvas()

        self.combo = QtGui.QComboBox()
        for key in MyCanvas().case_dict:
            self.combo.addItem(key)
            self.combo.setCurrentIndex(-1)

        self.combo.currentIndexChanged.connect(self.showPlot)

        layout = QtGui.QVBoxLayout(self)
        layout.addWidget(self.canvas_widget)
        layout.addWidget(self.combo)

    def showPlot(self):
        key_name = self.combo.currentText()
        self.canvas_widget = MyCanvas(key=unicode(key_name))

qApp = QtGui.QApplication(sys.argv)

aw = MainWindow()
aw.show()
sys.exit(qApp.exec_())

I want the figure to be refreshed when the Item in QComboBox is changed. But now, nothing happens. 选择“案例1”时 当选择“案例2”时

I am a beginner of Python and just don't know how to solve this problem. So, what should I do to connect the QComboBox with the figures generated by matplotlib?

With the instruction self.canvas_widget = MyCanvas(key=unicode(key_name)) you are creating a new widget that does not have a parent so it is not shown, besides it is advisable not to create a new widget since it is a memory expense unnecessary, what you must reuse the widget for it I wrote the setKey method that internally call the compute_initial_figure method that is responsible for redrawing reusing the scatter.

from matplotlib.backends.qt_compat import QtCore, QtGui
from matplotlib.backends.backend_qt4agg import (FigureCanvasQTAgg as FigureCanvas)
from matplotlib.figure import Figure
import sys

class MyCanvas(FigureCanvas):
    def __init__(self, parent=None, key="case 1"):

        self.case_dict = {"case 1": [2, 4, 6, 8, 10],
                        "case 2": [3, 4, 5, 6, 7]}
        self.key = key
        self.fig = Figure()
        self.axes = self.fig.add_subplot(111)
        FigureCanvas.__init__(self, self.fig)
        self.setParent(parent)
        FigureCanvas.updateGeometry(self)

        self.sc = None
        self.compute_initial_figure()

    def setKey(self, key):
        self.key = key
        self.compute_initial_figure()

    def compute_initial_figure(self):
        x = [1, 2, 3, 4, 5]
        y = self.case_dict[self.key]
        self.axes.set_title("%s" % self.key)
        if self.sc is None:
            self.sc = self.axes.scatter(x, y)
        else:
            import numpy as np
            data = np.stack((np.asarray(x), np.asarray(y)), axis=1)
            self.sc.set_offsets(data)
            self.draw()


class MainWindow(QtGui.QWidget):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        self.canvas_widget = MyCanvas()

        self.combo = QtGui.QComboBox()
        for key in MyCanvas().case_dict:
            self.combo.addItem(key)
            self.combo.setCurrentIndex(-1)

        self.combo.currentIndexChanged.connect(self.showPlot)

        layout = QtGui.QVBoxLayout(self)
        layout.addWidget(self.canvas_widget)
        layout.addWidget(self.combo)

    def showPlot(self):
        key_name = self.combo.currentText()
        self.canvas_widget.setKey(unicode(key_name))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM