Issue
I am new to PyQt and Im developing a utility where a user can import data from an excel file and plot its X and Y in a 2d scatter plot using below code:
def plot_2d_scatter(graphWidget,x,z,color=(66, 245, 72)):
graphWidget.clear()
brush = pg.mkBrush(color)
scatter = pg.ScatterPlotItem(size=5, brush=brush)
scatter.addPoints(x,z)
graphWidget.addItem(scatter)
Now I want a functionality which will allow the user to move his mouse over the scatter plot points using a cross hair / pointer / etc and select points on the scatter plot.
Whenever the user does a left click on the crosshair / marker on the scatter plot, I want its x,y coordinates to be saved for further use.
I have already tried the below snippet from somewhere on internet for using mouse events and getting my scatter points , but this didnt give me a cross hair that falls on my scatter points
def mouseMoved(self, evt):
pos = evt
if self.plotWidget.sceneBoundingRect().contains(pos):
mousePoint = self.plotWidget.plotItem.vb.mapSceneToView(pos)
mx = np.array([abs(float(i) - float(mousePoint.x())) for i in self.plotx])
index = mx.argmin()
if index >= 0 and index < len(self.plotx):
self.cursorlabel.setHtml(
"<span style='font-size: 12pt'>x={:0.1f}, \
<span style='color: red'>y={:0.1f}</span>".format(
self.plotx[index], self.ploty[index])
)
self.vLine.setPos(self.plotx[index])
self.hLine.setPos(self.ploty[index])
Any guidance is thankfully appreciated
Solution
my best fast effort, never used pg untill today:
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QDesktopWidget, QWidget
from PyQt5.QtCore import Qt
from PyQt5 import QtGui, QtCore, QtWidgets
import pyqtgraph as pg
import numpy as np
class MyApp(QMainWindow):
def __init__(self, parent=None):
super(MyApp, self).__init__(parent)
self.resize(781, 523)
self.graphWidget = pg.PlotWidget()
self.setCentralWidget(self.graphWidget)
self.show()
self.x = [1,2,3,4,5,6,7,8,9,5,6,7,8]
self.y = [1,2,3,4,5,6,7,8,9,5,6,7,8]
# self.y.reverse()
self.plot_2d_scatter(self.graphWidget, self.x, self.y)
self.cursor = Qt.CrossCursor
# self.cursor = Qt.BlankCursor
self.graphWidget.setCursor(self.cursor)
# Add crosshair lines.
self.crosshair_v = pg.InfiniteLine(angle=90, movable=False)
self.crosshair_h = pg.InfiniteLine(angle=0, movable=False)
self.graphWidget.addItem(self.crosshair_v, ignoreBounds=True)
self.graphWidget.addItem(self.crosshair_h, ignoreBounds=True)
self.cursorlabel = pg.TextItem()
self.graphWidget.addItem(self.cursorlabel)
self.proxy = pg.SignalProxy(self.graphWidget.scene().sigMouseMoved, rateLimit=60, slot=self.update_crosshair)
self.mouse_x = None
self.mouse_y = None
def plot_2d_scatter(self,graphWidget,x,z,color=(66, 245, 72)):
# graphWidget.clear()
brush = pg.mkBrush(color)
scatter = pg.ScatterPlotItem(size=5, brush=brush)
scatter.addPoints(x,z)
graphWidget.addItem(scatter)
def update_crosshair(self, e):
pos = e[0]
if self.graphWidget.sceneBoundingRect().contains(pos):
mousePoint = self.graphWidget.plotItem.vb.mapSceneToView(pos)
mx = np.array([abs(float(i) - float(mousePoint.x())) for i in self.x])
index = mx.argmin()
if index >= 0 and index < len(self.x):
self.cursorlabel.setText(
str((self.x[index], self.y[index])))
self.crosshair_v.setPos(self.x[index])
self.crosshair_h.setPos(self.y[index])
self.mouse_x = self.crosshair_v.setPos(self.x[index])
self.mouse_y = self.crosshair_h.setPos(self.y[index])
self.mouse_x = (self.x[index])
self.mouse_y = (self.y[index])
def mousePressEvent(self, e):
if e.buttons() & QtCore.Qt.LeftButton:
print('pressed')
# if self.mouse_x in self.x and self.mouse_y in self.y:
print(self.mouse_x, self.mouse_y)
if __name__ == '__main__':
app = QApplication(sys.argv)
myapp = MyApp()
# myapp.show()
try:
sys.exit(app.exec_())
except SystemExit:
print('Closing Window...')
it just prints out the coordinate of pressed point in graph
copied from https://www.pythonguis.com/faq/pyqt-show-custom-cursor-pyqtgraph/ and your piece of code result looks like:
there are other examples on SO like Trying to get cursor with coordinate display within a pyqtgraph plotwidget in PyQt5 and others
Answered By - pippo1980
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.