Skip to content

Visualization

Class defining a wrapper for allowing scrolling through different slices of a 3-D image when using plt.show().

Source code in pygrpm/visualization/index_tracker.py
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
class IndexTracker:
    """
    Class defining a wrapper for allowing scrolling through different slices of a 3-D
    image when using plt.show().
    """

    # pylint: disable=too-many-instance-attributes, too-many-arguments
    def __init__(
        self,
        img_array,
        slice_axis: int = 0,
        fig: plt.Figure = None,
        ax: plt.Axes = None,  # pylint: disable=invalid-name
        **kwargs,
    ):
        """
        Description: Constructs an imshow object, defining the central portion
        of the 3-D image, and the axis that represents the slices. It uses the
        minimum (minv) and maximum value (maxv) to create a colorbar, and to
        define the colormap (cmap). An interactive image is created at the end,
        where scrolling through different slices is possible in the window plt.show().


        Args:
            fig: plt.Figure
                Figure object created from "fig, ax = plt.subplots()"
            ax: plt.Axes
                Axes object created from "fig, ax = plt.subplots()"
            img_array: Array, list, np.ndarray
                3-D array containing image
            overlay: A 3D array of the same shape as img_array to overlay atop
            slice_axis: int
                Axis where slices are located for a 3-D image (usually 0 or 2). Defaults to 0.
            overlay_args: Dictionary of arguments to pass to the overlay's imshow.
            **kwargs: any
                Arguments passed to matplotlib's imshow()
        """
        if fig is None and ax is None:
            fig, ax = plt.subplots()

        # Copy of matplotlib.axes.Axes object
        self.ax = ax  # pylint: disable=invalid-name
        # Axis of slice
        self._slice_axis = slice_axis
        # Define image array
        self.img_array = np.array(img_array)

        self.overlay_arrays = []
        self.overlay = []

        # Set shape of image array
        try:
            self.slices = self.img_array.shape[self._slice_axis]
        except IndexError as error:
            print(f"{error}: slice index must be 0, 1 or 2!")
        # Get the slice in the 'center' of stack
        self._ind = self.slices // 2

        # Construct an indexing tuple to have dynamic indexing
        # Avoids the use of slower <ndarray>.take()
        idx = [slice(None)] * self.img_array.ndim
        idx[self._slice_axis] = self._ind
        self.idx = idx

        # Define image object to show in Window
        # pylint: disable=invalid-name
        self.im = ax.imshow(self.img_array[tuple(idx)], **kwargs)

        # Define color-bar
        self.cb = plt.colorbar(self.im, extend="max")
        # Updates to center of 3-D image
        self._update()
        # Allows scrolling
        fig.canvas.mpl_connect("scroll_event", self._onscroll)

    def _onscroll(self, event):
        """
        Defines scrolling event.
        """
        if event.button == "up":
            self._ind = (self._ind + 1) % self.slices
        else:
            self._ind = (self._ind - 1) % self.slices
        self._update()

    def _update(self):
        """
        Updates image based on index self._ind.
        """
        idx = [slice(None)] * self.img_array.ndim
        idx[self._slice_axis] = self._ind

        self.im.set_data(self.img_array[tuple(idx)])
        if len(self.overlay) > 0:
            for overlay, overlay_array in zip(self.overlay, self.overlay_arrays):
                overlay.set_data(overlay_array[tuple(idx)])

        self.ax.set_ylabel(f"slice {self._ind}/{self.slices - 1}")
        self.im.axes.figure.canvas.draw()

    def add_overlay(self, overlay: np.ndarray, **kwargs) -> None:
        """
        method to add an overlay array on the main view.
        Pixels desired to be transparent should be set to numpy.NaN
        @param overlay: numpy array of the overlay
        @param kwargs: paramters for the imshow of the overlay
        """
        self.overlay_arrays.append(np.array(overlay))
        self.overlay.append(self.ax.imshow(overlay[tuple(self.idx)], **kwargs))

    @staticmethod
    def show():
        """
        Simple wrapper to open Window to show image.
        """
        plt.show()

    def colorbar(self, mappable: Union[ScalarMappable, None] = None, **kwargs):
        """
        Simple wrapper to define the colorbar.
        @param mappable: The matplotlib.cm.ScalarMappable
        (i.e., AxesImage, ContourSet, etc.) described by this colorbar
        """
        self.cb.remove()

        if mappable is None:
            mappable = self.im
        self.cb = plt.colorbar(mappable, **kwargs)

__init__(img_array, slice_axis=0, fig=None, ax=None, **kwargs)

Description: Constructs an imshow object, defining the central portion of the 3-D image, and the axis that represents the slices. It uses the minimum (minv) and maximum value (maxv) to create a colorbar, and to define the colormap (cmap). An interactive image is created at the end, where scrolling through different slices is possible in the window plt.show().

