【问题标题】:Embedding a NetworkX graph into PyQT widget将 NetworkX 图嵌入 PyQT 小部件
【发布时间】:2016-02-11 00:51:09
【问题描述】:

我想将使用 NetworkX 创建的图表嵌入到 PyQT5 小部件中。我找到了一个使用 Matplotlib 的正弦函数示例,它运行良好,但我不知道如何使用 NetworkX 图表。

我的代码:

import sys
from PyQt5 import QtWidgets
from gt import Ui_MainWindow
import networkx as nx
import numpy as np
import pylab as P
import matplotlib.pyplot as plt
from networkx.algorithms import bipartite
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from numpy import arange, sin, pi


# example
class DrawSin(FigureCanvas):
    def __init__(self, parent=None):
        fig = Figure()
        self.axes = fig.add_subplot(111)

        self.axes.hold(False)

        t = arange(0.0, 3.0, 0.01)
        s = sin(2*pi*t)
        self.axes.plot(t, s)

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

        FigureCanvas.setSizePolicy(self,
                QtWidgets.QSizePolicy.Expanding,
                QtWidgets.QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)


class Core(QtWidgets.QMainWindow):
    def __init__(self):
        super(Core, self).__init__()

        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        grid = QtWidgets.QGridLayout(self.ui.widget)

        draw_sin = DrawSin(self.ui.widget)
        grid.addWidget(draw_sin)

        self.ui.widget.setFocus()


# my graph
class Test:
    def graphb(self):
        B = nx.Graph()
        B.add_nodes_from([1, 2, 3, 4], bipartite=0)
        B.add_nodes_from(['a', 'b', 'c', 'd', 'e'], bipartite=1)
        B.add_edges_from([(1, 'a'), (2, 'c'), (3, 'd'), (3, 'e'), (4, 'e'), (4, 'd')])

        X = set(n for n, d in B.nodes(data=True) if d['bipartite'] == 0)
        Y = set(B) - X

        X = sorted(X, reverse=True)
        Y = sorted(Y, reverse=True)

        pos = dict()
        pos.update( (n, (1, i)) for i, n in enumerate(X) ) # put nodes from X at x=1
        pos.update( (n, (2, i)) for i, n in enumerate(Y) ) # put nodes from Y at x=2
        nx.draw(B, pos=pos, with_labels=True)

        plt.show()  # to remove


def main():
    app = QtWidgets.QApplication(sys.argv)
    test = Test()
    test.graphb()
    ui = Core()
    ui.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

来自 Qt Designer 的 Ui 文件:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file '.\graphtest.ui'
#
# Created by: PyQt5 UI code generator 5.4.2
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")
        self.widget = QtWidgets.QWidget(self.centralwidget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.widget.sizePolicy().hasHeightForWidth())
        self.widget.setSizePolicy(sizePolicy)
        self.widget.setObjectName("widget")
        self.gridLayout.addWidget(self.widget, 0, 0, 1, 1)
        self.listWidget = QtWidgets.QListWidget(self.centralwidget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.listWidget.sizePolicy().hasHeightForWidth())
        self.listWidget.setSizePolicy(sizePolicy)
        self.listWidget.setMaximumSize(QtCore.QSize(200, 16777215))
        self.listWidget.setObjectName("listWidget")
        self.gridLayout.addWidget(self.listWidget, 0, 1, 1, 1)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

我已经为 wxPython 找到了答案 here,但我不知道如何在 PyQT 中做到这一点。

【问题讨论】:

    标签: python matplotlib networkx pyqt5


    【解决方案1】:

    查看工作示例:

    from PyQt5.QtCore import *
    from PyQt5.QtWidgets import *
    from PyQt5.QtGui import *
    import matplotlib.pyplot as plt
    from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
    from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
    import networkx as nx
    
    class PrettyWidget(QWidget):
    
        NumButtons = ['plot1','plot2', 'plot3']
    
        def __init__(self):
    
    
            super(PrettyWidget, self).__init__()        
            font = QFont()
            font.setPointSize(16)
            self.initUI()
    
        def initUI(self):
    
            self.setGeometry(100, 100, 800, 600)
            self.center()
            self.setWindowTitle('S Plot')
    
            grid = QGridLayout()
            self.setLayout(grid)
            self.createVerticalGroupBox() 
    
            buttonLayout = QVBoxLayout()
            buttonLayout.addWidget(self.verticalGroupBox)
    
            self.figure = plt.figure()
            self.canvas = FigureCanvas(self.figure)        
            grid.addWidget(self.canvas, 0, 1, 9, 9)          
            grid.addLayout(buttonLayout, 0, 0)
    
            self.show()
    
    
        def createVerticalGroupBox(self):
            self.verticalGroupBox = QGroupBox()
    
            layout = QVBoxLayout()
            for i in  self.NumButtons:
                    button = QPushButton(i)
                    button.setObjectName(i)
                    layout.addWidget(button)
                    layout.setSpacing(10)
                    self.verticalGroupBox.setLayout(layout)
                    button.clicked.connect(self.submitCommand)
    
        def submitCommand(self):
            eval('self.' + str(self.sender().objectName()) + '()')
    
    
    
        def plot1(self):
            self.figure.clf()
            ax1 = self.figure.add_subplot(211)
            x1 = [i for i in range(100)]
            y1 = [i**0.5 for i in x1]
            ax1.plot(x1, y1, 'b.-')
    
            ax2 = self.figure.add_subplot(212)
            x2 = [i for i in range(100)]
            y2 = [i for i in x2]
            ax2.plot(x2, y2, 'b.-')
            self.canvas.draw_idle()
    
        def plot2(self):
            self.figure.clf()
            ax3 = self.figure.add_subplot(111)
            x = [i for i in range(100)]
            y = [i**0.5 for i in x]
            ax3.plot(x, y, 'r.-')
            ax3.set_title('Square Root Plot')
            self.canvas.draw_idle()
    
        def plot3(self):
            self.figure.clf()
            B = nx.Graph()
            B.add_nodes_from([1, 2, 3, 4], bipartite=0)
            B.add_nodes_from(['a', 'b', 'c', 'd', 'e'], bipartite=1)
            B.add_edges_from([(1, 'a'), (2, 'c'), (3, 'd'), (3, 'e'), (4, 'e'), (4, 'd')])
    
            X = set(n for n, d in B.nodes(data=True) if d['bipartite'] == 0)
            Y = set(B) - X
    
            X = sorted(X, reverse=True)
            Y = sorted(Y, reverse=True)
    
            pos = dict()
            pos.update( (n, (1, i)) for i, n in enumerate(X) ) # put nodes from X at x=1
            pos.update( (n, (2, i)) for i, n in enumerate(Y) ) # put nodes from Y at x=2
            nx.draw(B, pos=pos, with_labels=True)
            self.canvas.draw_idle()
    
        def center(self):
            qr = self.frameGeometry()
            cp = QDesktopWidget().availableGeometry().center()
            qr.moveCenter(cp)
            self.move(qr.topLeft())
    
    if __name__ == '__main__':
    
        import sys  
        app = QApplication(sys.argv)
        app.aboutToQuit.connect(app.deleteLater)
        app.setStyle(QStyleFactory.create("gtk"))
        screen = PrettyWidget() 
        screen.show()   
        sys.exit(app.exec_())
    
    """
    Modify base on:
    http://stackoverflow.com/questions/36086361/embed-matplotlib-in-pyqt-with-multiple-plot/36093604
    
    """
    

    【讨论】:

      猜你喜欢
      • 2015-04-03
      • 2014-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-11
      • 2017-10-30
      • 1970-01-01
      相关资源
      最近更新 更多