1# -*- coding: utf-8 -*-
2"""
3Demonstrates use of GLScatterPlotItem with rapidly-updating plots.
4
5"""
6
7## Add path to library (just for examples; you do not need this)
8import initExample
9
10import pyqtgraph as pg
11from pyqtgraph import functions as fn
12from pyqtgraph.Qt import QtCore, QtGui
13import pyqtgraph.opengl as gl
14import numpy as np
15
16app = pg.mkQApp("GLScatterPlotItem Example")
17w = gl.GLViewWidget()
18w.show()
19w.setWindowTitle('pyqtgraph example: GLScatterPlotItem')
20w.setCameraPosition(distance=20)
21
22g = gl.GLGridItem()
23w.addItem(g)
24
25
26##
27##  First example is a set of points with pxMode=False
28##  These demonstrate the ability to have points with real size down to a very small scale
29##
30pos = np.empty((53, 3))
31size = np.empty((53))
32color = np.empty((53, 4))
33pos[0] = (1,0,0); size[0] = 0.5;   color[0] = (1.0, 0.0, 0.0, 0.5)
34pos[1] = (0,1,0); size[1] = 0.2;   color[1] = (0.0, 0.0, 1.0, 0.5)
35pos[2] = (0,0,1); size[2] = 2./3.; color[2] = (0.0, 1.0, 0.0, 0.5)
36
37z = 0.5
38d = 6.0
39for i in range(3,53):
40    pos[i] = (0,0,z)
41    size[i] = 2./d
42    color[i] = (0.0, 1.0, 0.0, 0.5)
43    z *= 0.5
44    d *= 2.0
45
46sp1 = gl.GLScatterPlotItem(pos=pos, size=size, color=color, pxMode=False)
47sp1.translate(5,5,0)
48w.addItem(sp1)
49
50
51##
52##  Second example shows a volume of points with rapidly updating color
53##  and pxMode=True
54##
55
56pos = np.random.random(size=(100000,3))
57pos *= [10,-10,10]
58pos[0] = (0,0,0)
59color = np.ones((pos.shape[0], 4))
60d2 = (pos**2).sum(axis=1)**0.5
61size = np.random.random(size=pos.shape[0])*10
62sp2 = gl.GLScatterPlotItem(pos=pos, color=(1,1,1,1), size=size)
63phase = 0.
64
65w.addItem(sp2)
66
67
68##
69##  Third example shows a grid of points with rapidly updating position
70##  and pxMode = False
71##
72
73pos3 = np.zeros((100,100,3))
74pos3[:,:,:2] = np.mgrid[:100, :100].transpose(1,2,0) * [-0.1,0.1]
75pos3 = pos3.reshape(10000,3)
76d3 = (pos3**2).sum(axis=1)**0.5
77
78sp3 = gl.GLScatterPlotItem(pos=pos3, color=(1,1,1,.3), size=0.1, pxMode=False)
79
80w.addItem(sp3)
81
82
83def update():
84    ## update volume colors
85    global phase, sp2, d2
86    s = -np.cos(d2*2+phase)
87    color = np.empty((len(d2),4), dtype=np.float32)
88    color[:,3] = fn.clip_array(s * 0.1, 0., 1.)
89    color[:,0] = fn.clip_array(s * 3.0, 0., 1.)
90    color[:,1] = fn.clip_array(s * 1.0, 0., 1.)
91    color[:,2] = fn.clip_array(s ** 3, 0., 1.)
92    sp2.setData(color=color)
93    phase -= 0.1
94
95    ## update surface positions and colors
96    global sp3, d3, pos3
97    z = -np.cos(d3*2+phase)
98    pos3[:,2] = z
99    color = np.empty((len(d3),4), dtype=np.float32)
100    color[:,3] = 0.3
101    color[:,0] = np.clip(z * 3.0, 0, 1)
102    color[:,1] = np.clip(z * 1.0, 0, 1)
103    color[:,2] = np.clip(z ** 3, 0, 1)
104    sp3.setData(pos=pos3, color=color)
105
106t = QtCore.QTimer()
107t.timeout.connect(update)
108t.start(50)
109
110if __name__ == '__main__':
111    pg.exec()
112