✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
⚡️ Concerned about the grid? Kyle Baranko teaches how to predicting peak loads using XGBoost. Register for the August webinar! # Keep light source fixed in data coordinates

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?

@mburger

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

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)

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')])])])
`````````
1 Like

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.