Heat kernel signature on cells#

from skimage import data, morphology
import napari
import napari_shape_odyssey as nso
import napari_segment_blobs_and_things_with_membranes as nsbatwm
import napari_process_points_and_surfaces as nppas
from napari_threedee.visualization.lighting_control import LightingControl

import pyclesperanto_prototype as cle
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import matplotlib as mpl
import numpy as np
import tqdm
import os
import pandas as pd
from sklearn.decomposition import PCA
viewer = napari.Viewer(ndisplay=3)
Invalid schema for package 'napari-stl-exporter', please run 'npe2 validate napari-stl-exporter' to check for manifest errors.
WARNING: QWindowsWindow::setGeometry: Unable to set geometry 6886x2120+1280+560 (frame: 6912x2191+1267+502) on QWidgetWindow/"_QtMainWindowClassWindow" on "\\.\DISPLAY1". Resulting geometry: 6886x2119+1280+560 (frame: 6912x2190+1267+502) margins: 13, 58, 13, 13 minimum size: 385x499 MINMAXINFO maxSize=0,0 maxpos=0,0 mintrack=796,1069 maxtrack=0,0)

Segmentation#

image = data.cells3d()
nuclei = image[:, 1]
membranes = image[:, 0]

segmentation = nsbatwm.voronoi_otsu_labeling(nuclei, 10, 2)
segmentation = np.asarray(cle.dilate_labels(segmentation, None, radius=1))
segmentation = morphology.area_closing(segmentation, 100, connectivity=1)

# turn pixels at edge of segmentation to zero with numpy
segmentation[0, :, :] = 0
segmentation[-1, :, :] = 0
segmentation[:, 0, :] = 0
segmentation[:, -1, :] = 0
segmentation[:, :, 0] = 0
segmentation[:, :, -1] = 0
viewer.add_image(nuclei, name='nuclei', colormap='bop blue', blending='additive')
viewer.add_image(membranes, name='membranes', colormap='bop orange', blending='additive')
viewer.add_labels(segmentation, name='segmentation', opacity=0.5)
<Labels layer 'segmentation' at 0x1f96e4ad130>

Surface conversion#

label_1 = 23
label_2 = 2
label_3 = 14
label_4 = 18
surface_1 = nppas.label_to_surface(segmentation, label_1)
surface_2 = nppas.label_to_surface(segmentation, label_2)
surface_3 = nppas.label_to_surface(segmentation, label_3)
surface_4 = nppas.label_to_surface(segmentation, label_4)

surface_1_smooth = nppas.remove_duplicate_vertices(nppas.smooth_surface(surface_1))
surface_2_smooth = nppas.remove_duplicate_vertices(nppas.smooth_surface(surface_2))
surface_3_smooth = nppas.remove_duplicate_vertices(nppas.smooth_surface(surface_3))
surface_4_smooth = nppas.remove_duplicate_vertices(nppas.smooth_surface(surface_4))

viewer.add_surface(surface_1_smooth, name='surface_1')
viewer.add_surface(surface_2_smooth, name='surface_2')
viewer.add_surface(surface_3_smooth, name='surface_3')
viewer.add_surface(surface_4_smooth, name='surface_4')
<Surface layer 'surface_4' at 0x1f9236aae80>

Label 1#

times = np.linspace(0, 2500, 50)
signature = nso.signatures.heat_kernel_signature(surface_1_smooth, times = times)
df = pd.DataFrame(signature, columns = [f'time_{i}' for i in range(signature.shape[1])])
viewer.layers['surface_1'].features = df
points = [1, 500, 2000, 6493]
colors = ['magenta', 'darkgreen', 'cyan', 'orange']
mpl.style.use('default')
fig, ax = plt.subplots(figsize=(10, 5))
for point, color in zip(points, colors):
    ax.plot(times, signature[point], color=color, linewidth=3)
    viewer.add_points(surface_1_smooth[0][point], name='points', size=3, face_color=color)

ax.set_xlabel('Time [a.u.]', fontsize=24)
ax.set_ylabel('Heat [a.u.]', fontsize=24)
ax.set_ylim(0.0001, 0.000135)
ax.set_yticks([])
ax.set_xticks([])
ax.set_xlim(0, times[-1])

