如何解决Celluloid库椭圆轨迹动画在Jupyter Notebook中运行报错的问题
解决Celluloid椭圆动画在Jupyter Notebook中的运行问题
我帮你排查了这个问题,主要是Jupyter Notebook和Sublime Text在Matplotlib动画渲染逻辑上的差异,再加上代码里的几个小细节没适配Jupyter的环境,导致报错。下面是具体的问题分析和修正方案:
核心问题点
- Matplotlib后端不兼容:Jupyter默认用的
inline后端只能静态显示图片,不支持Celluloid需要的交互式动画渲染。 - 图像数据类型错误:你用
np.ones()创建的img是float类型,但后续设置的RGB值是0-255的整数,超出了float数组的0-1正常范围,会导致渲染异常。 - 动画显示方式不对:Jupyter里直接用
plt.show()无法正确加载Celluloid生成的动画,需要用IPython的HTML展示方法。
修正后的完整代码
# 切换Jupyter的Matplotlib后端,支持动画 %matplotlib notebook import math import numpy as np import matplotlib.pyplot as plt from celluloid import Camera import copy from IPython.display import HTML # 改为uint8类型,初始化白色背景(255,255,255) img = np.ones((90,60,3), dtype=np.uint8) * 255 fig = plt.figure(figsize=(10,8), dpi=100, facecolor='w') camera = Camera(fig) quarterCircleOne = [] quarterCircleTwoHalfOne = [] quarterCircleTwoHalfTwo = [] quarterCircleThree = [] quarterCircleFourHalfOne = [] quarterCircleFourHalfTwo = [] xc = 45 yc = 30 rx = 25 ry = 15 def GenerateElipse(xc,yc,rx,ry): # 修正:uint8数组赋值要符合0-255范围 img[xc, yc] = (255,0,0) img[xc+1, yc] = (255,0,0) img[xc-1, yc] = (255,0,0) img[xc, yc+1] = (255,0,0) img[xc, yc-1] = (255,0,0) xk = 0 yk = ry pk = ry**2 - rx**2 * ry + 1/4 * rx**2 while ry**2 * xk < rx**2 * yk: if pk>0: xk = xk+1 yk = yk-1 pk = pk + 2 * ry**2 * xk + ry**2 - 2 * rx**2 * yk else: xk = xk+1 pk = pk + 2 * ry**2 * xk + ry**2 img[xc+xk, yc+yk] = (0,0,0) img[xc+xk, yc-yk] = (0,0,0) img[xc-xk, yc+yk] = (0,0,0) img[xc-xk, yc-yk] = (0,0,0) quarterCircleOne.append([xc-xk, yc-yk]) quarterCircleTwoHalfTwo.append([xc-xk, yc+yk]) quarterCircleThree.append([xc+xk, yc+yk]) quarterCircleFourHalfOne.append([xc+xk, yc-yk]) pk = ry**2 * (xk - 1/2)**2 + rx**2 * (yk - 1)**2 - rx**2 * ry**2 while yk>0: if pk>0: yk = yk-1 pk = pk - 2 * rx**2 * yk + rx**2 else: xk = xk+1 yk = yk-1 pk = pk - 2 * rx**2 * yk + 2 * ry**2 * xk + rx**2 img[xc+xk, yc+yk] = (0,0,0) img[xc+xk, yc-yk] = (0,0,0) img[xc-xk, yc+yk] = (0,0,0) img[xc-xk, yc-yk] = (0,0,0) quarterCircleOne.append([xc-xk, yc-yk]) quarterCircleTwoHalfOne.append([xc-xk, yc+yk]) quarterCircleThree.append([xc+xk, yc+yk]) quarterCircleFourHalfTwo.append([xc+xk, yc-yk]) GenerateElipse(45, 30, 25, 15) def DrawElipse(speed, img): sortedQuarterCircleOne = sorted(quarterCircleOne, key=lambda x: x[1]) sortedQuarterCircleTwoHalfOne = sorted(quarterCircleTwoHalfOne, key=lambda x: x[1]) sortedQuarterCircleTwoHalfTwo = sorted(quarterCircleTwoHalfTwo, key=lambda x: x[0]) sortedQuarterCircleThree = sorted(quarterCircleThree, key=lambda x: x[1], reverse=True) sortedQuarterCircleFourHalfTwo = sorted(quarterCircleFourHalfTwo, key=lambda x: x[1], reverse=True) sortedQuarterCircleFourHalfOne = sorted(quarterCircleFourHalfOne, key=lambda x: x[0], reverse=True) circle = [sortedQuarterCircleOne, sortedQuarterCircleTwoHalfOne, sortedQuarterCircleTwoHalfTwo, sortedQuarterCircleThree, sortedQuarterCircleFourHalfTwo, sortedQuarterCircleFourHalfOne] i = 0 for x in range(0, 6): for coordinates in circle[x]: freshImage = copy.deepcopy(img) freshImage[coordinates[0], coordinates[1]] = (0,0,0) freshImage[coordinates[0], coordinates[1]+1] = (255,0,0) freshImage[coordinates[0], coordinates[1]-1] = (255,0,0) freshImage[coordinates[0]+1, coordinates[1]-1] = (0,0,255) freshImage[coordinates[0]+1, coordinates[1]+1] = (0,0,255) freshImage[coordinates[0]+1, coordinates[1]] = (255,0,0) freshImage[coordinates[0]-1, coordinates[1]-1] = (0,0,255) freshImage[coordinates[0]-1, coordinates[1]+1] = (0,0,255) freshImage[coordinates[0]-1, coordinates[1]] = (255,0,0) if i % speed == 0: # 添加vmin和vmax确保颜色正确映射 plt.imshow(freshImage, vmin=0, vmax=255) camera.snap() i = i + 1 DrawElipse(1, img) animation = camera.animate() # Jupyter中用HTML展示动画,替代plt.show() HTML(animation.to_html5_video())
关键修改说明
- 后端切换:开头添加
%matplotlib notebook(Jupyter Notebook)或%matplotlib widget(Jupyter Lab),让Matplotlib使用支持动画的交互式后端。 - 图像类型修正:将
img定义为uint8类型并初始化为255(白色),匹配后续设置的0-255 RGB值范围,避免渲染时的数值异常。 - 动画展示方式:用
IPython.display.HTML将动画转为HTML5视频格式,这是Jupyter中展示Celluloid动画的标准方式,替代原生的plt.show()。 - imshow参数优化:添加
vmin=0, vmax=255确保Matplotlib正确解析RGB数值,避免颜色失真。
如果运行时提示缺少依赖(比如ffmpeg),可以通过pip install ffmpeg-python安装,这是生成HTML5视频需要的工具。
内容的提问来源于stack exchange,提问作者Nadīna Tarnovska
相关产品推荐
相关产品推荐

