def plot( self, view, sl=None, pos=None, ax=None, gs=None, figsize=None, zoom=None, zoom_centre=None, mpl_kwargs=None, show=True, colorbar=False, colorbar_label="HU", struct_kwargs=None, struct_plot_type=None, major_ticks=None, minor_ticks=None, ticks_all_sides=False, **kwargs, ): """Plot MultiImage and orthogonal view of main image and structs.""" self.set_axes(view, ax, gs, figsize, zoom, colorbar) # Plot the MultiImage MultiImage.plot( self, view, sl=sl, pos=pos, ax=self.ax, zoom=zoom, zoom_centre=zoom_centre, colorbar=colorbar, show=False, colorbar_label=colorbar_label, mpl_kwargs=mpl_kwargs, struct_kwargs=struct_kwargs, struct_plot_type=struct_plot_type, major_ticks=major_ticks, minor_ticks=minor_ticks, ticks_all_sides=ticks_all_sides, **kwargs, ) # Plot orthogonal view orthog_view = _orthog[view] orthog_sl = self.orthog_slices[_slider_axes[orthog_view]] Image.plot( self, orthog_view, sl=orthog_sl, ax=self.orthog_ax, mpl_kwargs=mpl_kwargs, show=False, colorbar=False, no_ylabel=True, no_title=True, major_ticks=major_ticks, minor_ticks=minor_ticks, ticks_all_sides=ticks_all_sides, ) # Plot structures on orthogonal image for struct in self.structs: if not struct.visible: continue plot_type = struct_plot_type if plot_type == "centroid": plot_type = "contour" elif plot_type == "filled centroid": plot_type = "filled" struct.plot( orthog_view, sl=orthog_sl, ax=self.orthog_ax, mpl_kwargs=struct_kwargs, plot_type=plot_type, no_title=True, ) # Plot indicator line pos = sl if not self.scale_in_mm else self.slice_to_pos(sl, _slider_axes[view]) if view == "x-y": full_y = ( self.extent[orthog_view][2:] if self.scale_in_mm else [0.5, self.n_voxels[_plot_axes[orthog_view][1]] + 0.5] ) self.orthog_ax.plot([pos, pos], full_y, "r") else: full_x = ( self.extent[orthog_view][:2] if self.scale_in_mm else [0.5, self.n_voxels[_plot_axes[orthog_view][0]] + 0.5] ) self.orthog_ax.plot(full_x, [pos, pos], "r") if show: plt.tight_layout() plt.show()
def test_nifti_image_zoom(): im = Image(arr) im.plot(zoom=(1, 2, 3), show=False) assert im.valid
def plot( self, view="x-y", sl=None, pos=None, ax=None, gs=None, figsize=None, zoom=None, zoom_centre=None, mpl_kwargs=None, n_date=1, show=True, colorbar=False, colorbar_label="HU", dose_kwargs=None, masked=False, invert_mask=False, mask_color="black", jacobian_kwargs=None, df_kwargs=None, df_plot_type="grid", df_spacing=30, struct_kwargs=None, struct_plot_type="contour", struct_legend=True, legend_loc="lower left", struct_plot_grouping=None, struct_to_plot=None, annotate_slice=None, major_ticks=None, minor_ticks=None, ticks_all_sides=False, ): """Plot a 2D slice of this image and all extra features. Parameters ---------- view : str Orientation in which to plot ("x-y"/"y-z"/"x-z"). sl : int, default=None Slice number. If <sl> and <pos> are both None, the middle slice will be plotted. pos : float, default=None Position in mm of the slice to plot (will be rounded to the nearest slice). If <sl> and <pos> are both None, the middle slice will be plotted. If <sl> and <pos> are both given, <sl> supercedes <pos>. ax : matplotlib.pyplot.Axes, default=None Axes on which to plot. If None, new axes will be created. gs : matplotlib.gridspec.GridSpec, default=None If not None and <ax> is None, new axes will be created on the current matplotlib figure with this gridspec. figsize : float, default=None Figure height in inches; only used if <ax> and <gs> are None. If None, the value in _default_figsize will be used. zoom : int/float/tuple, default=None Factor by which to zoom in. If a single int or float is given, the same zoom factor will be applied in all directions. If a tuple of three values is given, these will be used as the zoom factors in each direction in the order (x, y, z). If None, the image will not be zoomed in. mpl_kwargs : dict, default=None Dictionary of keyword arguments to pass to matplotlib.imshow() for the main image. show : bool, default=True If True, the plotted figure will be shown via matplotlib.pyplot.show(). colorbar : bool, default=True If True, a colorbar will be drawn alongside the plot. dose_kwargs : dict, default=None Dictionary of keyword arguments to pass to matplotlib.imshow() for the dose field. masked : bool, default=False If True and this object has attribute self.data_mask assigned, the image will be masked with the array in self.data_mask. invert_mask : bool, default=True If True and a mask is applied, the mask will be inverted. mask_color : matplotlib color, default="black" color in which to plot masked areas. mask_threshold : float, default=0.5 Threshold on mask array; voxels with values below this threshold will be masked (or values above, if <invert_mask> is True). jacobian_kwargs : dict, default=None Dictionary of keyword arguments to pass to matplotlib.imshow() for the jacobian determinant. df_kwargs : dict, default=None Dictionary of keyword arguments to pass to matplotlib.imshow() for the deformation field. df_plot_type : str, default="grid" Type of plot ("grid"/"quiver") to produce for the deformation field. df_spacing : int/float/tuple, default=30 Grid spacing for the deformation field plot. If self.scale_in_mm is true, the spacing will be in mm; otherwise in voxels. Can be either a single value for all directions, or a tuple of values for each direction in order (x, y, z). struct_kwargs : dict, default=None Dictionary of keyword arguments to pass to matplotlib for structure plotting. struct_plot_type : str, default="contour" Plot type for structures ("contour"/"mask"/"filled") struct_legend : bool, default=True If True, a legend will be drawn labelling any structrues visible on this slice. legend_loc : str, default='lower left' Position for the structure legend, if used. annotate_slice : str, default=None Color for annotation of slice number. If None, no annotation will be added. If True, the default color (white) will be used. """ # Set date if self.timeseries: self.set_date(n_date) # Plot image self.set_ax(view, ax, gs, figsize, zoom, colorbar) Image.plot( self, view, sl, pos, ax=self.ax, mpl_kwargs=mpl_kwargs, show=False, colorbar=colorbar, colorbar_label=colorbar_label, masked=masked, invert_mask=invert_mask, mask_color=mask_color, figsize=figsize, major_ticks=major_ticks, minor_ticks=minor_ticks, ticks_all_sides=ticks_all_sides, ) # Plot dose field self.dose.plot( view, self.sl, ax=self.ax, mpl_kwargs=self.get_kwargs(dose_kwargs, default=self.dose_kwargs), show=False, masked=masked, invert_mask=invert_mask, mask_color=mask_color, colorbar=colorbar, colorbar_label="Dose (Gy)", ) # Plot jacobian self.jacobian.plot( view, self.sl, ax=self.ax, mpl_kwargs=self.get_kwargs(jacobian_kwargs, default=self.jacobian_kwargs), show=False, colorbar=colorbar, colorbar_label="Jacobian determinant", ) # Plot standalone structures and comparisons for s in self.standalone_structs: s.plot( view, self.sl, ax=self.ax, mpl_kwargs=struct_kwargs, plot_type=struct_plot_type, ) for s in self.struct_comparisons: if struct_plot_grouping == "group others": if s.s1.name_unique != struct_to_plot: continue s.plot( view, self.sl, ax=self.ax, mpl_kwargs=struct_kwargs, plot_type=struct_plot_type, plot_grouping=struct_plot_grouping, ) # Plot deformation field self.df.plot( view, self.sl, ax=self.ax, mpl_kwargs=df_kwargs, plot_type=df_plot_type, spacing=df_spacing, ) # Draw structure legend if struct_legend and struct_plot_type != "none": handles = [] for s in self.structs: if struct_plot_grouping == "group others": if s.name_unique == struct_to_plot: handles.append(mpatches.Patch(color=s.color, label=s.name_nice)) handles.append(mpatches.Patch(color="white", label="Others")) elif s.visible and s.on_slice(view, self.sl): handles.append(mpatches.Patch(color=s.color, label=s.name_nice)) if len(handles): self.ax.legend( handles=handles, loc=legend_loc, facecolor="white", framealpha=1 ) self.adjust_ax(view, zoom, zoom_centre) self.label_ax(view, annotate_slice=annotate_slice) # Display image if show: plt.tight_layout() plt.show()
def test_nifti_image_plot(): im = Image(arr) im.plot("x-y", 25, show=False, colorbar=True)