Anatomist NoteBook widget

anatomist.notebook.Anatomist(*args, **kwargs)

Anatomist implementation rendering in a Jupyter Notebook. It is the headless wrapping around the NotebookAnatomist implementation.

Embed an Anatomist 3D view in a jupyter notebook widget

To work this notebook widget needs:

  • to install ipycanvas, ipyevents, ipywidgets, numpy, anatomist, jupyter notebook

  • to register jupyter notebook extensions (may require sudo permissions if jupyter is installed system-wide):

    jupyter nbextension enable --py widgetsnbextension
    jupyter nbextension enable --py ipyevents
    jupyter nbextension enable --py ipycanvas
    

There are two ways to use it, in a notebook cell. The first is an “integrated” variant of the Anatomist application which redirects all its views to notebook canvases, the second is a “by window” method.

Integrated Anatomist:

import anatomist.notebook as ana

a = ana.Anatomist()
w = a.createWindow('3D')
mesh = a.loadObject('/home/dr144257/data/ra_head.mesh')
w.addObjects(mesh)

By window:

import anatomist.headless as ana
# need to be instantiated before Qt implementations are loaded
a = ana.HeadlessAnatomist()

from anatomist.notebook.api import AnatomistInteractiveWidget

w = a.createWindow('3D')
mesh = a.loadObject('/home/riviere/data/ra_head.mesh')
w.addObjects(mesh)

canvas = AnatomistInteractiveWidget(w)
display(canvas)

Note that the integrated anatomist.notebook implementation is a headless implementation, and wraps Anatomist windows widget as a single canvas. It is able to render Qt interfaces in a web browser, but cannot open pop-ups, menus, tooltips, or parameters dialogs. Qt widgets renderings are not synchronized because we lack a callback slot when this is done.

class anatomist.notebook.api.AnatomistInteractiveWidget(**kwargs)[source]

Taken and modified from: https://github.com/Kitware/ipyvtklink/blob/master/ipyvtklink/viewer.py

Remote controller for Anatomist render windows. In Anatomist 5.1, Anatomist 3D views are sync’ed to the canvas automatically at each 3D rendering (via a Qt signal). In earlier Anatomist (5.0) this sync is not automatic and is only forced when input events are caught, which means that renderings done on Anatomist side for other reasons (such as animations) will not be rendered.

Other Qt widgets (browsers…) are not sync’ed either because we have no obvious means to capture paint events from arbitrary Qt widgets.

Parameters:
  • allow_wheel (bool, optional) – Capture wheel events and allow zooming using the mouse wheel.

  • quality (float, optional) – Full rendering image quality. 100 for best quality, 0 for min quality. Default 85.

  • quick_quality (float, optional) – Quick rendering image quality during mouse dragging. 100 for best quality, 0 for min quality. Default 50. Keep this number low to allow rapid rendering on limited bandwidth.

  • on_close (callable) – A callable function with no arguments to be triggered when the widget is destroyed. This is useful to have a callback to close/clean up the render window.

Create a Canvas widget.

close()[source]

Close method.

Closes the underlying comm. When the comm is closed, all of the widget views are automatically removed from the front-end.

property render_window

reference the weak reference

update_canvas(force_render=True, quality=75)[source]

Updates the canvas with the current render

class anatomist.notebook.api.NotebookAnatomist(*args, **kwargs)[source]

A derived Anatomist class which automatically redirects its views to Jupyter notebook canvases. It only overloads the createWindow() method which creates an AnatomistInteractiveWidget canvas together with each window. It is normally used with the “headless” variant of Anatomist.

Usage, in a notebook:

import anatomist.headless as ana

a = ana.HeadlessAnatomist(
    implementation='anatomist.notebook.api.NotebookAnatomist')
w = a.createWindow('3D')
mesh = a.loadObject('/home/dr144257/data/ra_head.mesh')
w.addObjects(mesh)

This is also implemented as a variant of Anatomist implementation:

import anatomist
anatomist.setDefaultImplementation('notebook')
import anatomist.api as ana

a = ana.Anatomist()

Or, simply:

import anatomist.notebook as ana

a = ana.Anatomist()

Note

In this example we load anatomist.notebook without the api submodule, because the latter loads Qt and thus prevents the optimized headless implementation to load and use VirtualGL.

The createWindow() method overload adds an additonal keyword argument, only_3D which enables to display only the 3D rendering view, or the full window with buttons and sliders.

Warning

Limitations

The notebook execution in a script (like for sphinx docs) may crash anatomist: the notebook execution while a GUI event loop is running, is done through GUI events. Such events thus contain code to execute. The code may contain (or imply) objects deletion, but they may be triggered from within Anatomist winwows methods. For instance, the AWindow3D.snapshotImage() method, used to draw the canvas, needs to call QApplication.processEvents(), because it needs to force the window paint before grabing its content, and this is done in Qt through events. Here with notebooks, the events may contain code which can delete the window being used, and lead to a crash.

We have not found a solution for now. However running the notebook interactively, or running notebooks which do not delete windows objects, seem to be safe.

The __init__ method of Singleton derived class should do nothing. Derived classes must define __singleton_init__() instead of __init__.

class AWindow(*args, **kwargs)[source]

If internal rep is given in parameter, the corresponding anatomist window already exists : take a reference on it (to prevent its deletion).

createWindow(wintype, geometry=[], block=None, no_decoration=None, options=None, only_3d=False)[source]

Overload for anatomist.direct.api.Anatomist.createWindow() which embeds the window in a Jupyter notebook canvas. It has an additional optional keyword argument:

Parameters:

only_3d (bool) – if False, the full window is rendered in the notebook canvas (except that menubars are hidden since popups are not working). If True, only the 3D view part is rendered in the canvas (which should also be more efficient because it avoids a buffer copy).