0

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. when choose 'case 1' when choose 'case 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?

1 Answer 1

1

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))
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.