2

(This is a follow-up question to the accepted answer found here.)

I want to synchronize two 3D plots in a notebook by setting their ViewVertical and ViewPoint options to a shared dynamic variable, as discussed in the answer linked to above. As a simple example, consider a notebook containing:

{vp, vv} = Options[Graphics3D, {ViewPoint, ViewVertical}][[All, 2]];
{
    Graphics3D[Cuboid[], ViewPoint->Dynamic[vp], ViewVertical->Dynamic[vv]],
    Graphics3D[Cuboid[], ViewPoint->Dynamic[vp], ViewVertical->Dynamic[vv]]
} // GraphicsRow

This works great. However, if I close the notebook and open it up again (and don't run anything), as expected, I get a plot with a red background complaining about

Viewpoint $CellContext`vp is not a triple of numbers or a recognized symbolic form.

Is there an easy way to get this to avoid this while maintaining the synchronization feature? The reason I care is because this is for a documentation notebook for a library I'm writing, and I'd like to make it look like it isn't broken when a user opens it up.

Ian Hincks
  • 1,859
  • 13
  • 21

1 Answers1

3

A simple solution would be to wrap those expressions into a DynamicModule:

DynamicModule[{vp, vv}
, {vp, vv} = Options[Graphics3D, {ViewPoint, ViewVertical}][[All, 2]]
; { Graphics3D[Cuboid[], ViewPoint->Dynamic[vp], ViewVertical->Dynamic[vv]]
  , Graphics3D[Cuboid[], ViewPoint->Dynamic[vp], ViewVertical->Dynamic[vv]]
  } // GraphicsRow
]

DynamicModule was designed for precisely this use case: to preserve the values of variables, and other state, across sessions.

The resulting output cell can be copied-and-pasted to yield a separate UI object with its own state. It can even be pasted into a completely separate front-end session -- provided all referenced variables and definitions are localized within the DynamicModule expression.

WReach
  • 68,832
  • 4
  • 164
  • 269