Update 3D surface without resetting translation (zoom, pan, rotation)


I am currently trying to set up a small dashboard containing some filter options and a 3D surface through Dash. All works well. However, I have the following problem. As soon as I change some filter values, the graph gets completely redrawn. This also includes the zoom level, panning, or rotation of the camera in the 3D surface figure.

Is there a way to keep the camera’s translation the same while updating the underlying data of the graph?

Kind regards,

Hi @MarcS,welcome to the forums.

This should be possible with the Patch() object. Take a look at this:

You could also extract the scene and ranges from the current figure and apply the same settings to the new figure.

I would recommend the first method, though.


Thanks for your answer. However, neither of the options works. To reiterate: I want to keep the current camera positions of a plot after an update. Looking at the examples of Patches: I can zoom into a graph, but as soon as I update the graph, the camera is again zoomed out. I didn’t implement it myself but the examples on the page already demonstrate the problem.

I tried to take a look at the scene property. However, it stays the same in an update (I looked at the current state as an Input) even as I rotated the camera beforehand.

After some additional searching, I guess the “uirevision” is the thing that I’m searching for. See here: 📣 Preserving UI State, like Zoom, in dcc.Graph with uirevision with Dash

Hey @MarcS this topic seems to be similar, the Patch() works in this case.

Could you create a MRE?

I think this has to be done clientside due to sync between browser and backend. Did you try with a clientside callback?

Does the uirevision work for you?

I may have a potential solution for this. May not be perfect but you can make a clientside callback that tracks the current orientation of the ‘camera’ and sends this to a dcc.Store component any time the camera changes. This keeps a live track of the orientation as follows:

if (relayout_data === null || typeof relayout_data === ‘undefined’) {
return window.dash_clientside.no_update;
if (‘scene.camera’ in relayout_data) {
return relayout_data;
This callback ensures the orientation of the 3D scatter plot viewer is maintained
when it is regenerated after the user changes the inputs.
The current orientation is stored in a dcc.Store component.
Output(“camera-store”, “data”),
Input("graph_component, “relayoutData”),

It would also help to initialise this dcc.Store in your app layout to tie in with the preferred original orientation of the camera:

“scene.camera”: {
“up”: {“x”: 0, “y”: 0, “z”: 1},
“center”: {“x”: 0, “y”: 0, “z”: 0},
“eye”: {“x”: -0.81, “y”: 2.00, “z”: 0.09},
“projection”: {“type”: “perspective”},

Then in your original callback to generate the 3D graph, you include this ‘camera-store’ as one of the states of the callback and plug the “scene.camera” value from it into your graph layout scene attribute:

layout = go.Layout(
“xaxis”: {…},
“yaxis”: {…},
“zaxis”: {…},
“camera”: camera_store[“scene.camera”],
fig = go.Figure(data = your_data, layout = layout)

Hope that helps. Cheers

I’m using Plotly to create interactive 3D surface plots, and everything is working beautifully. I’ve noticed that whenever I adjust the filter options to change the data, the entire 3D plot resets, including the camera’s position and orientation. This can be quite disorienting for users who want to explore the 3D visualization without losing their perspective. I’ve explored various avenues, like setting up callbacks and preserving the camera state.