MatPlotlib внутри PyQt5 QML - PullRequest
       30

MatPlotlib внутри PyQt5 QML

0 голосов
/ 12 февраля 2020

Я должен использовать MatPlotlib в моем проекте. Однако мне нужно спроектировать приложение QML в PyQt5, и, как я понимаю, графики matplotlib - это виджеты. Итак, мне нужно использовать графики Matplotlib внутри QML.

Мой вопрос таков: есть ли способ отобразить интерактивный сюжет matplotlib в QML? (Под интерактивным я подразумеваю не просто фигуру, которая была сохранена как изображение, в идеале со стандартной панелью инструментов для увеличения и пр. c.)

В здесь , он спрашивал раньше, но это не ответил Кто-нибудь может мне помочь?

1 Ответ

0 голосов
/ 13 февраля 2020

Если вы можете жить с виджетами, это не так сильно отличается от PyQT4. Этот ответ очень вдохновлен этой веткой .

PyQT5-совместимый код:

import sys, random

from PyQt5.QtWidgets import (
    QMainWindow,
    QApplication,
    QWidget,
    QVBoxLayout,
    QPushButton,
    QHBoxLayout,
)

import matplotlib
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure


class AppForm(QMainWindow):
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)

        # The main_frame keeps all widgets on itself
        self.main_frame = QWidget()

        # Create the interactive matplotlib  figure
        self.fig = Figure((10.0, 16.0), dpi=100)

        # Create figure canvas that gets a reference to self.fig
        # in its __init__
        self.canvas = FigureCanvas(self.fig)
        self.ax = self.fig.add_subplot(111)

        # Create the matplotlib navigation toolbar
        self.mpl_toolbar = NavigationToolbar(self.canvas, self.main_frame)

        # VBox (V for vertical) where the canvas is placed above the toolbar
        plotVbox = QVBoxLayout()
        plotVbox.addWidget(self.canvas)
        plotVbox.addWidget(self.mpl_toolbar)

        # Another VBox with a button, could eventually hold more
        # vertically ordered buttons
        controls = QVBoxLayout()
        self.button = QPushButton("Refresh")
        self.button.clicked.connect(self.refresh)
        controls.addWidget(self.button)

        # HBox (h for horizontal) where the
        # controls VBox with buttons is on the left
        # and the VBox with the plot is on the riht
        hbox = QHBoxLayout()
        hbox.addLayout(controls)
        hbox.addLayout(plotVbox)

        self.main_frame.setLayout(hbox)
        self.setCentralWidget(self.main_frame)

    def refresh(self):
        """
        Here, the functionality of the 'Refresh' button is implemented.
        Note that we do not return anything, instead we modify the state 
        of the AppForm instance.
        """
        self.ax.clear()
        x = [random.random() for i in range(10)]
        y = [random.random() for i in range(10)]
        self.ax.plot(x, y, "o")
        self.canvas.draw()


def main():
    """
    Open the main window.
    """
    app = QApplication(sys.argv)
    form = AppForm()
    form.show()
    app.exec_()


if __name__ == "__main__":
    main()
...