Manim&Napari#

[1]:
import napari
from skimage import data
import numpy as np
from manim import *
config.media_embed = True

viewer = napari.view_image(data.cells3d(), channel_axis=1, ndisplay=3)
viewer.camera.angles = (0, 0, 90)
Manim Community v0.17.2

3D Cells#

[2]:
def make_plot(zoom, angle1, angle2, angle3, parameter):
    viewer.camera.zoom = zoom
    viewer.camera.angles = (angle1, angle2, angle3)
    viewer.layers[0].gamma = parameter
    img = viewer.screenshot(canvas_only=True, flash=False)
    return img

class Example(Scene):
    def construct(self):
        self.camera.background_color = BLUE_A

        tr_zoom = ValueTracker(1)
        tr_angle1 = ValueTracker(0)
        tr_angle2 = ValueTracker(0)
        tr_angle3 = ValueTracker(90)
        tr_para = ValueTracker(1)

        image = ImageMobject(
            make_plot(
                tr_zoom.get_value(),
                tr_angle1.get_value(),
                tr_angle2.get_value(),
                tr_angle3.get_value(),
                tr_para.get_value(),
            )
        )
        self.add(image)

        def update_image(mob):
            new_mob = ImageMobject(
                make_plot(
                    tr_zoom.get_value(),
                    tr_angle1.get_value(),
                    tr_angle2.get_value(),
                    tr_angle3.get_value(),
                    tr_para.get_value(),
                )
            )
            mob.become(new_mob)

        image.add_updater(update_image)
        self.play(tr_zoom.animate.set_value(2), rate_func=smooth, run_time=1.0)
        self.play(
            tr_angle1.animate.set_value(20),
            tr_angle2.animate.set_value(-25),
            tr_angle3.animate.set_value(140),
            rate_func=smooth,
            run_time=1.0,
        )

        self.play(tr_para.animate.set_value(0.4), rate_func=smooth, run_time=0.5)
        self.wait(0.2)
        self.play(tr_para.animate.set_value(1), rate_func=smooth, run_time=0.5)
        self.play(tr_zoom.animate.set_value(1), rate_func=smooth, run_time=1.0)
        self.play(
                    tr_angle1.animate.set_value(0),
                    tr_angle2.animate.set_value(0),
                    tr_angle3.animate.set_value(90),
                    rate_func=smooth,
                    run_time=1.0,
                )
        self.wait(0.2)

%manim -v WARNING -qh --disable_caching --progress_bar None Example
[3]:
viewer = napari.view_image(data.cells3d(), channel_axis=1, ndisplay=3)
viewer.camera.angles = (0, 0, 90)

class Example(Scene):
    def construct(self):
        self.camera.background_color = BLUE_A
        img = viewer.screenshot(canvas_only=True, flash=False)
        t = ImageMobject(img)
        t.time = 0
        self.add(t)

        tr_zoom = ValueTracker(1)
        contrast_tracker = ValueTracker(65535) # dark limit

        def foo(mob,dt):
            mob.time += dt

        SECOND = 1

        def bar(mob):
            viewer.camera.angles = (0, 30*np.sin((mob.time*PI/11*2)), 50)
            viewer.camera.zoom = tr_zoom.get_value()

            viewer.layers[0].contrast_limits = (0, contrast_tracker.get_value())
            img = viewer.screenshot(canvas_only=True, flash=False)
            new_mob = ImageMobject(img)
            mob.become(new_mob)

        t.add_updater(foo)
        t.add_updater(bar)

        viewer.layers[1].opacity = 1
        self.play(tr_zoom.animate.set_value(2), rate_func=smooth, run_time=SECOND)
        self.play(contrast_tracker.animate.set_value(19500), rate_func=smooth, run_time=SECOND) #bright limit
        self.wait(SECOND)
        viewer.layers[1].opacity = 0
        self.play(tr_zoom.animate.set_value(4), rate_func=smooth, run_time=SECOND)
        self.wait(SECOND)
        self.wait(SECOND)
        self.play(tr_zoom.animate.set_value(2), rate_func=smooth, run_time=SECOND)
        self.wait(SECOND)
        viewer.layers[1].opacity = 1
        self.wait(SECOND)
        self.play(contrast_tracker.animate.set_value( 65535 ), rate_func=smooth, run_time=SECOND) #dark limit

        self.play(tr_zoom.animate.set_value(1), rate_func=smooth, run_time=SECOND)
        t.remove_updater(foo)
        self.wait(SECOND)

