When working with plots changing the cursor can help with pointing accuracy. For example, if you need to isolate particular points in a scatter plot a cross-hair will give you a more accurate view of where you are pointing than the standard arrow cursor.
Changing the mouse cursor
Changing the mouse cursor in a PyQtGraph is fairly simple and uses Qt's built-in support for custom cursors over a widget. Since the PyQtGraph PlotWidget
is a subclass of QGraphicsWidget
(and therefore QWidget
) you can use the standard methods.
cursor = Qt.CrossCursor
self.graphWidget.setCursor(cursor)
For the complete list of cursor types, see the Qt documentation. The example below shows this in action on a simple PyQtGraph plot.
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QMainWindow, QApplication
from pyqtgraph import PlotWidget, plot
import pyqtgraph as pg
import sys # We need sys so that we can pass argv to QApplication
import os
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.graphWidget = pg.PlotWidget()
self.setCentralWidget(self.graphWidget)
hour = [1,2,3,4,5,6,7,8,9,10]
temperature = [30,32,34,32,33,31,29,32,35,45]
#Add Background colour to white
self.graphWidget.setBackground('w')
# Add Title
self.graphWidget.setTitle("Your Title Here", color="b", size="30pt")
# Add Axis Labels
styles = {"color": "#f00", "font-size": "20px"}
self.graphWidget.setLabel("left", "Temperature (°C)", **styles)
self.graphWidget.setLabel("bottom", "Hour (H)", **styles)
#Add legend
self.graphWidget.addLegend()
#Add grid
self.graphWidget.showGrid(x=True, y=True)
#Set Range
self.graphWidget.setXRange(0, 10, padding=0)
self.graphWidget.setYRange(20, 55, padding=0)
pen = pg.mkPen(color=(255, 0, 0))
self.graphWidget.plot(hour, temperature, name="Sensor 1", pen=pen, symbol='+', symbolSize=30, symbolBrush=('b'))
# Set the cursor for the plotwidget. The mouse cursor will change when over the plot.
cursor = Qt.CrossCursor
self.graphWidget.setCursor(cursor)
app = QApplication(sys.argv)
main = MainWindow()
main.show()
app.exec_()
If you run this you'll see a cross-hair cursor appear when you hover your mouse over the plot.
Crosshair cursor on plot
Drawing a custom cursor
If you want to show a completely custom cursor, for example an full-size crosshair over the plot, things are a little trickier. In this case you need to draw the cursor yourself by adding elements to the plot and then listening for mouse events and updating their position.
The code below is an updated version of the plot above, with two crosshair lines added using PyQtGraphs InfiniteLine
objects. The lines are drawn in the __init__
method, and then updated in the mouseMoved
method.
Never miss an update
Enjoyed this? Subscribe to get new updates straight in your Inbox.
You could also add any other QGraphicsScene item here instead.
The important part is the SignalProxy
which forwards mouse movements to our custom method update_crosshair
. The rateLimit
parameter
sets the maximum number of signals per second which will be sent, to avoid overloading our handler/app with excessive events.
from PyQt5.QtWidgets import QMainWindow, QApplication
from PyQt5.QtCore import Qt
from pyqtgraph import PlotWidget, plot
import pyqtgraph as pg
import sys # We need sys so that we can pass argv to QApplication
import os
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.graphWidget = pg.PlotWidget()
self.setCentralWidget(self.graphWidget)
hour = [1,2,3,4,5,6,7,8,9,10]
temperature = [30,32,34,32,33,31,29,32,35,45]
#Add Background colour to white
self.graphWidget.setBackground('w')
# Add Title
self.graphWidget.setTitle("Your Title Here", color="b", size="30pt")
# Add Axis Labels
styles = {"color": "#f00", "font-size": "20px"}
self.graphWidget.setLabel("left", "Temperature (°C)", **styles)
self.graphWidget.setLabel("bottom", "Hour (H)", **styles)
#Add legend
self.graphWidget.addLegend()
#Add grid
self.graphWidget.showGrid(x=True, y=True)
#Set Range
self.graphWidget.setXRange(0, 10, padding=0)
self.graphWidget.setYRange(20, 55, padding=0)
pen = pg.mkPen(color=(255, 0, 0))
self.graphWidget.plot(hour, temperature, name="Sensor 1", pen=pen, symbol='+', symbolSize=30, symbolBrush=('b'))
# 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.proxy = pg.SignalProxy(self.graphWidget.scene().sigMouseMoved, rateLimit=60, slot=self.update_crosshair)
def update_crosshair(self, e):
pos = e[0]
if self.graphWidget.sceneBoundingRect().contains(pos):
mousePoint = self.graphWidget.getPlotItem().vb.mapSceneToView(pos)
self.crosshair_v.setPos(mousePoint.x())
self.crosshair_h.setPos(mousePoint.y())
app = QApplication(sys.argv)
main = MainWindow()
main.show()
app.exec_()
If you run this example, in addition to the mouse cursor you'll also see a faint yellow line overlaying the plot.
The custom cursor with default mouse cursor hidden
To hide the default mouse cursor over the plot set the curser type to Qt.BlankCursor
. For example.
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
# ... rest of __init__ as before
# Hide the cursor over the plot.
cursor = Qt.BlankCursor
self.graphWidget.setCursor(cursor)
This will give the following result when hovering over the plot.
The custom cursor with default mouse cursor hidden