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))