Lighting and marker sizing in scatter3d

I have a 3D scatter plot that was pleasantly straightforward to get to its current state, but I’m making no progress in refining a few aspects of it:

  1. The sizing of the marker points and those in the legend - if I set marker: { size: 14}, the size of both changes. 14 looks good for the legend, but too large for the data. If I set the size to suit the data, the markers in the legend become tiny. Is there a way to set them independantly, or change the ratio between them?

  2. mesh3d and surface both have the concept of lighting, but scatter3d appears not to. When markers overlap, as shown below, some lighting to give the markers more definition would be very beneficial. Is this possible?

  3. Marker sizing as a function of depth into the screen would also help with comprehension. A user has to waggle the view around in order to gain a sense of whether a marker is near or far.

There’s no way to set the size of the marker points in the legend items at the moment unfortunately

There’s no lighting options for scatter3d at the moment. I’d recommend using marker.opacity in the meantime.

There’s no way to do that at the moment either.

In case this is still bothering anyone, you can now set the legend size to be constant to stop it resizing depending on the trace data.

fig.update_layout(legend_itemsizing='constant')

Has there been any updates or workarounds for the lighting of scatter3d? I haven’t found anything in the forum or documentation.

When visualizing bigger scenes it is really difficult to differentiate between points that are far or near, as well as recognizing objects in the scene. A lighting source would be really helpful.

As an example I’m adding the visualization of the same scene in plotly and open3d.
Open3d is using the point normals to simulate lighting conditions and can therefore aid in the visualization process.


I am also interested in any solutions found, or new features regarding this. When visualizing plots, it is very difficult to determine foreground points from background points without jiggling the view.

Example while viewing some trees:


giggling_gif

Hey @hadallen welcome to the forums.

What you could do is assigning a color to each point. Here an example where the point color is determined by the x- coordinate. But in the end, you are doing this right now, because your marker color is defined by the z- coordinate. So I’m not really sure, I understand your question correctly.

import numpy as np
import plotly.graph_objects as go
import plotly

# create some data
x, y, z = np.meshgrid(
    np.linspace(10, 100, 10), 
    np.linspace(10, 100, 10),
    np.linspace(10, 100, 10)
)

x = x.flatten()
y = y.flatten()
z = z.flatten()

# scaling function
def scale(coordinate_array):
    return [(val - coordinate_array.min()) / (coordinate_array.max() - coordinate_array.min()) for val in coordinate_array]

# plotly color sampler
colors = plotly.colors.sample_colorscale(
    colorscale=plotly.colors.sequential.Turbo,
    samplepoints=scale(x),
)
    

fig = go.Figure(
    data=go.Scatter3d(
        x=x,
        y=y,
        z=z,
        mode='markers',
        marker_size=3,
        marker_color=colors
    ),
    layout={'height': 700}
)

fig.show()


mrep colors

Hi there,

I apologize for necro-bumping and hijacking this old thread, but it is the only one I could find that was related to my interests. Thank you for your suggestion, however I would like to colour the points as they are, based on just the Z value.

I thought that perhaps one way I could achieve what I wish is to calculate the distance from the camera and apply some colour effect (darkening, for example) based on the distance, but I’m not sure if the camera’s eye could even be used to calculate that.

In other 3d point cloud visualization programs, I’ve used an eye-dome lighting effect that greatly increased depth perception - this would be my ideal solution but I believe no lighting effects are implemented for scatter3d plots.

The only other property which comes into my mind would be the opacity. I could imagine converting the color list into rgba strings and vary the alpha value depending on your chosen axis. But the range of [0, 1] might be too small to actually make a difference in the perception. On top, it would not be a dynamic adjustment but static.

In dash you can grab the camera properties, but I’m not sure how to do this in plotly.

what dos this effect look like?

Here is the paper on Eye Dome Lighting (EDL)

I’m not exactly sure how it works, but it is a shading effect like shown here (from ESRI):

1 Like

Also, I am actually using Dash, and this is a dcc.Graph() so I can retrieve the camera parameters.

But I’m not sure how I could turn the camera’s eye value into a vector point.

They use some kind of edge detection algorithm there, looks nice indeed!

Concerning the camera: I think you might need to consider more parameters (eye, up, center) for the vector calculations. A while back I created a demo app for myself to play around with, maybe it helps:

1 Like

Thank you for your help here, I will continue to look into this when I have some time to do so. I’m not even sure it’s possible to determine the vector location of the camera using the eye, center, and up values, but I will explore and see what I can do.

I appreciate you sharing your demo app here, I have been creating an app myself to be used for a tool at work, and I am still relatively inexperienced with Dash and plotly. I will inspect your clientside callback function, as I haven’t been able to wrap my head around that stuff fully yet and I think that has great potential to speed up my app.

1 Like

You’re welcome. If you have any questions about dash or plotly, this is a great place to ask.

Your application seems interesting, if I find the time, I play around with the scene properties.

1 Like