Skip to content

Commit

Permalink
update visualize
Browse files Browse the repository at this point in the history
  • Loading branch information
bmandracchia committed Aug 28, 2024
1 parent feb99ce commit ded6451
Show file tree
Hide file tree
Showing 3 changed files with 2,404,658 additions and 47 deletions.
2 changes: 2 additions & 0 deletions bioMONAI/_modidx.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@
'bioMONAI.transforms._process_sz': ('transforms.html#_process_sz', 'bioMONAI/transforms.py')},
'bioMONAI.visualize': { 'bioMONAI.visualize._fig_bounds': ('visualize.html#_fig_bounds', 'bioMONAI/visualize.py'),
'bioMONAI.visualize.mosaic_image_3d': ('visualize.html#mosaic_image_3d', 'bioMONAI/visualize.py'),
'bioMONAI.visualize.plot_image': ('visualize.html#plot_image', 'bioMONAI/visualize.py'),
'bioMONAI.visualize.plot_volume': ('visualize.html#plot_volume', 'bioMONAI/visualize.py'),
'bioMONAI.visualize.show_images_grid': ('visualize.html#show_images_grid', 'bioMONAI/visualize.py'),
'bioMONAI.visualize.show_plane': ('visualize.html#show_plane', 'bioMONAI/visualize.py'),
'bioMONAI.visualize.slice_explorer': ('visualize.html#slice_explorer', 'bioMONAI/visualize.py'),
Expand Down
101 changes: 87 additions & 14 deletions bioMONAI/visualize.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/09_visualize.ipynb.

# %% auto 0
__all__ = ['mosaic_image_3d', 'show_images_grid', 'show_plane', 'visualize_slices', 'slice_explorer']
__all__ = ['plot_image', 'mosaic_image_3d', 'show_images_grid', 'show_plane', 'visualize_slices', 'slice_explorer', 'plot_volume']

# %% ../nbs/09_visualize.ipynb 3
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
import plotly.io as pio
import plotly.express as px
import plotly.graph_objects as go
from skimage import util
from skimage.data import cells3d
import torchvision
Expand All @@ -19,12 +20,44 @@
from .io import tiff2torch

# %% ../nbs/09_visualize.ipynb 6
def plot_image(values):
"""
Plot a 2D image using Matplotlib. The function assumes that 'values' is a 2D array representing an image, typically in grayscale.
Parameters:
values (numpy.ndarray): A 2D array of pixel values representing the image.
Returns:
None
"""
# Create a figure with Matplotlib
fig = plt.figure()

# Add an axis to the figure, which will be used for plotting the image
ax = fig.add_subplot(111)

# Display the image using imshow. The np.flipud function is applied to flip the array vertically,
# which is necessary because Matplotlib's default orientation might differ from NumPy's or Plotly's.
ax.imshow(np.flipud(values), cmap='gray')

# Turn off axis numbers and ticks for a cleaner visual appearance of the image
ax.axis('off')

# Display the figure with all defined elements
plt.show()


# Example usage:
plot_image(data[35])


# %% ../nbs/09_visualize.ipynb 8
# Utility function for determining figure bounds
def _fig_bounds(x):
r = x//8
return min(15, max(1,r))

# %% ../nbs/09_visualize.ipynb 7
# %% ../nbs/09_visualize.ipynb 9
def mosaic_image_3d(t: (np.ndarray, torchTensor),
axis: int = 0,
figsize: tuple = (15,15),
Expand Down Expand Up @@ -78,7 +111,7 @@ def mosaic_image_3d(t: (np.ndarray, torchTensor),
plt.imshow(grid[0,:,:], cmap=cmap, alpha=alpha)
plt.axis('off')

# %% ../nbs/09_visualize.ipynb 8
# %% ../nbs/09_visualize.ipynb 10
@delegates(plt.Axes.imshow, keep=True, but=['shape', 'imlim'])
def show_images_grid(images, ax=None, ncols=10, figsize=None, title=None, spacing=0.02, max_slices=3, ctx=None, **kwargs):
"""
Expand Down Expand Up @@ -151,7 +184,7 @@ def show_images_grid(images, ax=None, ncols=10, figsize=None, title=None, spacin

return ax

# %% ../nbs/09_visualize.ipynb 12
# %% ../nbs/09_visualize.ipynb 14
def show_plane(ax, plane, cmap="gray", title=None, lines=None, linestyle='--', linecolor='white'):
"""
Display a slice of the image tensor on a given axis with optional dashed lines.
Expand All @@ -175,7 +208,7 @@ def show_plane(ax, plane, cmap="gray", title=None, lines=None, linestyle='--', l
ax.axvline(lines[1], color=linecolor, linestyle=linestyle)


# %% ../nbs/09_visualize.ipynb 13
# %% ../nbs/09_visualize.ipynb 15
def visualize_slices(data, planes=None, showlines=True, **kwargs):
"""
Visualize slices of a 3D image tensor along its planes, rows, and columns.
Expand Down Expand Up @@ -210,8 +243,8 @@ def visualize_slices(data, planes=None, showlines=True, **kwargs):
plt.show()


# %% ../nbs/09_visualize.ipynb 16
def slice_explorer(data, width=500, height=500, **kwargs):
# %% ../nbs/09_visualize.ipynb 18
def slice_explorer(data, **kwargs):
"""
Visualizes the provided data using Plotly's interactive imshow function with animation support.
Expand All @@ -221,19 +254,59 @@ def slice_explorer(data, width=500, height=500, **kwargs):
Returns:
None: Displays the plot directly.
"""
fig = px.imshow(data, animation_frame=0, binary_string=True)

if len(data.shape) == 4:
fig = px.imshow(data, animation_frame=0, binary_string=True, labels=dict(animation_frame="slice", facet_col='channel'), facet_col=1)
elif len(data.shape) == 3:
fig = px.imshow(data, animation_frame=0, binary_string=True, labels=dict(animation_frame="slice"))
else:
raise ValueError("Input must be a 3D or 4D array.")

# Remove tick labels from axes
fig.update_xaxes(showticklabels=False)
fig.update_yaxes(showticklabels=False)

# Set custom size for the plot
fig.update_layout(autosize=False, width=width, height=height, **kwargs)

# Drop animation buttons as they are not supported in this specific configuration
fig['layout'].pop('updatemenus')

fig.update_layout(**kwargs, title_x=0.5)

# Display the plot using Plotly's show function
pio.show(fig)



# %% ../nbs/09_visualize.ipynb 21
def plot_volume(values, opacity=0.1, min=0.1, max=0.8, surface_count=5, width=800, height=600):
"""
Plot a 3D volume using Plotly. The function assumes that 'values' is a 3D array representing the volume data.
Parameters:
values (numpy.ndarray): A 3D array of pixel values representing the volume.
opacity (float, optional): Opacity level for the surfaces in the volume plot. Defaults to 0.1.
min (float, optional): Minimum threshold multiplier for the visualization. Defaults to 0.1.
max (float, optional): Maximum threshold multiplier for the visualization. Defaults to 0.8.
surface_count (int, optional): Number of surfaces to display in the volume plot. Defaults to 5.
width (int, optional): Width of the plotted figure. Defaults to 800.
height (int, optional): Height of the plotted figure. Defaults to 600.
Returns:
None
"""
# Generate coordinates based on the shape of the values array
X, Y, Z = np.mgrid[0:values.shape[0], 0:values.shape[1], 0:values.shape[2]]

# Create a Plotly figure with volume data
fig = go.Figure(data=go.Volume(
x=X.flatten(),
y=Y.flatten(),
z=Z.flatten(),
value=values.flatten(),
isomin=np.min(values) * min, # Adjust the minimum threshold for visualization
isomax=np.max(values) * max, # Adjust the maximum threshold for visualization
opacity=opacity, # needs to be small to see through all surfaces
surface_count=surface_count, # needs to be a large number for good volume rendering
))

# Update layout with specific width and height
fig.update_layout(width=width, height=height) # Adjust these values as needed

# Display the figure in a new window
fig.show()
Loading

0 comments on commit ded6451

Please sign in to comment.