Использование контрольных кнопок matplotlib в PyQT5 - PullRequest
1 голос
/ 16 июня 2020

Можно ли использовать контрольные кнопки matplotlib в графике, встроенном в PyQT5? Код ниже, график работает, и он встроен в окно PyQT, но контрольные кнопки не добавляют и не удаляют серию, как должны. Код отлично работает при извлечении из PyQT.

import numpy as np
import sys
from matplotlib.widgets import CheckButtons
from PyQt5.QtWidgets import QDialog, QApplication, QPushButton, QVBoxLayout
from PyQt5 import QtCore
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
import matplotlib.pyplot as plt


class Window(QDialog):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)

        self.figure = plt.figure()
        t = np.arange(0.0, 2.0, 0.01)
        s0 = np.sin(2*np.pi*t)
        s1 = np.sin(4*np.pi*t)
        s2 = np.sin(6*np.pi*t)

        self.figure, ax = plt.subplots()
        l0, = ax.plot(t, s0, visible=False, lw=2, color='k', label='2 Hz')
        l1, = ax.plot(t, s1, lw=2, color='r', label='4 Hz')
        l2, = ax.plot(t, s2, lw=2, color='g', label='6 Hz')
        plt.subplots_adjust(left=0.2)

        self.lines = [l0, l1, l2]

        # Make checkbuttons with all plotted lines with correct visibility
        rax = plt.axes([0.05, 0.4, 0.1, 0.15])
        self.labels = [str(line.get_label()) for line in self.lines]
        visibility = [line.get_visible() for line in self.lines]
        check = CheckButtons(rax, self.labels, visibility)
        check.on_clicked(self.b)
##        print('showing')
##        plt.show()


        self.canvas = FigureCanvas(self.figure)
        layout = QVBoxLayout()
##        layout.addWidget(self.toolbar)
        layout.addWidget(self.canvas)
        # layout.addWidget(self.button)
        self.setLayout(layout)

        self.canvas.draw()
##        print('done')
##        plt.show()

    def b(self,label):
        index = self.labels.index(label)
        self.lines[index].set_visible(not self.lines[index].get_visible())
        plt.draw()

if __name__ == '__main__':
    app = QApplication(sys.argv)

    main = Window()
    main.show()

    sys.exit(app.exec_())

1 Ответ

2 голосов
/ 16 июня 2020

Если вы собираетесь использовать matplotlib с Qt, вам следует использовать не pyplot, а рисунок, установленный на холсте. Также "check" должен быть членом класса.

Учитывая вышеизложенное, решение:

from PyQt5.QtWidgets import QApplication, QDialog, QVBoxLayout

import numpy as np
from matplotlib.backends.backend_qt5agg import FigureCanvas
from matplotlib.figure import Figure
from matplotlib.widgets import CheckButtons


class Window(QDialog):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)

        self.canvas = FigureCanvas(Figure(figsize=(5, 3)))

        t = np.arange(0.0, 2.0, 0.01)
        s0 = np.sin(2 * np.pi * t)
        s1 = np.sin(4 * np.pi * t)
        s2 = np.sin(6 * np.pi * t)

        ax = self.canvas.figure.subplots()
        (l0,) = ax.plot(t, s0, visible=False, lw=2, color="k", label="2 Hz")
        (l1,) = ax.plot(t, s1, lw=2, color="r", label="4 Hz")
        (l2,) = ax.plot(t, s2, lw=2, color="g", label="6 Hz")

        self.canvas.figure.subplots_adjust(left=0.2)

        self.lines = [l0, l1, l2]

        rax = self.canvas.figure.add_axes([0.05, 0.4, 0.1, 0.15])

        self.labels = [str(line.get_label()) for line in self.lines]
        visibility = [line.get_visible() for line in self.lines]

        self.check = CheckButtons(rax, self.labels, visibility)
        self.check.on_clicked(self.on_clicked)

        lay = QVBoxLayout(self)
        lay.addWidget(self.canvas)

        self.resize(640, 480)

    def on_clicked(self, label):
        index = self.labels.index(label)
        self.lines[index].set_visible(not self.lines[index].get_visible())
        self.canvas.draw()


def main():
    import sys

    app = QApplication(sys.argv)

    main = Window()
    main.show()

    sys.exit(app.exec_())


if __name__ == "__main__":
    main()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...