You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Manim中制作带丰富色图的类Matlab/Octave风格曲面图动画?

实现Manim中类似Octave风格的3D曲面动画(带丰富色图)

1. 从Octave导出计算数据

先把Octave中计算好的X、Y网格矩阵和对应的Z高度矩阵导出,方便Manim读取:

  • 导出为CSV文件(适合小数据):
    在Octave中执行:
    csvwrite("x_data.csv", X);
    csvwrite("y_data.csv", Y);
    csvwrite("z_data.csv", Z);
    
  • 导出为numpy兼容的.npy文件(适合大数据,读写更快):
    先在Octave中安装octave-numpy包,然后执行:
    save("-npy", "x_data.npy", X);
    save("-npy", "y_data.npy", Y);
    save("-npy", "z_data.npy", Z);
    

2. 在Manim中实现丰富色图

Manim的Surface类支持自定义颜色映射,完全可以复刻Octave/Matlab的色图效果,无需局限于默认棋盘格:

方法1:直接使用Matplotlib色图

Manim兼容Matplotlib的所有色图(比如viridis、plasma、jet等,和Octave内置色图对应),只需导入Matplotlib的颜色映射模块:

from manim import *
import matplotlib.cm as cm
import numpy as np

class CustomSurface(ThreeDScene):
    def construct(self):
        # 从Octave导出的文件读取数据
        X = np.load("x_data.npy")
        Y = np.load("y_data.npy")
        Z = np.load("z_data.npy")

        # 创建带自定义色图的曲面
        surface = Surface(
            lambda u, v: np.array([X[u, v], Y[u, v], Z[u, v]]),
            u_range=(0, X.shape[0]-1),
            v_range=(0, X.shape[1]-1),
            color_map=cm.viridis,  # 这里替换成你需要的色图,比如cm.jet
            fill_opacity=1
        )

        # 设置俯视视角
        self.set_camera_orientation(phi=0 * DEGREES, theta=-90 * DEGREES)
        self.add(surface)
        self.wait()

方法2:自定义颜色渐变

如果需要完全自定义色图,可以通过get_color方法手动映射Z值到颜色:

from manim import *
import numpy as np

class CustomColoredSurface(ThreeDScene):
    def construct(self):
        X = np.load("x_data.npy")
        Y = np.load("y_data.npy")
        Z = np.load("z_data.npy")

        # 归一化Z值到0-1范围
        z_min, z_max = Z.min(), Z.max()
        norm_z = (Z - z_min) / (z_max - z_min)

        # 自定义颜色映射函数
        def get_color(u, v):
            z_val = norm_z[u, v]
            # 从蓝色到红色的渐变,可根据需求调整
            return interpolate_color(BLUE, RED, z_val)

        surface = Surface(
            lambda u, v: np.array([X[u, v], Y[u, v], Z[u, v]]),
            u_range=(0, X.shape[0]-1),
            v_range=(0, X.shape[1]-1),
            get_color=get_color,
            fill_opacity=1
        )

        self.set_camera_orientation(phi=0 * DEGREES, theta=-90 * DEGREES)
        self.add(surface)
        self.wait()

3. 添加动画效果

要制作曲面的动态展示,比如从平面升起、颜色渐变动画等,示例如下:

from manim import *
import matplotlib.cm as cm
import numpy as np

class SurfaceAnimation(ThreeDScene):
    def construct(self):
        X = np.load("x_data.npy")
        Y = np.load("y_data.npy")
        Z = np.load("z_data.npy")
        z_min = Z.min()

        # 初始平面(Z值为最小值)
        initial_surface = Surface(
            lambda u, v: np.array([X[u, v], Y[u, v], z_min]),
            u_range=(0, X.shape[0]-1),
            v_range=(0, X.shape[1]-1),
            color_map=cm.viridis,
            fill_opacity=1
        )

        # 目标曲面
        target_surface = Surface(
            lambda u, v: np.array([X[u, v], Y[u, v], Z[u, v]]),
            u_range=(0, X.shape[0]-1),
            v_range=(0, X.shape[1]-1),
            color_map=cm.viridis,
            fill_opacity=1
        )

        self.set_camera_orientation(phi=0 * DEGREES, theta=-90 * DEGREES)
        self.add(initial_surface)
        # 播放从平面到目标曲面的过渡动画
        self.play(Transform(initial_surface, target_surface), run_time=3)
        self.wait()

关键注意事项

  • 确保Octave导出的X、Y、Z矩阵维度一致,Manim的Surface要求输入的网格坐标和高度一一对应。
  • 调整phi和theta参数可以精准设置俯视视角,phi=0对应完全俯视,theta=-90调整水平朝向。
  • 如果使用CSV文件读取,需要用np.genfromtxt替代np.load,注意处理数据格式。

内容的提问来源于stack exchange,提问作者Redsbefall

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 17:15:37