从 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)

方案对比与选择建议

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

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

相关推荐
程序猿小D2 小时前
【完整源码+数据集+部署教程】脑部CT图像分割系统源码和数据集:改进yolo11-CSwinTransformer
python·yolo·计算机视觉·数据集·yolo11·脑部ct图像分割
max5006002 小时前
北京大学MuMo多模态肿瘤分类模型复现与迁移学习
人工智能·python·机器学习·分类·数据挖掘·迁移学习
修一呀2 小时前
[后端快速搭建]基于 Django+DeepSeek API 快速搭建智能问答后端
后端·python·django
WSSWWWSSW2 小时前
Seaborn数据可视化实战:Seaborn数据可视化实战入门
python·信息可视化·数据挖掘·数据分析·matplotlib·seaborn
小石3 小时前
Python 装饰器核心知识点:无参装饰器构建、带参装饰器扩展及函数与类实现差异
python
老歌老听老掉牙4 小时前
Pandas DataFrame 列数操作完全指南
python·pandas
数据智能老司机4 小时前
Python 实战遗传算法——遗传算法导论
python·算法·机器学习
让心淡泊1445 小时前
DAY 58 经典时序预测模型2
python
love530love5 小时前
怎么更新 cargo.exe ?(Rust 工具链)
人工智能·windows·python·rust·r语言