1# -*- coding: utf-8 -*- 2""" 3Example demonstrating a variety of scatter plot features. 4""" 5 6 7 8## Add path to library (just for examples; you do not need this) 9import initExample 10 11from pyqtgraph.Qt import QtGui, QtCore 12import pyqtgraph as pg 13import numpy as np 14from collections import namedtuple 15from itertools import chain 16 17app = pg.mkQApp("Scatter Plot Item Example") 18mw = QtGui.QMainWindow() 19mw.resize(800,800) 20view = pg.GraphicsLayoutWidget() ## GraphicsView with GraphicsLayout inserted by default 21mw.setCentralWidget(view) 22mw.show() 23mw.setWindowTitle('pyqtgraph example: ScatterPlot') 24 25## create four areas to add plots 26w1 = view.addPlot() 27w2 = view.addViewBox() 28w2.setAspectLocked(True) 29view.nextRow() 30w3 = view.addPlot() 31w4 = view.addPlot() 32print("Generating data, this takes a few seconds...") 33 34## Make all plots clickable 35clickedPen = pg.mkPen('b', width=2) 36lastClicked = [] 37def clicked(plot, points): 38 global lastClicked 39 for p in lastClicked: 40 p.resetPen() 41 print("clicked points", points) 42 for p in points: 43 p.setPen(clickedPen) 44 lastClicked = points 45 46 47## There are a few different ways we can draw scatter plots; each is optimized for different types of data: 48 49## 1) All spots identical and transform-invariant (top-left plot). 50## In this case we can get a huge performance boost by pre-rendering the spot 51## image and just drawing that image repeatedly. 52 53n = 300 54s1 = pg.ScatterPlotItem(size=10, pen=pg.mkPen(None), brush=pg.mkBrush(255, 255, 255, 120)) 55pos = np.random.normal(size=(2,n), scale=1e-5) 56spots = [{'pos': pos[:,i], 'data': 1} for i in range(n)] + [{'pos': [0,0], 'data': 1}] 57s1.addPoints(spots) 58w1.addItem(s1) 59s1.sigClicked.connect(clicked) 60 61 62## 2) Spots are transform-invariant, but not identical (top-right plot). 63## In this case, drawing is almsot as fast as 1), but there is more startup 64## overhead and memory usage since each spot generates its own pre-rendered 65## image. 66 67TextSymbol = namedtuple("TextSymbol", "label symbol scale") 68 69def createLabel(label, angle): 70 symbol = QtGui.QPainterPath() 71 #symbol.addText(0, 0, QFont("San Serif", 10), label) 72 f = QtGui.QFont() 73 f.setPointSize(10) 74 symbol.addText(0, 0, f, label) 75 br = symbol.boundingRect() 76 scale = min(1. / br.width(), 1. / br.height()) 77 tr = QtGui.QTransform() 78 tr.scale(scale, scale) 79 tr.rotate(angle) 80 tr.translate(-br.x() - br.width()/2., -br.y() - br.height()/2.) 81 return TextSymbol(label, tr.map(symbol), 0.1 / scale) 82 83random_str = lambda : (''.join([chr(np.random.randint(ord('A'),ord('z'))) for i in range(np.random.randint(1,5))]), np.random.randint(0, 360)) 84 85s2 = pg.ScatterPlotItem(size=10, pen=pg.mkPen('w'), pxMode=True) 86pos = np.random.normal(size=(2,n), scale=1e-5) 87spots = [{'pos': pos[:,i], 'data': 1, 'brush':pg.intColor(i, n), 'symbol': i%10, 'size': 5+i/10.} for i in range(n)] 88s2.addPoints(spots) 89spots = [{'pos': pos[:,i], 'data': 1, 'brush':pg.intColor(i, n), 'symbol': label[1], 'size': label[2]*(5+i/10.)} for (i, label) in [(i, createLabel(*random_str())) for i in range(n)]] 90s2.addPoints(spots) 91w2.addItem(s2) 92s2.sigClicked.connect(clicked) 93 94 95## 3) Spots are not transform-invariant, not identical (bottom-left). 96## This is the slowest case, since all spots must be completely re-drawn 97## every time because their apparent transformation may have changed. 98 99s3 = pg.ScatterPlotItem( 100 pxMode=False, # Set pxMode=False to allow spots to transform with the view 101 hoverable=True, 102 hoverPen=pg.mkPen('g'), 103 hoverSize=1e-6 104) 105spots3 = [] 106for i in range(10): 107 for j in range(10): 108 spots3.append({'pos': (1e-6*i, 1e-6*j), 'size': 1e-6, 'pen': {'color': 'w', 'width': 2}, 'brush':pg.intColor(i*10+j, 100)}) 109s3.addPoints(spots3) 110w3.addItem(s3) 111s3.sigClicked.connect(clicked) 112 113## Test performance of large scatterplots 114 115s4 = pg.ScatterPlotItem( 116 size=10, 117 pen=pg.mkPen(None), 118 brush=pg.mkBrush(255, 255, 255, 20), 119 hoverable=True, 120 hoverSymbol='s', 121 hoverSize=15, 122 hoverPen=pg.mkPen('r', width=2), 123 hoverBrush=pg.mkBrush('g'), 124) 125n = 10000 126pos = np.random.normal(size=(2, n), scale=1e-9) 127s4.addPoints( 128 x=pos[0], 129 y=pos[1], 130 # size=(np.random.random(n) * 20.).astype(int), 131 # brush=[pg.mkBrush(x) for x in np.random.randint(0, 256, (n, 3))], 132 data=np.arange(n) 133) 134w4.addItem(s4) 135s4.sigClicked.connect(clicked) 136 137if __name__ == '__main__': 138 pg.exec() 139