Search code examples
plotly

3d Camera Control Slider


I was wondering if it is possible to make a slider for 3d Camera Controls. And I want to save it as a html file. The following is my code. Any help or suggestion would be appreciated.

import numpy as np
import plotly.graph_objects as go


x, y = np.mgrid[0:2*np.pi:100j, 0:2*np.pi:100j]
z = np.sin(x) *np.cos(y)

fig = go.Figure()

for step in np.arange(0, 5, 1):
    fig.add_trace(
        go.Surface(visible=False,
            x=x,y=y,z=z
            ))
    fig.update_layout(
    scene_camera=dict(
    eye=dict(x=2, y=2, z=step)
    )
    )

fig.data[1].visible = True

steps = []
for i in range(len(fig.data)):
    step = dict(
        method="update",
        args=[{"visible": [False] * len(fig.data)}]
    )
    step["args"][0]["visible"][i] = True
    steps.append(step)

sliders = [dict(
    active=0,
    steps=steps
)]

fig.update_layout(
    sliders=sliders
)

fig.show()

Solution

  • If you are using Jupyter Notebook, you can use ipywidgets:

    import plotly.graph_objects as go
    import numpy as np
    from ipywidgets import widgets
    
    # numerical data
    r, t = np.mgrid[0:2.25:20j, 0:2*np.pi:20j]
    x = r * np.cos(t)
    y = r * np.sin(t)
    z = np.cos(r**2)
    
    ele_slider = widgets.FloatSlider(min=-np.pi/2, max=np.pi/2, value=np.pi/4, description="Elevation")
    azi_slider = widgets.FloatSlider(min=0, max=2*np.pi, value=np.pi/4, description="Azimuth")
    fig_widg = go.FigureWidget(data=[go.Surface(x=x, y=y, z=z)])
    
    # set the distance of the camera from the center
    r = 2
    
    def func(change):
        x = r * np.cos(ele_slider.value) * np.cos(azi_slider.value)
        y = r * np.cos(ele_slider.value) * np.sin(azi_slider.value)
        z = r * np.sin(ele_slider.value)
        fig_widg.update_layout({"scene": { "camera": {"eye": {"x": x, "y": y, "z": z}}}})
    
    azi_slider.observe(func, names="value")
    ele_slider.observe(func, names="value")
    widgets.VBox([ele_slider, azi_slider, fig_widg])