Advanced#

Matplotlib an manim combined#

[1]:
from manim import *
import matplotlib.pyplot as plt

param   = "-v WARNING -s -ql --disable_caching --progress_bar None Example"
paramH  = "-v WARNING -s -qh --disable_caching --progress_bar None Example"
paramp  = "-v WARNING    -ql --disable_caching --progress_bar None Example"
parampH = "-v WARNING    -qh --disable_caching --progress_bar None Example"
Manim Community v0.15.2

[2]:
%%manim $paramp

plt.rcParams['figure.dpi'] = 100

def my_function(amplitude, x):
    return amplitude * np.sin(x)

def mpl_image_plt(amplitude, x):
    fig, ax = plt.subplots()
    ax.plot(x, my_function(amplitude, x))
    ax.set_ylim(-1, 1)
    fig.canvas.draw()
    img = ImageMobject(fig.canvas.buffer_rgba()).scale(2)
    plt.close(fig)
    return img

class Example(Scene):
    def construct(self):
        self.camera.background_color=WHITE
        x_values = np.linspace(0, 30, 400)
        amp1 = 0.5
        amp2 = 1
        tr_amplitude = ValueTracker(amp1)
        image = mpl_image_plt(amp1, x_values)
        self.add(image)

        def update_image(mob):
            new_mob = mpl_image_plt(tr_amplitude.get_value(), x_values)
            mob.become(new_mob)

        image.add_updater(update_image)
        self.play(tr_amplitude.animate.set_value(amp2), run_time=3)

[3]:
%%manim $paramp

plt.rcParams['figure.dpi'] = 300

class Example(Scene):
    def construct(self):
        self.camera.background_color= WHITE
        fig = plt.figure()
        ax = fig.add_subplot(projection='3d')
        x=np.full((21,27,27),0)
        x[10,10,10]=1
        x[10,16,10]=1
        ax.voxels(x, edgecolor='k')
        fig.canvas.draw()
        buf = fig.canvas.buffer_rgba()
        img = ImageMobject(buf).scale(1)
        plt.close(fig)
        self.add(img)
_images/ch8_3_0.png
[4]:
%%manim $paramp

plt.rcParams['figure.dpi'] = 300

def my_function(amplitude, x):
    return amplitude * np.sin(x)

def mpl_image3d_plt(amp1,x):
    fig = plt.figure()
    ax = fig.add_subplot(projection='3d')
    ax.view_init(elev=40+3*np.sin(amp1), azim=20+10*np.cos(amp1))
    ax.voxels(x, edgecolor='k')
    ax.axes.xaxis.set_ticklabels([])
    ax.axes.yaxis.set_ticklabels([])
    ax.axes.zaxis.set_ticklabels([])
    fig.canvas.draw()
    buf = fig.canvas.buffer_rgba()
    img = ImageMobject(buf).scale(1)
    plt.close(fig)
    return img


class Example(Scene):
    def construct(self):
        self.camera.background_color= WHITE
        x=np.full((21,27,27),0)
        x[10,10,10]=1
        x[10,16,10]=1
        amp1=0
        amp2=TAU
        tr_amplitude = ValueTracker(amp1)
        image = mpl_image3d_plt(amp1, x)
        self.add(image)

        def update_image(mob):
            new_mob = mpl_image3d_plt(tr_amplitude.get_value(), x)
            mob.become(new_mob)

        image.add_updater(update_image)
        self.play(tr_amplitude.animate.set_value(amp2), run_time=4)

Animations with OpenGL#

Just add the --renderer=opengl flag, and animations will render with the OpenGL backend, which is still under development. Here are two examples: one for rendering a video (needs additional the --write_to_movie flag) and one for a static 3D scene (including it)

[5]:
paramGL   = "-v WARNING -s -ql --renderer=opengl --disable_caching --progress_bar None Example"
paramHGL  = "-v WARNING -s -qh --renderer=opengl --disable_caching --progress_bar None Example"
parampGL  = "-v WARNING    -ql --renderer=opengl --write_to_movie --disable_caching --progress_bar None Example"
parampHGL = "-v WARNING    -qh --renderer=opengl --write_to_movie --disable_caching --progress_bar None Example"
[6]:
%%time
%%manim $parampHGL
class Example(Scene):
    def construct(self):
        dot= Dot(color= YELLOW, radius=0.5)
        self.play(dot.animate.shift(2*RIGHT).scale(2).set_color(BLUE))
        self.wait()
CPU times: user 1.13 s, sys: 449 ms, total: 1.58 s
Wall time: 11.8 s
[7]:
%%time
%%manim $parampGL
class Example(ThreeDScene):
    def construct(self):
        resolution_fa = 42
        self.set_camera_orientation(phi=75 * DEGREES, theta=-30 * DEGREES)

        def param_gauss(u, v):
            x = u
            y = v
            sigma, mu = 0.4, [0.0, 0.0]
            d = np.linalg.norm(np.array([x - mu[0], y - mu[1]]))
            z = np.exp(-(d ** 2 / (2.0 * sigma ** 2)))
            return np.array([x, y, z])

        gauss_plane = Surface(
            param_gauss,
            resolution=(resolution_fa, resolution_fa),
            v_range=[-2, +2],
            u_range=[-2, +2]
        )

        gauss_plane.scale(2, about_point=ORIGIN)
        gauss_plane.set_style(fill_opacity=1,stroke_color=GREEN)
        gauss_plane.set_fill_by_checkerboard(ORANGE, BLUE, opacity=0.5)
        axes = ThreeDAxes()
        self.add(axes,gauss_plane)
_images/ch8_8_0.png
CPU times: user 4.43 s, sys: 92.8 ms, total: 4.52 s
Wall time: 4.39 s
[8]:
%%time
%%manim $param
## comparison of the same example to cairo:
class Example(ThreeDScene):
    def construct(self):
        resolution_fa = 42
        self.set_camera_orientation(phi=75 * DEGREES, theta=-30 * DEGREES)

        def param_gauss(u, v):
            x = u
            y = v
            sigma, mu = 0.4, [0.0, 0.0]
            d = np.linalg.norm(np.array([x - mu[0], y - mu[1]]))
            z = np.exp(-(d ** 2 / (2.0 * sigma ** 2)))
            return np.array([x, y, z])

        gauss_plane = Surface(
            param_gauss,
            resolution=(resolution_fa, resolution_fa),
            v_range=[-2, +2],
            u_range=[-2, +2]
        )

        gauss_plane.scale(2, about_point=ORIGIN)
        gauss_plane.set_style(fill_opacity=1,stroke_color=GREEN)
        gauss_plane.set_fill_by_checkerboard(ORANGE, BLUE, opacity=0.5)
        axes = ThreeDAxes()
        self.add(axes,gauss_plane)
_images/ch8_9_0.png
CPU times: user 5.63 s, sys: 0 ns, total: 5.63 s
Wall time: 5.63 s
[ ]: