首先,我刚开始学习Python。在过去的几个小时里,我一直在努力更新箭头属性,以便在绘图动画期间更改它们。
在彻底寻找答案后,我检查了可以通过修改属性“中心”(例如circle.center = new_coordinates
)来更改圆形补丁中心。但是,我没有找到将此机制推断为箭头补丁的方法......
目前的代码是:
import numpy as np, math, matplotlib.patches as patches
from matplotlib import pyplot as plt
from matplotlib import animation
# Create figure
fig = plt.figure()
ax = fig.gca()
# Axes labels and title are established
ax = fig.gca()
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_ylim(-2,2)
ax.set_xlim(-2,2)
plt.gca().set_aspect('equal', adjustable='box')
x = np.linspace(-1,1,20)
y = np.linspace(-1,1,20)
dx = np.zeros(len(x))
dy = np.zeros(len(y))
for i in range(len(x)):
dx[i] = math.sin(x[i])
dy[i] = math.cos(y[i])
patch = patches.Arrow(x[0], y[0], dx[0], dy[0] )
def init():
ax.add_patch(patch)
return patch,
def animate(t):
patch.update(x[t], y[t], dx[t], dy[t]) # ERROR
return patch,
anim = animation.FuncAnimation(fig, animate,
init_func=init,
interval=20,
blit=False)
plt.show()
尝试了几个选项后,我认为功能更新可能会让我更接近解决方案。但是,我收到错误:
TypeError: update() takes 2 positional arguments but 5 were given
如果我只是通过定义动画功能每步添加一个补丁,如下所示,我会得到附加图像中显示的结果。
def animate(t):
patch = plt.Arrow(x[t], y[t], dx[t], dy[t] )
ax.add_patch(patch)
return patch,
我试图添加一个patch.delete语句,并创建一个新的补丁作为更新机制但导致空动画...
答案 0 :(得分:2)
在ax.clear()
之前添加ax.add_patch(patch)
,但会删除剧情中的所有元素。
def animate(t):
ax.clear()
patch = plt.Arrow(x[t], y[t], dx[t], dy[t] )
ax.add_patch(patch)
return patch,
编辑删除一个补丁
使用ax.patches.pop(index)
。
在您的示例中只有一个补丁,因此您可以使用index=0
def animate(t):
ax.patches.pop(0)
patch = plt.Arrow(x[t], y[t], dx[t], dy[t] )
ax.add_patch(patch)
return patch,
使用ax.patches.remove(object)
global
需要patch
来获取/设置外部Arrow
def animate(t):
global patch
ax.patches.remove(patch)
patch = plt.Arrow(x[t], y[t], dx[t], dy[t] )
ax.add_patch(patch)
return patch,
BTW:获取可与update()
print( patch.properties().keys() )
dict_keys(['aa', 'clip_path', 'patch_transform', 'edgecolor', 'path', 'verts', 'rasterized', 'linestyle', 'transform', 'picker', 'capstyle', 'children', 'antialiased', 'sketch_params', 'contains', 'snap', 'extents', 'figure', 'gid', 'zorder', 'transformed_clip_path_and_affine', 'clip_on', 'data_transform', 'alpha', 'hatch', 'axes', 'lw', 'path_effects', 'visible', 'label', 'ls', 'linewidth', 'agg_filter', 'ec', 'facecolor', 'fc', 'window_extent', 'animated', 'url', 'clip_box', 'joinstyle', 'fill'])
所以你可以使用update
来改变颜色 - “facecolor
def animate(t):
global patch
t %= 20 # get only 0-19 to loop animation and get color t/20 as 0.0-1.0
ax.patches.remove(patch)
patch = patches.Arrow(x[t], y[t], dx[t], dy[t])
patch.update({'facecolor': (t/20,t/20,t/20,1.0)})
ax.add_patch(patch)
return patch,
答案 1 :(得分:1)
我通过模仿patches.Arrow.__init__
中的代码找到了这个:
import numpy as np
import matplotlib.patches as patches
from matplotlib import pyplot as plt
from matplotlib import animation
import matplotlib.transforms as mtransforms
# Create figure
fig, ax = plt.subplots()
# Axes labels and title are established
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_ylim(-2,2)
ax.set_xlim(-2,2)
ax.set_aspect('equal', adjustable='box')
N = 20
x = np.linspace(-1,1,N)
y = np.linspace(-1,1,N)
dx = np.sin(x)
dy = np.cos(y)
patch = patches.Arrow(x[0], y[0], dx[0], dy[0])
def init():
ax.add_patch(patch)
return patch,
def animate(t):
L = np.hypot(dx[t], dy[t])
if L != 0:
cx = float(dx[t]) / L
sx = float(dy[t]) / L
else:
# Account for division by zero
cx, sx = 0, 1
trans1 = mtransforms.Affine2D().scale(L, 1)
trans2 = mtransforms.Affine2D.from_values(cx, sx, -sx, cx, 0.0, 0.0)
trans3 = mtransforms.Affine2D().translate(x[t], y[t])
trans = trans1 + trans2 + trans3
patch._patch_transform = trans.frozen()
return patch,
anim = animation.FuncAnimation(fig, animate,
init_func=init,
interval=20,
frames=N,
blit=False)
plt.show()