fig.tight_layout()
fig.savefig('./images/heat_kernel_signature_label1.png', dpi=300)
../../_images/dcc21489f05aff6021177ab703c8fa0808e3e5aeeba2413c8edd07d4b381f47c.png
viewer.camera.angles = (125, -41, 51)
viewer.camera.zoom = 20
viewer.camera.center = (36, 88, 56)
screenshots = []
for idx, t in enumerate(times):
    _surf = list(viewer.layers['surface_1'].data)
    _surf[2] = df[f'time_{idx}'].values
    viewer.layers['surface_1'].data = tuple(_surf)
    viewer.layers['surface_1'].contrast_limits = (0.0001, 0.00013)

    screenshots.append(viewer.screenshot())
fig, ax = plt.subplots(figsize=(10, 10))
ax.axis('off')
im = ax.imshow(screenshots[0])

def animate(i):
    im.set_data(screenshots[i])

ani = animation.FuncAnimation(fig, animate, frames=len(screenshots), interval=100)
ani.save('./images/heat_kernel_signature.gif', writer='imagemagick', fps=10, dpi=300)
MovieWriter imagemagick unavailable; using Pillow instead.
../../_images/81f751068325ef98b3de42d648f6f4e8a30d1854d171da5f7d0723ce1646c7d3.png

Label 2#

signature = nso.signatures.heat_kernel_signature(surface_3_smooth, times = times)
df = pd.DataFrame(signature, columns = [f'time_{i}' for i in range(signature.shape[1])])
viewer.layers['surface_3'].features = df
viewer.camera.angles = (125, -41, 51)
viewer.camera.zoom = 20
viewer.camera.center = (34.263706, 157.35388 , 110.837875)

screenshots = []
for idx, t in enumerate(times):
    _surf = list(viewer.layers['surface_3'].data)
    _surf[2] = df[f'time_{idx}'].values
    viewer.layers['surface_3'].data = tuple(_surf)
    viewer.layers['surface_3'].contrast_limits = (0.0001, 0.00013)

    screenshots.append(viewer.screenshot())
fig, ax = plt.subplots(figsize=(10, 10))
ax.axis('off')
im = ax.imshow(screenshots[0])

def animate(i):
    im.set_data(screenshots[i])

ani = animation.FuncAnimation(fig, animate, frames=len(screenshots), interval=100)
ani.save('./images/heat_kernel_signature_label2.gif', writer='imagemagick', fps=10, dpi=300)
MovieWriter imagemagick unavailable; using Pillow instead.
../../_images/e7e6da91935a7a58103450509512adbe62871123a0195c0e5285351453f38e76.png
points = [1, 500, 2000, 6000]
colors = ['magenta', 'darkgreen', 'cyan', 'orange']
mpl.style.use('default')
fig, ax = plt.subplots(figsize=(10, 5))
for point, color in zip(points, colors):
    ax.plot(times, signature[point], color=color, linewidth=3)
    #viewer.add_points(surface_3_smooth[0][point], name='points', size=3, face_color=color)

ax.set_xlabel('Time [a.u.]', fontsize=24)
ax.set_ylabel('Heat [a.u.]', fontsize=24)
ax.set_xlim(0, times[-1])

ax.set_ylim(0.0001, 0.000135)
ax.set_yticks([])
ax.set_xticks([])

fig.tight_layout()
fig.savefig('./images/heat_kernel_signature_label2.png', dpi=300)
../../_images/b0c11caef7b20bc33410ffaae32b3e5c30fff7797fbdfa4fea1b2a28d65b4c3a.png
_surf = list(viewer.layers['surface_1'].data)
_surf[2] = viewer.layers['surface_1'].features['PC_1'].values
viewer.layers['surface_1'].data = tuple(_surf)
WARNING: Error drawing visual <vispy.visuals.mesh.MeshVisual object at 0x000001F967597760>
WARNING: Error drawing visual <vispy.visuals.mesh.MeshVisual object at 0x000001F967597760>
WARNING: Error drawing visual <vispy.visuals.mesh.MeshVisual object at 0x000001F967597760>
WARNING: Error drawing visual <vispy.visuals.mesh.MeshVisual object at 0x000001F967597760>