问题描述
我正在尝试为 jupyter notebook 编写一个神奇的函数,它可以让我直接在 notebook 中看到 manim
的输出。
为了实现这一点,我基本上将单元格的内容保存到临时 .py
文件中,然后使用临时 manimce
文件在子进程中调用 .py
命令并检查输出找到创建的视频/gif 的路径。
我的问题是,假设我在其他单元格(甚至导入语句)中声明了一些其他变量,并且我在调用我的魔术函数的单元格中使用它们。我怎样才能将这些变量(或基本上是代码)从同一个临时 .py
文件中的其他单元格保存,以便我不会出错?或者有什么其他方式可以实现?希望下面的屏幕截图能更好地解释我想问的问题。
这是我使用的代码:
# manimce_magic.py
from IPython.core.display import display,HTML
from IPython.core.magic import Magics,magics_class,line_magic,cell_magic,line_cell_magic
from IPython.core.magic import needs_local_scope
from pathlib import Path
from subprocess import Popen,PIPE
from tempfile import NamedTemporaryFile
import IPython.display
import os
import re
def find_path(output_string):
output_string = output_string.decode('utf-8')
output_string = re.sub(' ','',''.join(output_string.split('\n')))
if m := re.search('(?<=Filereadyat).+(?=INFO)',output_string):
return m.group(0)
@magics_class
class ManimceMagic(Magics):
@needs_local_scope
@cell_magic
def manimce(self,line,cell,**kwargs):
manimce_args = line.split()
f = NamedTemporaryFile('r+',suffix='.py',delete=False)
try:
f.write(cell)
f.close()
args = ['manimce',f.name,*manimce_args]
p = Popen(args,stdout=PIPE,stdin=PIPE,stderr=PIPE)
output,err = p.communicate()
path = find_path(output)
display(IPython.display.Code(output.decode('utf-8'),language='python3'))
display(p.returncode)
finally:
os.remove(f.name)
if path:
path = Path(path)
relative_path = path.relative_to(Path.cwd())
if '-i' in manimce_args:
return IPython.display.Image(relative_path,width=854,height=480)
else:
return IPython.display.Video(relative_path,height=480,html_attributes='controls loop autoplay')
def load_ipython_extension(ipython):
ipython.register_magics(ManimceMagic)
解决方法
我无法回答您的具体问题,但也许这会有所帮助。我相信当前版本的 manim 已经带有 manim 魔法命令。我已经试过了,它似乎工作正常。我让它工作,我首先运行 import jupyter_manim
,然后在一个新单元格中,我编写我的程序,从魔术命令 %%manim TestClass -p -ql
开始,其中 TestClass
是我的动画名称正在建设。 Manim 输出显示在 Jupyter 笔记本中。