Getting NetworkX edge 'weight' to show in

2019-05-29 22:50发布

问题:

I've been trying to figure out how to get NetworkX to present very nicely into a QGraphicsScene. I need it to be able to show the 'weight' of each edge, which is the amount of times Company1 was in contact with Company2. The scripts that I have below is a working demo of getting the Nodes and Edges presented into the GUI..but because I'm assigning only the Nodes and Edges, I cannot get the 'weight' or colors at that...but I think I have a way of assigning colors after the fact of placing the individual nodes into the QGraphicsScene. Could someone help me get the 'weight' to show in the QGraphicsScene? I'm totally at a loss. I was thinking of maybe using a dictionary and somehow created extra edges on the QGraphicsItem side of things with the Edge class...any thoughts?

-------- companytrades.csv --------

date,Company1,Company2
1/2/2017,1001,1111
1/3/2017,1001,1100
1/4/2017,1111,1001
1/5/2017,1100,1001
1/6/2017,1011,1001
1/7/2017,1001,1111
1/8/2017,1111,1100
1/9/2017,1100,1011

-------nodes_edges_2_graphicsitem.py---------

class NodeItem(QGraphicsItem):
    def __init__(self, node, radius=15, **args):
        QGraphicsItem.__init__(self, **args)
        global pos
        pos = POS
        global scene
        scene = SCENE 

        self.node = node
        self.radius = radius

        x, y = pos[node]
        self.setPos(QPointF(x, y))

        self.setFlag(QGraphicsItem.ItemIsMovable)
        self.setFlag(QGraphicsItem.ItemIsSelectable)
        self.setFlag(QGraphicsItem.ItemSendsGeometryChanges)

    def itemChange(self, change, value):
        if change == QGraphicsItem.ItemPositionChange :
            point = value.toPointF()
            pos[self.node] = [point.x(), point.y()]
            scene.update()
        return QGraphicsItem.itemChange(self, change, value)

    def update(self, *__args):
        self.setPos(*pos[self.node])

    def boundingRect(self):
        return QRectF(-self.radius, -self.radius, 2*self.radius, 2*self.radius)

    def paint(self, painter, style, widget=None):
        assert isinstance(painter, QPainter)

        if self.isSelected():
            brush = QBrush(Qt.blue)
        else:
            brush = QBrush(Qt.white)

        pen = QPen(Qt.black)

        circle_path = QPainterPath()
        circle_path.addEllipse(self.boundingRect())
        painter.fillPath(circle_path, brush)
        painter.strokePath(circle_path, pen)

        text_path = QPainterPath()
        text_path.addText(0, 0, QFont(), str(self.node))
        box = text_path.boundingRect()
        text_path.translate(-box.center())

        painter.fillPath(text_path, QBrush(Qt.black))


class EdgeItem(QGraphicsItem):
    def __init__(self,POS, SCENE, source, target,  **args):
        QGraphicsItem.__init__(self, **args)
        self.source = source
        self.target = target
        global pos
        pos = POS
        global scene
        scene = SCENE

    def boundingRect(self):
        x0, y0 = pos[self.source]
        x1, y1 = pos[self.target]
        return QRectF(min(x0, x1), min(y0, y1), abs(x1-x0), abs(y1-y0))

    def paint(self, painter, style, widget=None):
        assert(isinstance(painter, QPainter))
        x0, y0 = pos[self.source]
        x1, y1 = pos[self.target]
        painter.drawLine(x0, y0, x1, y1)

---------main.py------------

import pandas as pd
from numpy import *
import sys
from math import *
from PyQt4 import QtCore,QtGui
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import networkx as nx
import nodes_edges_2_graphicsitem.py
from x import *


pf = pd.read_csv('/desktop/companytrades.csv',header=0,index_col=['date'])

#setup the needed variables
if __names__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    app.setStyle("Plastique")

class netx(QtGui.QDialog):
    def __init__(self):
        super(netx,self).__init__()
        self.uiNX = Ui_Form() 
        self.uiNX.setupUi(self)
        g = nx.from_pandas_dataframe(pf,'Company1','Company2',create_using=nx.DiGraph())
Pos = nx.spring_layout(g,scale=300)
scene = QGraphicsScene()

for edge in g.edges():
    scene.addItem(EdgeItem(Pos,scene,edge[0], edge[1]))

for node in g.nodes():
    scene.addItem(Pos,scene,NodeItem(node))
self.uiNX.neworkx_graphicsView.setScene(scene)

NX = netx()
NX.show()
sys.exit(exit(app.exec_())
app.deleteLater()

------- x.py -------

from PyQt4 import QtCore,QtGui
try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.unicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName(_fromUtf8("Form"))
        Form.resize(1492,1029)
        self.networkx_graphicsView = QtGui.QGraphicsView(Form)
        self.networkx_graphicsView.setGeometry(QtCore.QRect(240,70,971,911))
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(5)
        sizePolicy.setHeightForWidth(self.networkx_graphicsView.sizePolicy().hasHeightForWidth())
        self.networkx_graphicsView.setSizePolicy(sizePolicy)
        self.networkx_graphicsView.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.networkx_graphicsView.setObjectName(_fromUtf8("networkx_graphicsView"))
        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)
    def retranslateUi(self,Form):
        Form.setWindowTitle(_translate("Form","Form",None))