如何在pyqt中嵌入matplotlib - 用于傻瓜

ari*_*ari 72 python matplotlib pyqt4

我目前正在尝试在我设计的pyqt4用户界面中嵌入我想绘制的图形.因为我对编程几乎是全新的 - 我不知道人们如何在我发现的例子中嵌入 - 这个(在底部)那个.

如果任何人可以发布逐步解释或者至少是一个非常小的,非常简单的代码,只在一个pyqt4 GUI中创建例如图形和按钮,那将是非常棒的.

Ava*_*ris 103

实际上并不复杂.相关的Qt小部件都在matplotlib.backends.backend_qt4agg.FigureCanvasQTAggNavigationToolbar2QT通常你需要什么.这些是常规的Qt小部件.您将它们视为任何其他小部件.下面是一个非常简单的示例Figure,Navigation其中包含一个按钮,可以绘制一些随机数据.我添加了评论以解释事情.

import sys
from PyQt4 import QtGui

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

import random

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

        # a figure instance to plot on
        self.figure = Figure()

        # this is the Canvas Widget that displays the `figure`
        # it takes the `figure` instance as a parameter to __init__
        self.canvas = FigureCanvas(self.figure)

        # this is the Navigation widget
        # it takes the Canvas widget and a parent
        self.toolbar = NavigationToolbar(self.canvas, self)

        # Just some button connected to `plot` method
        self.button = QtGui.QPushButton('Plot')
        self.button.clicked.connect(self.plot)

        # set the layout
        layout = QtGui.QVBoxLayout()
        layout.addWidget(self.toolbar)
        layout.addWidget(self.canvas)
        layout.addWidget(self.button)
        self.setLayout(layout)

    def plot(self):
        ''' plot some random stuff '''
        # random data
        data = [random.random() for i in range(10)]

        # create an axis
        ax = self.figure.add_subplot(111)

        # discards the old graph
        ax.clear()

        # plot data
        ax.plot(data, '*-')

        # refresh canvas
        self.canvas.draw()

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

    main = Window()
    main.show()

    sys.exit(app.exec_())
Run Code Online (Sandbox Code Playgroud)

编辑:

已更新以反映注释和API更改.

  • NavigationToolbar2QTAgg 改变了 NavigationToolbar2QT
  • 直接导入Figure而不是pyplot
  • 替换过时ax.hold(False)ax.clear()

  • 请注意,根据[SO note](http://stackoverflow.com/questions/17973177/matplotlib-and-pyqt-dynamic-figure-runs-slow-after-several-loads-or-looks-messy#comment26295260_17973177) ,嵌入时不应导入pyplot.它做了一些时髦的事情,比如用自己的主循环运行自己的GUI.有一个关于嵌入的[Matplotlib示例](http://matplotlib.org/examples/user_interfaces/embedding_in_qt4.html) (13认同)
  • 我有一个错误:MatplotlibDeprecationWarning:这个类在1.4中已被弃用,因为它没有"NavigationToolbar2QT"的附加功能.请更改您的代码以使用`NavigationToolbar2QT`而不是mplDeprecation) (8认同)
  • @gs_developer_user3605534用`NavigationToolbar2QT替换`NavigationToolbar2QTAgg`杀死了邮件 (4认同)

Ana*_*bar 58

下面是对PyQt5Matplotlib 2.0下使用的代码的改编.有一些小的变化:PyQt子模块的结构,来自matplotlib的其他子模块,已弃用的方法已被替换......


import sys
from PyQt5.QtWidgets import QDialog, QApplication, QPushButton, QVBoxLayout

from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
import matplotlib.pyplot as plt

import random

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

        # a figure instance to plot on
        self.figure = plt.figure()

        # this is the Canvas Widget that displays the `figure`
        # it takes the `figure` instance as a parameter to __init__
        self.canvas = FigureCanvas(self.figure)

        # this is the Navigation widget
        # it takes the Canvas widget and a parent
        self.toolbar = NavigationToolbar(self.canvas, self)

        # Just some button connected to `plot` method
        self.button = QPushButton('Plot')
        self.button.clicked.connect(self.plot)

        # set the layout
        layout = QVBoxLayout()
        layout.addWidget(self.toolbar)
        layout.addWidget(self.canvas)
        layout.addWidget(self.button)
        self.setLayout(layout)

    def plot(self):
        ''' plot some random stuff '''
        # random data
        data = [random.random() for i in range(10)]

        # instead of ax.hold(False)
        self.figure.clear()

        # create an axis
        ax = self.figure.add_subplot(111)

        # discards the old graph
        # ax.hold(False) # deprecated, see above

        # plot data
        ax.plot(data, '*-')

        # refresh canvas
        self.canvas.draw()

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

    main = Window()
    main.show()

    sys.exit(app.exec_())
Run Code Online (Sandbox Code Playgroud)

  • 我认为在将 matplotlib 嵌入 pyqt 时导入 `matplotlib.pyplot` 不是最佳实践(如果我在这种情况下错了,请纠正我)。如果我是正确的,我在这个 SO 帖子上使用这种方法嵌入了我的 matplotlib,它不会导入 pyplot:/sf/ask/3076312291/设计器形式和 pyqt5/44029435#44029435 (3认同)

Tre*_*ees 11

对于那些寻找在 PyQt5 中嵌入 Matplotlib 的动态解决方案的人(甚至使用拖放来绘制数据)。在 PyQt5 中,您需要在主窗口类上使用 super 来接受 drop。dropevent 函数可用于获取文件名,其余的很简单:

def dropEvent(self,e):
        """
        This function will enable the drop file directly on to the 
        main window. The file location will be stored in the self.filename
        """
        if e.mimeData().hasUrls:
            e.setDropAction(QtCore.Qt.CopyAction)
            e.accept()
            for url in e.mimeData().urls():
                if op_sys == 'Darwin':
                    fname = str(NSURL.URLWithString_(str(url.toString())).filePathURL().path())
                else:
                    fname = str(url.toLocalFile())
            self.filename = fname
            print("GOT ADDRESS:",self.filename)
            self.readData()
        else:
            e.ignore() # just like above functions  
Run Code Online (Sandbox Code Playgroud)

对于初学者来说,参考完整代码给出了以下输出: 在此输入图像描述