Scatter3d plot with slider#
In this example, we combine a three-dimensional scatter plot with a slider, which is used to navigate the time dimension of our data.
[1]:
import plopp as pp
import plopp.widgets as pw
import scipp as sc
import numpy as np
Generate data on a curved panel#
We first generate some data that represents events detected on a cylindrical detector panel, as a function of time.
[2]:
nphi = 100
nz = 20
nt = 50
r = sc.scalar(10.0, unit='m')
phi = sc.linspace('phi', 0, np.pi, nphi, unit='rad')
z = sc.linspace('z', -3.0, 3.0, nz, unit='m')
t = sc.linspace('time', 0.0, 6.0, 50, unit='s')
x = r * sc.cos(phi)
y = r * sc.sin(phi)
h, _ = np.histogramdd(np.random.standard_normal(size=[10_000, 3]), bins=(nt, nz, nphi))
a = sc.array(dims=['time', 'z', 'phi'], values=h, unit='counts')
sizes = a.sizes.copy()
del sizes['time']
da = sc.DataArray(
data=a.flatten(dims=['z', 'phi'], to='pixel'),
coords={
'x': sc.broadcast(x, sizes=sizes).flatten(to='pixel'),
'y': sc.broadcast(z, sizes=sizes).flatten(to='pixel'),
'z': sc.broadcast(y, sizes=sizes).flatten(to='pixel'),
'time': t,
},
)
da
[2]:
scipp.DataArray (830.27 KB)
- time: 50
- pixel: 2000
- time(time)float64s0.0, 0.122, ..., 5.878, 6.0
Values:
array([0. , 0.12244898, 0.24489796, 0.36734694, 0.48979592, 0.6122449 , 0.73469388, 0.85714286, 0.97959184, 1.10204082, 1.2244898 , 1.34693878, 1.46938776, 1.59183673, 1.71428571, 1.83673469, 1.95918367, 2.08163265, 2.20408163, 2.32653061, 2.44897959, 2.57142857, 2.69387755, 2.81632653, 2.93877551, 3.06122449, 3.18367347, 3.30612245, 3.42857143, 3.55102041, 3.67346939, 3.79591837, 3.91836735, 4.04081633, 4.16326531, 4.28571429, 4.40816327, 4.53061224, 4.65306122, 4.7755102 , 4.89795918, 5.02040816, 5.14285714, 5.26530612, 5.3877551 , 5.51020408, 5.63265306, 5.75510204, 5.87755102, 6. ]) - x(pixel)float64m10.0, 9.995, ..., -9.995, -10.0
Values:
array([ 10. , 9.99496542, 9.97986676, ..., -9.97986676, -9.99496542, -10. ]) - y(pixel)float64m-3.0, -3.0, ..., 3.0, 3.0
Values:
array([-3., -3., -3., ..., 3., 3., 3.]) - z(pixel)float64m0.0, 0.317, ..., 0.317, 1.225e-15
Values:
array([0.00000000e+00, 3.17279335e-01, 6.34239197e-01, ..., 6.34239197e-01, 3.17279335e-01, 1.22464680e-15])
- (time, pixel)float64counts0.0, 0.0, ..., 0.0, 0.0
Values:
array([[0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], ..., [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.]])
A slider selecting a single data slice#
We then construct our interface with a slider, a node that slices our data at the index of the slider, and a scatter3dfigure
.
[3]:
# Use Plopp's widget to slice dimensions
slider = pw.SliceWidget(da, dims=['time'])
slider_node = pp.widget_node(slider)
slice_node = pw.slice_dims(data_array=da, slices=slider_node)
fig = pp.scatter3dfigure(slice_node, size=0.3, cbar=True)
# Set slider in the middle so panel isn't all dark
slider.controls['time']['slider'].value = 23
pp.widgets.Box([fig, slider])
[3]:
A slider slicing out a range#
It is also possible to use a RangeSliceWidget
to create a slider with two handles that selects a data range instead of slicing using a single index:
[4]:
# Use Plopp's widget to slice dimensions
slider = pw.RangeSliceWidget(da, dims=['time'])
slider_node = pp.widget_node(slider)
slice_node = pw.slice_dims(data_array=da, slices=slider_node)
# Sum over the selected range of time dimension
sum_slices = pp.Node(sc.sum, slice_node, dim='time')
fig = pp.scatter3dfigure(sum_slices, size=0.3, cbar=True)
# Set slider in the middle so panel isn't all dark
slider.controls['time']['slider'].value = (0, 12)
pp.widgets.Box([fig, slider])
[4]:
[5]:
pp.show_graph(fig)
[5]: