✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
🧬 Learn how to build RNA-Seq data apps with Python & Dash. Register for the May 20 Webinar!

Changing camera views and projection with Custom Buttons

Hi everyone,

I am trying to use custom buttons to change the camera view (e.g. XZ plane, XY Plane) and projection type (e.g.: Orthographic, Perspective)

I have tried setting a variable

xzplane = dict(
            eye=dict(x=0, y=2.5, z=0),
            projection_type="orthographic",
            )

And then in the update menus

updatemenus=[
                            dict(
                                type="buttons",
                                direction="right",
                                active=0,
                                x=0.57,
                                y=1.2,
                                buttons=list([
                                        dict(label="XZ Plane",
                                        method="update",
                                        args=[{"visible": [True, True, True, True]},
                                        {"title": "XZ Orthographic Projection",
                                        "annotations": xzplane}]),
                                ]),
                            )
                  ]

Any suggestions?

I have tried changing “annotations” to “scene_camera”, and even “projection_type”, however, it does not seem to work. Perhaps my understanding of args is flawed.

I have also tried changing the method=“relayout” and then using “scene_camera” and “projection_type”. No change there.

Thanks in advance.

Hi @astro,

The method used for changing the 'scene.camera.up' vector (i.e the horizontal plane), respectively the 'scene.camera.projection.type', is relayout, not update, because it is the layout that changes not both the trace attributes or data, and layout. (see https://plotly.com/python/dropdowns/).
visible is an attribute of a trace, not for layout

Notice that in a button arg definition below, we are following the javascript rule to access an item of a nested dictionary, like scene = {'camera': {'up': {'x': 0, 'y':0, 'z'=1}}}, i.e. we are setting 'scene.camera.up': {'x':0, 'y':0, 'z':1}}:

import plotly.graph_objects as go

x =  [ 1, 2, 3, 4, 5]
y =  [0.1, 0.2, 0.3, 0.4]
z= [[1001, 1002, 1001, 1000, 1004],  
     [1002, 1001, 1004, 1002, 1003],
     [1003, 1000, 1001, 1001, 1004],
     [1000, 1004, 1000, 1002, 999]]

surf = go.Surface(x=x, y=y, z=z, 
                  colorscale='Oranges', 
                  colorbar_thickness=25)
fig=go.Figure(surf)

button1 = dict(method = "relayout",
               args = [{"scene.camera.up": {'x':0,
                                            'y':0,
                                            'z':1}}], 
               label = "z-up")
button2 = dict(method = "relayout",
               args=[{"scene.camera.up": {'x':0, 
                                          'y':1,
                                          'z':0}}], 
               label="y-up")

fig.update_layout(width=600, height=600,
                  margin_b=80,
                  updatemenus=[dict(
                                 buttons=[button1, button2])
                              ])

and

fig1=go.Figure(surf)

button1 = dict(method = "relayout",
               args = [{"scene.camera.projection.type=": "perspective",
                       "scene.camera.eye":{'x': 1.25, 'y':1.25, 'z': 1}}], 
               label = "Perspective")
button2 = dict(method = "relayout",
               args = [{"scene.camera.projection.type=": "orthographic",
                        "scene.camera.eye": None}],
               label="Orthographic")

fig1.update_layout(width=600, height=600,
                   margin_b=80,
                   updatemenus=[dict(
                                 buttons=[button1, button2])
                              ])

Hi @empet,

Great thanks! Works perfectly!
And thanks for explaining and clarifying args definition rule and the method!