Skip to content

Embedding ArrayViewer#

ndv can be embedded in an existing Qt (or wx) application and enriched with additional elements in a custom layout. The following document shows some examples of such implementation.

The key in each case is the use of the ArrayViewer.widget method, which returns a native widget for the current GUI backend.

Change the content of ArrayViewer via push buttons#

The following script shows an example on how to dynamically select a data set and load it in the ArrayViewer.

examples/cookbook/ndv_embedded.py
# /// script
# dependencies = [
#   "ndv[vispy,pyqt]",
#   "imageio[tifffile]",
# ]
# ///
"""An example on how to embed the `ArrayViewer` controller in a custom Qt widget."""

from qtpy import QtWidgets

from ndv import ArrayViewer, run_app
from ndv.data import astronaut, cat


class EmbeddingWidget(QtWidgets.QWidget):
    def __init__(self) -> None:
        super().__init__()
        self._viewer = ArrayViewer()

        self._cat_button = QtWidgets.QPushButton("Load cat image")
        self._cat_button.clicked.connect(self._load_cat)

        self._astronaut_button = QtWidgets.QPushButton("Load astronaut image")
        self._astronaut_button.clicked.connect(self._load_astronaut)

        btns = QtWidgets.QHBoxLayout()
        btns.addWidget(self._cat_button)
        btns.addWidget(self._astronaut_button)

        layout = QtWidgets.QVBoxLayout(self)
        # `ArrayViewer.widget()` returns the native Qt widget
        layout.addWidget(self._viewer.widget())
        layout.addLayout(btns)

        self._load_cat()

    def _load_cat(self) -> None:
        self._viewer.data = cat().mean(axis=-1)

    def _load_astronaut(self) -> None:
        self._viewer.data = astronaut().mean(axis=-1)


app = QtWidgets.QApplication([])
widget = EmbeddingWidget()
widget.show()
run_app()

Screenshot generated with ndv_embedded Screenshot generated with ndv_embedded

Use multiple ndv.ArrayViewer controllers in the same widget#

The following script shows an example on how to create multiple instances of the ArrayViewer controller in the same widget and load two different datasets in each one.

examples/cookbook/multi_ndv.py
# /// script
# dependencies = [
#   "ndv[vispy,pyqt]",
#   "imageio[tifffile]",
# ]
# ///
"""An example on how to embed multiple `ArrayViewer` controllers in a custom Qt widget.

It shows the `astronaut` and `cells3d` images side by side on two different viewers.
"""

from qtpy import QtWidgets

from ndv import ArrayViewer, run_app
from ndv.data import astronaut, cells3d


class MultiNDVWrapper(QtWidgets.QWidget):
    def __init__(self) -> None:
        super().__init__()

        self._astronaut_viewer = ArrayViewer(astronaut().mean(axis=-1))
        self._cells_virewer = ArrayViewer(cells3d(), current_index={0: 30, 1: 1})

        # get `ArrayViewer` widget and add it to the layout
        layout = QtWidgets.QHBoxLayout(self)
        layout.addWidget(self._astronaut_viewer.widget())
        layout.addWidget(self._cells_virewer.widget())


app = QtWidgets.QApplication([])
widget = MultiNDVWrapper()
widget.show()
run_app()

Screenshot generated with multi_ndv Screenshot generated with multi_ndv