You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中如何引用列表内Polygon并变换放回以优化多边形动画?

问题原因

plt.fill()返回的是包含单个Polygon实例的列表,所以你的poly列表里每个元素都是列表,不是Polygon对象,调用set_transform自然会触发AttributeError。

正确实现方案

要优化大量多边形的动画性能,推荐两种高效实现方式:

方式1:直接存储单个Polygon对象

直接创建patches.Polygon实例,添加到坐标轴后存入列表,后续直接操作这些实例的变换:

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib.animation import FuncAnimation

n_poly = 10
poly = []

fig = plt.figure(frameon=False)
fig.set_size_inches(2.0, 2.0)
ax = plt.axes(xlim=(-2, 3), ylim=(-2, 3))  # 调整坐标轴范围防止图形跑出视野

# 定义正方形顶点
x_profile = [0, 1, 1, 0]
y_profile = [0, 0, 1, 1]
vertices = np.array([x_profile, y_profile]).T

for i in range(n_poly):
    # 创建Polygon对象,设置初始位置偏移
    polygon = patches.Polygon(vertices + [i*0.5, i*0.5], closed=True, facecolor=f"C{i}")
    ax.add_patch(polygon)
    poly.append(polygon)

# 动画更新函数:每一帧更新旋转角度
def update(frame):
    angle = frame * 5  # 每帧旋转5度
    for polygon in poly:
        # 构建旋转变换,结合坐标轴的默认变换(避免位置偏移)
        rotation = mpl.transforms.Affine2D().rotate_deg(angle) + ax.transData
        polygon.set_transform(rotation)
    return poly

# 启动动画
ani = FuncAnimation(fig, update, frames=72, interval=50, blit=True)
plt.show()

方式2:使用PatchCollection批量处理(更高效)

当多边形数量很多时,用PatchCollection可以批量管理和更新,性能更优:

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib.collections import PatchCollection
from matplotlib.animation import FuncAnimation

n_poly = 10
patches_list = []

fig = plt.figure(frameon=False)
fig.set_size_inches(2.0, 2.0)
ax = plt.axes(xlim=(-2, 3), ylim=(-2, 3))

# 定义正方形顶点
x_profile = [0, 1, 1, 0]
y_profile = [0, 0, 1, 1]
vertices = np.array([x_profile, y_profile]).T

for i in range(n_poly):
    polygon = patches.Polygon(vertices + [i*0.5, i*0.5], closed=True)
    patches_list.append(polygon)

# 创建PatchCollection并添加到坐标轴
collection = PatchCollection(patches_list, cmap="tab10")
collection.set_array(np.arange(n_poly))  # 给每个多边形分配颜色
ax.add_collection(collection)

# 动画更新函数
def update(frame):
    angle = frame * 5
    # 批量更新每个patch的变换
    for i in range(len(collection._transforms)):
        rotation = mpl.transforms.Affine2D().rotate_deg(angle) + ax.transData
        collection._transforms[i] = rotation
    return [collection]

ani = FuncAnimation(fig, update, frames=72, interval=50, blit=True)
plt.show()
关键注意点
  • 旋转变换需要和ax.transData结合,否则图形会以原点为中心旋转,且位置可能偏离预期
  • 使用FuncAnimation的blit=True可以大幅提升动画性能,只更新变化的部分
  • 避免每一帧重新创建多边形,复用初始化的实例是优化性能的核心

内容的提问来源于stack exchange,提问作者user20787420

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 13:55:36