
Hi all,
I am currently trying to implement a way to display data on a 3D scatter plot like one can do in Paraview (see image).
So far I got to that:
def vpscatter(xdata, ydata, zdata):
# build your visuals
Scatter3D = scene.visuals.create_visual_node(visuals.MarkersVisual)
# The real-things : plot using scene
# build canvas
canvas = scene.SceneCanvas(keys='interactive', show=True)
# Add a ViewBox to let the user zoom/rotate
view = canvas.central_widget.add_view()
view.camera = 'turntable'
view.camera.fov = 45
view.camera.distance = 500
# data
n = xdata.size
pos = np.zeros((n, 3))
pos[:,0] = xdata.ravel()
pos[:,1] = ydata.ravel()
pos[:,2] = zdata.ravel()
colors = np.ones((n, 4), dtype=np.float32)
# plot
p1 = Scatter3D(parent=view.scene)
p1.set_gl_state('translucent', blend=True, depth_test=True)
p1.set_data(pos, face_color=colors)
p1.symbol = '*' #visuals.marker_types[10]
# run
app.run()
but is there a way to:
- display axes with ticks and labels
- translate the view when we click one both mouse buttons
- change the centre of rotation
- access properties of the plot and change them (values, color, sing size of separate datasets)
?
I was thinking of something like:
vpscatter(datasets, axes_labels=None, mark_size=1, mark_sign='+', mark_color='white', parent=None):
"""
This function displays a 3Dscatter plot of different samples that are arrays of shape Nx3. They can be numpy arrays or panda dataframes.
datasets: tuple of samples
axes_labels: if None, the labels are taken from the column names of the panda dataframe if samples are dataframes, otherwise they are not displayed
if tuple of 3 strings, one string is displayed per axis
mark_size: ...
mark_sign: ...
mark_color: ...
parent: handle of the parent widget if relevant
"""
...
return scatter_view
and then we could do in a matplotlib kind of way:
data_display = vpscatter((data1, data2))
data_display.add_dataset(data3) # displays a new sample in the scene
ds = data_display.get_datasets() # return a tuple of handle of samples
ds[0].set_color(#ff0000) # change to red the color of the first sample
ds[0].set_datalabel('first experiment') # change the label of the sample
extracted_data = ds[0].get_data() # returns a numpy array
ds[0].update_data(data4) # change the values of the dataset and refreshes the view
axes = data_display.get_axes() return a tuple of handles of the 3 axes
xaxis = axes[0]
xaxis.ticks.set_values(np.arrange(100))
xaxis.label.set_value('pressure')
xaxis.label.set_color('green')
xaxis.label.display(False) # hides the label of the xaxis
xaxis.display(False) # hides the xaxis
I think this kind of end-user function/API would be very useful, especially for those who don't have skill or time to implement it.
Do you have an idea on how to do it?
Thanks a lot,
Alexis