Python從Manim中提取表格/坐標系并轉(zhuǎn)GIF的四種高效方案
引言
在數(shù)據(jù)可視化和數(shù)學(xué)動畫創(chuàng)作中,我們經(jīng)常需要將 Manim 動畫中的表格、坐標系等核心元素單獨導(dǎo)出為 GIF。本文整理了四種高效方案,每種方案僅提供核心代碼,聚焦關(guān)鍵實現(xiàn)邏輯。
方案 1:代碼級篩選與渲染
通過 AST 解析技術(shù)過濾掉文字和公式,保留目標元素代碼并導(dǎo)出。 核心代碼(篩選邏輯):
import ast
from ast import NodeTransformer
class ManimElementFilter(NodeTransformer):
# 保留的元素類型
PRESERVE = {"Axes", "Table", "BarChart"}
# 移除的文字公式類型
REMOVE = {"Text", "MathTex", "Tex"}
def visit_Call(self, node):
# 移除文字公式創(chuàng)建代碼
if isinstance(node.func, ast.Name) and node.func.id in self.REMOVE:
return None
# 過濾方法調(diào)用中的文字參數(shù)
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
使用方式:
# 處理代碼 tree = ast.parse(original_code) filtered_tree = ManimElementFilter().visit(tree) # 添加相機聚焦邏輯并導(dǎo)出GIF
方案 2:運行時對象篩選
通過自定義場景類,在渲染時自動過濾不需要的元素。 核心代碼(自定義場景):
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):
# 執(zhí)行原始構(gòu)造邏輯
self.original_construct()
# 篩選目標元素
self.mobjects = [m for m in self.mobjects
if isinstance(m, self.target_types)]
# 調(diào)整相機
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)
使用方式:
# 修改原場景繼承
class MyScene(ElementExtractingScene):
# 原場景代碼不變
方案 3:視頻幀后處理
對已渲染的視頻進行圖像處理,識別并提取目標區(qū)域。 核心代碼(元素識別):
import cv2
import numpy as np
def detect_table_region(frame):
"""檢測表格區(qū)域"""
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區(qū)域創(chuàng)建GIF"""
min_y, max_y, min_x, max_x = roi
# 裁剪所有幀并合成GIF
# ...
方案 4:標記式提取
在創(chuàng)建元素時主動標記,后續(xù)專用工具提取標記元素。 核心代碼(標記工具):
class ElementMarker:
def __init__(self):
self.marked = {}
def mark(self, element, name=None, **kwargs):
"""標記元素并附加導(dǎo)出參數(shù)"""
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"
)
# 導(dǎo)出邏輯
self.export_marked(marker)
方案對比與選擇建議
| 方案 | 核心優(yōu)勢 | 適用場景 |
|---|---|---|
| 代碼級篩選 | 精度最高,保留完整動畫 | 代碼規(guī)范、批量處理 |
| 運行時篩選 | 無需修改原代碼 | 快速驗證、中等復(fù)雜度場景 |
| 視頻后處理 | 不依賴源代碼 | 僅有視頻文件的情況 |
| 標記式提取 | 靈活可控,支持復(fù)雜元素 | 長期項目、需精細控制 |
實際應(yīng)用中,推薦優(yōu)先使用 "運行時篩選" 方案(平衡實現(xiàn)難度和效果),或 "標記式提取" 方案(適合長期維護的項目)。 所有方案均可結(jié)合批處理腳本實現(xiàn)多文件自動化處理,根據(jù)實際需求調(diào)整參數(shù)即可獲得理想效果。
到此這篇關(guān)于Python從Manim中提取表格/坐標系并轉(zhuǎn)GIF的四種高效方案的文章就介紹到這了,更多相關(guān)Python Manim提取表格并轉(zhuǎn)GIF內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Django批量查詢優(yōu)化的多種實現(xiàn)方案
在 Django 中處理大規(guī)模數(shù)據(jù)集時,批量查詢是提升性能的關(guān)鍵技術(shù),以下是完整的批量查詢實現(xiàn)方案,涵蓋從基礎(chǔ)到高級的各種場景,需要的朋友可以參考下2025-07-07
python:接口間數(shù)據(jù)傳遞與調(diào)用方法
今天小編就為大家分享一篇python:接口間數(shù)據(jù)傳遞與調(diào)用方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-12-12
Python寫的Discuz7.2版faq.php注入漏洞工具
這篇文章主要介紹了Python寫的Discuz7.2版faq.php注入漏洞工具,全自動的一款注入工具,針對Discuz7.2版,需要的朋友可以參考下2014-08-08
Python機器學(xué)習(xí)庫scikit-learn入門開發(fā)示例
scikit-learn是一個開源Python語言機器學(xué)習(xí)工具包,它涵蓋了幾乎所有主流機器學(xué)習(xí)算法的實現(xiàn),并且提供了一致的調(diào)用接口。它基于Numpy和scipy等Python數(shù)值計算庫,提供了高效的算法實現(xiàn)2022-07-07

