High level API for 3D scatter plot of different samples

585 views
Skip to first unread message

Alexis Coullomb

unread,
Jan 11, 2018, 5:09:07 AM1/11/18
to vispy

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

David Hoese

unread,
Jan 11, 2018, 1:05:44 PM1/11/18
to vispy
You'll want to look at the plotting API documentation and how the axes are added there. I'm pretty sure there is already scatter plot functionality, but it may only be for 2D plots.

Dave

Alexis Coullomb

unread,
Jan 14, 2018, 10:58:21 AM1/14/18
to vispy
Hi Dave,
The image is from Paraview not from Visy, so I still have to work on Vispy documentation and examples.
Actually someone already asked for something like this: https://github.com/vispy/vispy/issues/1263 and it looks a bit complicated, specially if like me you're not a "real programmer".
Still, I'll try to tinker with it.
Reply all
Reply to author
Forward
0 new messages