%manim -v WARNING -qh --disable_caching --progress_bar None Example

Cryo-electron tomography#

[4]:
import mrcfile
import napari
import numpy as np
import starfile
from scipy.spatial.transform import Rotation as R
config.media_embed = True
viewer = napari.Viewer(ndisplay=3)


# files from https://zenodo.org/record/6504891/#.ZAri4-zMJ6k
tomogram_file = '01_10.00Apx.mrc'
particles_file = '01_10.00Apx_particles.star'

with mrcfile.open(tomogram_file) as mrc:
    tomogram = mrc.data.copy()

df = starfile.read(particles_file)
xyz = df[['rlnCoordinateX', 'rlnCoordinateY', 'rlnCoordinateZ']].to_numpy()
euler_angles = df[['rlnAngleRot', 'rlnAngleTilt', 'rlnAnglePsi']].to_numpy()

rotations = R.from_euler(seq='ZYZ', angles=euler_angles, degrees=True).inv()
rotated_z_vectors = rotations.apply([0, 0, 1])

vectors = np.zeros((rotated_z_vectors.shape[0], 2, 3))

vectors[:, 0, :] = xyz[:, ::-1]
vectors[:, 1, :] = rotated_z_vectors[:, ::-1]

viewer.add_image(tomogram, blending='translucent_no_depth', colormap='gray_r')
viewer.add_points(xyz[:, ::-1], face_color='cornflowerblue', size=10)
viewer.add_vectors(vectors, length=10, edge_color='orange')

[4]:
<Vectors layer 'vectors' at 0x1ab07e6d0>
[5]:
def make_plot(zoom, angle1, angle2, angle3, parameter):
    viewer.camera.zoom = zoom
    viewer.camera.angles = (angle1, angle2, angle3)
    viewer.layers[0].opacity = parameter
    img = viewer.screenshot(canvas_only=True, flash=False)
    return img

class Example(Scene):
    def construct(self):
        self.camera.background_color = BLUE_A

        tr_zoom = ValueTracker(1)
        tr_angle1 = ValueTracker(0)
        tr_angle2 = ValueTracker(0)
        tr_angle3 = ValueTracker(90)
        tr_para = ValueTracker(1)

        image = ImageMobject(
            make_plot(
                tr_zoom.get_value(),
                tr_angle1.get_value(),
                tr_angle2.get_value(),
                tr_angle3.get_value(),
                tr_para.get_value(),
            )
        )
        self.add(image)

        def update_image(mob):
            new_mob = ImageMobject(
                make_plot(
                    tr_zoom.get_value(),
                    tr_angle1.get_value(),
                    tr_angle2.get_value(),
                    tr_angle3.get_value(),
                    tr_para.get_value(),
                )
            )
            mob.become(new_mob)

        image.add_updater(update_image)
        self.play(tr_zoom.animate.set_value(2), rate_func=smooth, run_time=1.0)
        self.play(
            tr_angle1.animate.set_value(20),
            tr_angle2.animate.set_value(-25),
            tr_angle3.animate.set_value(140),
            rate_func=smooth,
            run_time=1.0,
        )

        self.play(tr_para.animate.set_value(0), rate_func=smooth, run_time=0.5)
        self.wait(0.2)
        self.play(tr_para.animate.set_value(1), rate_func=smooth, run_time=0.5)
        self.play(tr_zoom.animate.set_value(1), rate_func=smooth, run_time=1.0)
        self.play(
                    tr_angle1.animate.set_value(0),
                    tr_angle2.animate.set_value(0),
                    tr_angle3.animate.set_value(90),
                    rate_func=smooth,
                    run_time=1.0,
                )
        self.wait(0.2)

%manim -v WARNING -qh --disable_caching --progress_bar None Example