pyqtgraph 获取节点文本并在 MouseClick 上更改颜色
pyqtgraph get text of node and change color on MouseClick
我从 pyqtgraph github 存储库中找到了 this 示例。
我想用 pyqtgraph
创建一个具有以下功能的交互式(网络)图:
- 当用户点击一个节点时,he/she会得到'text'-info of
那个节点。
- 单击节点时该节点的颜色,以及
它的所有邻居(边和节点)都会改变(例如变成黄色)
- 允许多选
代码:
# -*- coding: utf-8 -*-
"""
Simple example of subclassing GraphItem.
"""
import initExample ## Add path to library (just for examples; you do not need this)
import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
import numpy as np
# Enable antialiasing for prettier plots
pg.setConfigOptions(antialias=True)
w = pg.GraphicsWindow()
w.setWindowTitle('pyqtgraph example: CustomGraphItem')
v = w.addViewBox()
v.setAspectLocked()
class Graph(pg.GraphItem):
def __init__(self):
self.dragPoint = None
self.dragOffset = None
self.textItems = []
pg.GraphItem.__init__(self)
self.scatter.sigClicked.connect(self.clicked)
def setData(self, **kwds):
self.text = kwds.pop('text', [])
self.data = kwds
if 'pos' in self.data:
npts = self.data['pos'].shape[0]
self.data['data'] = np.empty(npts, dtype=[('index', int)])
self.data['data']['index'] = np.arange(npts)
self.setTexts(self.text)
self.updateGraph()
def setTexts(self, text):
for i in self.textItems:
i.scene().removeItem(i)
self.textItems = []
for t in text:
item = pg.TextItem(t)
self.textItems.append(item)
item.setParentItem(self)
def updateGraph(self):
pg.GraphItem.setData(self, **self.data)
for i,item in enumerate(self.textItems):
item.setPos(*self.data['pos'][i])
def mouseDragEvent(self, ev):
if ev.button() != QtCore.Qt.LeftButton:
ev.ignore()
return
if ev.isStart():
# We are already one step into the drag.
# Find the point(s) at the mouse cursor when the button was first
# pressed:
pos = ev.buttonDownPos()
pts = self.scatter.pointsAt(pos)
if len(pts) == 0:
ev.ignore()
return
self.dragPoint = pts[0]
ind = pts[0].data()[0]
self.dragOffset = self.data['pos'][ind] - pos
elif ev.isFinish():
self.dragPoint = None
return
else:
if self.dragPoint is None:
ev.ignore()
return
ind = self.dragPoint.data()[0]
self.data['pos'][ind] = ev.pos() + self.dragOffset
self.updateGraph()
ev.accept()
def clicked(self, pts):
print("clicked: %s" % pts)
g = Graph()
v.addItem(g)
## Define positions of nodes
pos = np.array([
[0,0],
[10,0],
[0,10],
[10,10],
[5,5],
[15,5]
], dtype=float)
## Define the set of connections in the graph
adj = np.array([
[0,1],
[1,3],
[3,2],
[2,0],
[1,5],
[3,5],
])
## Define the symbol to use for each node (this is optional)
symbols = ['o','o','o','o','t','+']
## Define the line style for each connection (this is optional)
lines = np.array([
(255,0,0,255,1),
(255,0,255,255,2),
(255,0,255,255,3),
(255,255,0,255,2),
(255,0,0,255,1),
(255,255,255,255,4),
], dtype=[('red',np.ubyte),('green',np.ubyte),('blue',np.ubyte),('alpha',np.ubyte),('width',float)])
## Define text to show next to each symbol
texts = ["Point %d" % i for i in range(6)]
## Update the graph
g.setData(pos=pos, adj=adj, pen=lines, size=1, symbol=symbols, pxMode=False, text=texts)
## Start Qt event loop unless running in interactive mode or using pyside.
if __name__ == '__main__':
import sys
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
QtGui.QApplication.instance().exec_()
上面的代码returns以下信息,当一个节点被点击时:
<pyqtgraph.graphicsItems.ScatterPlotItem.ScatterPlotItem object at 0x7f1e51657558>
其实就是整个图项(因为点击信号是对整个图调用的)
现在:如何在每个节点上调用 MouseClicking 功能,获取该节点的文本并在单击事件时更改其(及其相邻节点)的颜色?
Another example 显示在另一个图中更改单击曲线的颜色。在这里,点击信号在每条曲线上被调用。我试图以此为起点,在下面第一个提到的代码示例中实现类似的东西,但老实说,我什至不知道如何到达 pyqtgraph 图形对象中的单个节点(因为 [我可能在这里错了], 节点仅通过它们的位置来定义)。
一如既往,我们将不胜感激。
编辑:感谢kesumu的回答,我能够像这样获取点击节点的文本内容:
def clicked(self, scatter, pts):
data_list = scatter.data.tolist()
mypoint = [tup for tup in data_list if pts[0] in tup][0]
mypoint_index = data_list.index(mypoint)
mypoint_text = self.text[mypoint_index]
编辑二:
可以找到同一问题的更详细示例 here。
问题是你的clicked
函数有误。
应该是这样的:
def clicked(self, scatter, pts):
print(scatter)
print(pts[0])
print("clicked: %s" % pts)
因为 sigClicked
有两个参数:self,points。这是它的定义:
sigClicked = QtCore.Signal(object, object) ## self, points
修复后可以得到点击点数:
希望对您有所帮助。
我从 pyqtgraph github 存储库中找到了 this 示例。
我想用 pyqtgraph
创建一个具有以下功能的交互式(网络)图:
- 当用户点击一个节点时,he/she会得到'text'-info of 那个节点。
- 单击节点时该节点的颜色,以及 它的所有邻居(边和节点)都会改变(例如变成黄色)
- 允许多选
代码:
# -*- coding: utf-8 -*-
"""
Simple example of subclassing GraphItem.
"""
import initExample ## Add path to library (just for examples; you do not need this)
import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
import numpy as np
# Enable antialiasing for prettier plots
pg.setConfigOptions(antialias=True)
w = pg.GraphicsWindow()
w.setWindowTitle('pyqtgraph example: CustomGraphItem')
v = w.addViewBox()
v.setAspectLocked()
class Graph(pg.GraphItem):
def __init__(self):
self.dragPoint = None
self.dragOffset = None
self.textItems = []
pg.GraphItem.__init__(self)
self.scatter.sigClicked.connect(self.clicked)
def setData(self, **kwds):
self.text = kwds.pop('text', [])
self.data = kwds
if 'pos' in self.data:
npts = self.data['pos'].shape[0]
self.data['data'] = np.empty(npts, dtype=[('index', int)])
self.data['data']['index'] = np.arange(npts)
self.setTexts(self.text)
self.updateGraph()
def setTexts(self, text):
for i in self.textItems:
i.scene().removeItem(i)
self.textItems = []
for t in text:
item = pg.TextItem(t)
self.textItems.append(item)
item.setParentItem(self)
def updateGraph(self):
pg.GraphItem.setData(self, **self.data)
for i,item in enumerate(self.textItems):
item.setPos(*self.data['pos'][i])
def mouseDragEvent(self, ev):
if ev.button() != QtCore.Qt.LeftButton:
ev.ignore()
return
if ev.isStart():
# We are already one step into the drag.
# Find the point(s) at the mouse cursor when the button was first
# pressed:
pos = ev.buttonDownPos()
pts = self.scatter.pointsAt(pos)
if len(pts) == 0:
ev.ignore()
return
self.dragPoint = pts[0]
ind = pts[0].data()[0]
self.dragOffset = self.data['pos'][ind] - pos
elif ev.isFinish():
self.dragPoint = None
return
else:
if self.dragPoint is None:
ev.ignore()
return
ind = self.dragPoint.data()[0]
self.data['pos'][ind] = ev.pos() + self.dragOffset
self.updateGraph()
ev.accept()
def clicked(self, pts):
print("clicked: %s" % pts)
g = Graph()
v.addItem(g)
## Define positions of nodes
pos = np.array([
[0,0],
[10,0],
[0,10],
[10,10],
[5,5],
[15,5]
], dtype=float)
## Define the set of connections in the graph
adj = np.array([
[0,1],
[1,3],
[3,2],
[2,0],
[1,5],
[3,5],
])
## Define the symbol to use for each node (this is optional)
symbols = ['o','o','o','o','t','+']
## Define the line style for each connection (this is optional)
lines = np.array([
(255,0,0,255,1),
(255,0,255,255,2),
(255,0,255,255,3),
(255,255,0,255,2),
(255,0,0,255,1),
(255,255,255,255,4),
], dtype=[('red',np.ubyte),('green',np.ubyte),('blue',np.ubyte),('alpha',np.ubyte),('width',float)])
## Define text to show next to each symbol
texts = ["Point %d" % i for i in range(6)]
## Update the graph
g.setData(pos=pos, adj=adj, pen=lines, size=1, symbol=symbols, pxMode=False, text=texts)
## Start Qt event loop unless running in interactive mode or using pyside.
if __name__ == '__main__':
import sys
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
QtGui.QApplication.instance().exec_()
上面的代码returns以下信息,当一个节点被点击时:
<pyqtgraph.graphicsItems.ScatterPlotItem.ScatterPlotItem object at 0x7f1e51657558>
其实就是整个图项(因为点击信号是对整个图调用的)
现在:如何在每个节点上调用 MouseClicking 功能,获取该节点的文本并在单击事件时更改其(及其相邻节点)的颜色?
Another example 显示在另一个图中更改单击曲线的颜色。在这里,点击信号在每条曲线上被调用。我试图以此为起点,在下面第一个提到的代码示例中实现类似的东西,但老实说,我什至不知道如何到达 pyqtgraph 图形对象中的单个节点(因为 [我可能在这里错了], 节点仅通过它们的位置来定义)。
一如既往,我们将不胜感激。
编辑:感谢kesumu的回答,我能够像这样获取点击节点的文本内容:
def clicked(self, scatter, pts):
data_list = scatter.data.tolist()
mypoint = [tup for tup in data_list if pts[0] in tup][0]
mypoint_index = data_list.index(mypoint)
mypoint_text = self.text[mypoint_index]
编辑二:
可以找到同一问题的更详细示例 here。
问题是你的clicked
函数有误。
应该是这样的:
def clicked(self, scatter, pts):
print(scatter)
print(pts[0])
print("clicked: %s" % pts)
因为 sigClicked
有两个参数:self,points。这是它的定义:
sigClicked = QtCore.Signal(object, object) ## self, points
修复后可以得到点击点数:
希望对您有所帮助。