I’m plotting a sphere with Mesh3d and I’d like the light source to rotate with the plot. Right now, the specular reflection stays roughly fixed when I rotate the plot. I’m trying to simulate the Sun shining on a planet, so the Sun needs to rotate with the planet when I change the viewing angle. Is there a way to do this?
The light position remains invariant no matter how you are moving the sphere, by mouse (the camera_eye position is also invariant). You can change light position through animation. Because the lighting and lightposition setttings for Mesh3d are similar to those for Surface, I illustrate the lightposition rotation for a parameterized sphere, defined as an instance of go.Surface.
LE: After a few experiments with different initial light positions, I noticed that
go.Surface.lightposition, as well as
go.Mesh3d.lightposition, has a lot of issues. No matter how the initial
lightposition['z'] is set to a zl value, with -1<zl <1, and keeping xl=yl=10000, the light trajectory is the same during zaxis-rotation. When xl=yl=zl, the light spot does not rotate. This seems to be related to the default
camera.eye position that has
eye.x=eye.y=eye.z. @archmoj could explain what’s going on. Is
lightposition buggy or not?
import numpy as np from numpy import pi, sin, cos import plotly.graph_objects as go #Rotation about zaxis: def rotate_z(x, y, z, theta): w = x+1j*y rw = np.exp(1j*theta)*w return np.real(rw), np.imag(rw), z #Sphere parameterization: lon = np.linspace(0, 2*pi, 200) lat = np.linspace(-pi/2, pi/2) llon, llat = np.meshgrid(lon, lat) x = cos(llon)*cos(llat) y = sin(llon)*cos(llat) z = sin(llat) # constant colorscale brown = [[0, '#9f3632'], [1, '#9f3632']] #initial light position: xl = 10000 yl = 10000 zl = 0.75 fig = go.Figure(go.Surface(x=x, y=y, z=z, colorscale=brown, showscale=False, lighting=dict(ambient=0.5, diffuse=1, fresnel=2, specular=0.5, roughness=0.5), lightposition=dict(x=xl, y=yl, z=zl))) fig.update_layout(dict(title='Animating Light Position Rotation', width=800, height=800)); fig.update_scenes( xaxis_visible=False, yaxis_visible=False, zaxis_visible=False, camera_eye=dict(z=zl)); #define animation frames frames =  theta = np.linspace(0, 2*pi, 36) for t in theta: new_xl, new_yl, new_zl = rotate_z(xl, yl, zl, -t) frames.append(go.Frame(data=[go.Surface(lightposition=dict(x=new_xl, y=new_yl, z=new_zl))], traces=)) fig.update(frames=frames) fig.update_layout(updatemenus=[dict(type='buttons', y=0.75, x=1.05, active=0, buttons=[dict(label='Play', method='animate', args=[None, dict(frame=dict(duration=50, redraw=True), transition=dict(duration=0), fromcurrent=True, mode='immediate')])])]) ```
There is this issue open https://github.com/plotly/plotly.js/issues/2477 which could be related.
Thank you @archmoj. For sure the odd position of the light spot is caused by this issue.