从 Manim 中提取表格 / 坐标系并转 GIF:实用方案与核心代码

在数据可视化和数学动画创作中,我们经常需要将 Manim 动画中的表格、坐标系等核心元素单独导出为 GIF。本文整理了四种高效方案,每种方案仅提供核心代码,聚焦关键实现逻辑。

方案 1:代码级筛选与渲染

通过 AST 解析技术过滤掉文字和公式,保留目标元素代码并导出。 核心代码(筛选逻辑):

python 复制代码
import ast
from ast import NodeTransformer

class ManimElementFilter(NodeTransformer):
    # 保留的元素类型
    PRESERVE = {"Axes", "Table", "BarChart"}
    # 移除的文字公式类型
    REMOVE = {"Text", "MathTex", "Tex"}

    def visit_Call(self, node):
        # 移除文字公式创建代码
        if isinstance(node.func, ast.Name) and node.func.id in self.REMOVE:
            return None
        
        # 过滤方法调用中的文字参数
        if (isinstance(node.func, ast.Attribute) and 
            node.func.value.id == "self" and 
            node.func.attr in ["add", "play"]):
            
            node.args = [arg for arg in node.args 
                        if not (isinstance(arg, ast.Call) and 
                                isinstance(arg.func, ast.Name) and 
                                arg.func.id in self.REMOVE)]
        
        return node

使用方式:

python 复制代码
# 处理代码
tree = ast.parse(original_code)
filtered_tree = ManimElementFilter().visit(tree)
# 添加相机聚焦逻辑并导出GIF

方案 2:运行时对象筛选

通过自定义场景类,在渲染时自动过滤不需要的元素。 核心代码(自定义场景):

python 复制代码
from manimlib.scene.scene import Scene

class ElementExtractingScene(Scene):
    # 目标元素类型
    target_types = (Axes, Table, BarChart)
    
    def setup(self):
        super().setup()
        self.original_construct = self.construct
        self.construct = self.filtered_construct
    
    def filtered_construct(self):
        # 执行原始构造逻辑
        self.original_construct()
        # 筛选目标元素
        self.mobjects = [m for m in self.mobjects 
                        if isinstance(m, self.target_types)]
        # 调整相机
        if self.mobjects:
            self.camera.frame.move_to(self.mobjects[0].get_center())
            self.camera.frame.set_height(max(m.get_height() for m in self.mobjects) * 1.2)

使用方式:

python 复制代码
# 修改原场景继承
class MyScene(ElementExtractingScene):
    # 原场景代码不变

方案 3:视频帧后处理

对已渲染的视频进行图像处理,识别并提取目标区域。 核心代码(元素识别):

python 复制代码
import cv2
import numpy as np

def detect_table_region(frame):
    """检测表格区域"""
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    edges = cv2.Canny(gray, 50, 150)
    
    # 检测直线(表格线特征)
    lines = cv2.HoughLinesP(edges, 1, np.pi/180, 100, 
                           minLineLength=50, maxLineGap=10)
    
    if lines is None:
        return None
        
    # 计算边界框
    min_x = np.min(lines[:, :, 0])
    max_x = np.max(lines[:, :, 2])
    min_y = np.min(lines[:, :, 1])
    max_y = np.max(lines[:, :, 3])
    
    return (min_y, max_y, min_x, max_x)

def create_gif_from_roi(frames, roi, output_path):
    """从ROI区域创建GIF"""
    min_y, max_y, min_x, max_x = roi
    # 裁剪所有帧并合成GIF
    # ...

方案 4:标记式提取

在创建元素时主动标记,后续专用工具提取标记元素。 核心代码(标记工具):

python 复制代码
class ElementMarker:
    def __init__(self):
        self.marked = {}
    
    def mark(self, element, name=None, **kwargs):
        """标记元素并附加导出参数"""
        name = name or f"element_{len(self.marked)}"
        self.marked[name] = (element, kwargs)
        return element  # 不影响原有代码

# 使用示例
class MyScene(Scene):
    def construct(self):
        marker = ElementMarker()
        
        # 标记表格
        table = marker.mark(
            Table([["A", "B"], ["C", "D"]]),
            name="data_table", type="table"
        )
        
        # 标记坐标系
        axes = marker.mark(
            Axes(x_range=[0, 10], y_range=[0, 10]),
            name="main_axes", type="axes"
        )
        
        # 导出逻辑
        self.export_marked(marker)

方案对比与选择建议

方案 核心优势 适用场景
代码级筛选 精度最高,保留完整动画 代码规范、批量处理
运行时筛选 无需修改原代码 快速验证、中等复杂度场景
视频后处理 不依赖源代码 仅有视频文件的情况
标记式提取 灵活可控,支持复杂元素 长期项目、需精细控制

实际应用中,推荐优先使用 "运行时筛选" 方案(平衡实现难度和效果),或 "标记式提取" 方案(适合长期维护的项目)。 所有方案均可结合批处理脚本实现多文件自动化处理,根据实际需求调整参数即可获得理想效果。

相关推荐
databook12 小时前
Manim实现闪光轨迹特效
后端·python·动效
Juchecar13 小时前
解惑:NumPy 中 ndarray.ndim 到底是什么?
python
用户83562907805114 小时前
Python 删除 Excel 工作表中的空白行列
后端·python
Json_14 小时前
使用python-fastApi框架开发一个学校宿舍管理系统-前后端分离项目
后端·python·fastapi
数据智能老司机20 小时前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机21 小时前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机21 小时前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机21 小时前
精通 Python 设计模式——性能模式
python·设计模式·架构
c8i1 天前
drf初步梳理
python·django
每日AI新事件1 天前
python的异步函数
python