Args: fig: plt.Figure Figure object created from "fig, ax = plt.subplots()" ax: plt.Axes Axes object created from "fig, ax = plt.subplots()" img_array: Array, list, np.ndarray 3-D array containing image overlay: A 3D array of the same shape as img_array to overlay atop slice_axis: int Axis where slices are located for a 3-D image (usually 0 or 2). Defaults to 0. overlay_args: Dictionary of arguments to pass to the overlay's imshow. **kwargs: any Arguments passed to matplotlib's imshow()

Source code in pygrpm/visualization/index_tracker.py
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
def __init__(
    self,
    img_array,
    slice_axis: int = 0,
    fig: plt.Figure = None,
    ax: plt.Axes = None,  # pylint: disable=invalid-name
    **kwargs,
):
    """
    Description: Constructs an imshow object, defining the central portion
    of the 3-D image, and the axis that represents the slices. It uses the
    minimum (minv) and maximum value (maxv) to create a colorbar, and to
    define the colormap (cmap). An interactive image is created at the end,
    where scrolling through different slices is possible in the window plt.show().


    Args:
        fig: plt.Figure
            Figure object created from "fig, ax = plt.subplots()"
        ax: plt.Axes
            Axes object created from "fig, ax = plt.subplots()"
        img_array: Array, list, np.ndarray
            3-D array containing image
        overlay: A 3D array of the same shape as img_array to overlay atop
        slice_axis: int
            Axis where slices are located for a 3-D image (usually 0 or 2). Defaults to 0.
        overlay_args: Dictionary of arguments to pass to the overlay's imshow.
        **kwargs: any
            Arguments passed to matplotlib's imshow()
    """
    if fig is None and ax is None:
        fig, ax = plt.subplots()

    # Copy of matplotlib.axes.Axes object
    self.ax = ax  # pylint: disable=invalid-name
    # Axis of slice
    self._slice_axis = slice_axis
    # Define image array
    self.img_array = np.array(img_array)

    self.overlay_arrays = []
    self.overlay = []

    # Set shape of image array
    try:
        self.slices = self.img_array.shape[self._slice_axis]
    except IndexError as error:
        print(f"{error}: slice index must be 0, 1 or 2!")
    # Get the slice in the 'center' of stack
    self._ind = self.slices // 2

    # Construct an indexing tuple to have dynamic indexing
    # Avoids the use of slower <ndarray>.take()
    idx = [slice(None)] * self.img_array.ndim
    idx[self._slice_axis] = self._ind
    self.idx = idx

    # Define image object to show in Window
    # pylint: disable=invalid-name
    self.im = ax.imshow(self.img_array[tuple(idx)], **kwargs)

    # Define color-bar
    self.cb = plt.colorbar(self.im, extend="max")
    # Updates to center of 3-D image
    self._update()
    # Allows scrolling
    fig.canvas.mpl_connect("scroll_event", self._onscroll)

add_overlay(overlay, **kwargs)

method to add an overlay array on the main view. Pixels desired to be transparent should be set to numpy.NaN @param overlay: numpy array of the overlay @param kwargs: paramters for the imshow of the overlay

Source code in pygrpm/visualization/index_tracker.py
113
114
115
116
117
118
119
120
121
def add_overlay(self, overlay: np.ndarray, **kwargs) -> None:
    """
    method to add an overlay array on the main view.
    Pixels desired to be transparent should be set to numpy.NaN
    @param overlay: numpy array of the overlay
    @param kwargs: paramters for the imshow of the overlay
    """
    self.overlay_arrays.append(np.array(overlay))
    self.overlay.append(self.ax.imshow(overlay[tuple(self.idx)], **kwargs))

colorbar(mappable=None, **kwargs)

Simple wrapper to define the colorbar. @param mappable: The matplotlib.cm.ScalarMappable (i.e., AxesImage, ContourSet, etc.) described by this colorbar

Source code in pygrpm/visualization/index_tracker.py
130
131
132
133
134
135
136
137
138
139
140
def colorbar(self, mappable: Union[ScalarMappable, None] = None, **kwargs):
    """
    Simple wrapper to define the colorbar.
    @param mappable: The matplotlib.cm.ScalarMappable
    (i.e., AxesImage, ContourSet, etc.) described by this colorbar
    """
    self.cb.remove()

    if mappable is None:
        mappable = self.im
    self.cb = plt.colorbar(mappable, **kwargs)

show() staticmethod

Simple wrapper to open Window to show image.

Source code in pygrpm/visualization/index_tracker.py
123
124
125
126
127
128
@staticmethod
def show():
    """
    Simple wrapper to open Window to show image.
    """
    plt.show()