I want to display a 3D matrix in Pyqtgraph using GLVolumeItem (with x, y and z axis) with the specific colors corresponding to the input data.
How can I proceed with my code ?
import numpy as np
import pyqtgraph as pg
import pyqtgraph.opengl as gl
from pyqtgraph import functions as fn
app = pg.mkQApp("GLVolumeItem Example")
w = gl.GLViewWidget()
w.show()
w.setWindowTitle('pyqtgraph example: GLVolumeItem')
w.setCameraPosition(distance=200)
g = gl.GLGridItem()
g.scale(10, 10, 1)
w.addItem(g)
x = np.linspace(0,10,11)
y = np.linspace(0,10,11)
z = np.linspace(0,10,11)
data = np.zeros((10,10,10))
data[1,:,:] = 10
data[3,:,:] = 10
d2 = np.empty(data.shape + (4,), dtype=np.ubyte)
v = gl.GLVolumeItem(d2)
w.addItem(v)
ax = gl.GLAxisItem()
w.addItem(ax)
if __name__ == '__main__':
pg.exec()
The goal is to get a 3D representation with different colors corresponding to the levels of the data.
I think something like this is what you are looking for:
import numpy as np
import pyqtgraph as pg
import pyqtgraph.opengl as gl
from pyqtgraph import functions as fn
from pyqtgraph.opengl import GLScatterPlotItem
app = pg.mkQApp("GLVolumeItem Example")
w = gl.GLViewWidget()
w.show()
w.setWindowTitle('pyqtgraph example: GLVolumeItem')
w.setCameraPosition(distance=40)
g = gl.GLGridItem()
# g.scale(10, 10, 1)
w.addItem(g)
N_x = 10
N_y = 10
N_z = 10
x = np.arange(N_x)
y = np.arange(N_y)
z = np.arange(N_z)
data = np.zeros((N_x, N_y, N_z))
data[1, :, :] = 10
data[3, :, :] = 10
d2 = np.zeros(data.shape + (4,), dtype=np.ubyte)
print(data.shape)
print(d2.shape)
d2[:, :, :, 0] = 255*data/np.max(data) # only works if minimum is 0
d2[:, :, :, 1] = 0
d2[:, :, :, 2] = 0
d2[:, :, :, 3] = 50
v = gl.GLVolumeItem(d2)
# v.translate(10, 10, 10)
w.addItem(v)
ax = gl.GLAxisItem()
w.addItem(ax)
curve = GLScatterPlotItem()
w.addItem(curve)
# pos = np.array((10, 10, 10)).T
# curve.setData(pos=pos, pxMode=False, color=(255, 255, 255, 100), size=0.2) # I use these for checking positions
if __name__ == '__main__':
pg.exec()
The data has shape (N_x, N_y, N_z)
, but the data for a volume item should be shape (N_x, N_y, N_z, 4)
, where the 4
stands for the colour. The line d2[:, :, :, 3] = 50
sets the opacity to 50
at every place. The line d2[:, :, :, 0] = 255*data/np.max(data)
sets the red part of the colour depending on the data of your array.