Skip to main content
 首页 » 编程设计

python之动画+在矩阵之间平滑插值

2025年05月04日10zhoujg

我有一个点矩阵,例如:

import numpy as np 
import seaborn as sns; sns.set() 
import matplotlib.pyplot as plt 
%matplotlib inline 
 
originalPoints = np.asarray([[1,2,3,4,5,6],[2,4,6,8,10,12]]) 
newPoints = np.asarray([[1,2,3,4,5,6],[2,4,6,8,10,12]]) + 20 
plt.scatter(originalPoints[0,:],originalPoints[1,:], color='red'); 
plt.scatter(newPoints[0,:],newPoints[1,:], color='blue'); 

这给了我:

我正在尝试生成一个 gif/动画,显示点沿着从红色到蓝色的平滑路径移动。我一直在尝试使用类似 what is discussed here 的东西和 scipy 的 interpolate discussed here但我似乎无法弄清楚。

任何帮助都会很棒。

奖励:也适用于 3D 的解决方案

编辑:明确地说,我想要的是一些非线性平滑路径,每个蓝点都沿着该路径移动以到达红点。注意 - 上面的例子是虚构的。实际上只有一堆蓝点和一堆红点。考虑在两个不同的散点图之间制作动画。

请您参考如下方法:

您可以只在每对点之间创建线性路径;将其与 matplotlib.animation.FuncAnimation 相结合看起来像

import matplotlib.animation as animation 
 
def update_plot(t): 
    interpolation = originalPoints*(1-t) + newPoints*t 
    scat.set_offsets(interpolation.T) 
    return scat, 
 
fig = plt.gcf() 
plt.scatter(originalPoints[0,:],originalPoints[1,:], color='red') 
plt.scatter(newPoints[0,:],newPoints[1,:], color='blue') 
scat = plt.scatter([], [], color='green') 
animation.FuncAnimation(fig, update_plot, frames=np.arange(0, 1, 0.01)) 

编辑:编辑后的问题现在要求非线性插值;将 update_plot 替换为

noise = np.random.normal(0, 3, (2, 6)) 
def update_plot(t): 
    interpolation = originalPoints*(1-t) + newPoints*t + t*(1-t)*noise 
    scat.set_offsets(interpolation.T) 
    return scat, 

你得到了

编辑 #2:关于下面评论中关于颜色插值的查询,您可以通过 matplotlib.collections.Collection.set_color 处理。 ;具体来说,将上面的 update_plot 替换为

def update_plot(t): 
    interpolation = originalPoints*(1-t) + newPoints*t + t*(1-t)*noise 
    scat.set_offsets(interpolation.T) 
    scat.set_color([1-t, 0, t, 1]) 
    return scat, 

我们结束了

关于“奖励”:3D 情况大体相似;

a = np.random.multivariate_normal([-3, -3, -3], np.identity(3), 20) 
b = np.random.multivariate_normal([3, 3, 3], np.identity(3), 20) 
 
def update_plot(t): 
    interpolation = a*(1-t) + b*t 
    scat._offsets3d = interpolation.T 
    scat._facecolor3d = [1-t, 0, t, 1] 
    return scat, 
 
fig = plt.figure() 
ax = fig.gca(projection='3d') 
ax.scatter(a[:, 0], a[:, 1], a[:, 2], c='r') 
ax.scatter(b[:, 0], b[:, 1], b[:, 2], c='b') 
scat = ax.scatter([], [], []) 
ani = animation.FuncAnimation(fig, update_plot, frames=np.arange(0, 1, 0.01)) 
ani.save('3d.gif', dpi=80, writer='imagemagick') 

编辑下面有关如何分阶段执行此操作的评论:可以通过合并 the composition of paths 来实现此目的直接在 update_plot 中:

a = np.random.multivariate_normal([-3, -3, -3], np.identity(3), 20) 
b = np.random.multivariate_normal([3, 3, 3], np.identity(3), 20) 
c = np.random.multivariate_normal([-3, 0, 3], np.identity(3), 20) 
 
def update_plot(t): 
    if t < 0.5: 
        interpolation = (1-2*t)*a + 2*t*b 
        scat._facecolor3d = [1-2*t, 0, 2*t, 1] 
    else: 
        interpolation = (2-2*t)*b + (2*t-1)*c 
        scat._facecolor3d = [0, 2*t-1, 2-2*t, 1] 
    scat._offsets3d = interpolation.T 
    return scat, 
 
fig = plt.figure() 
ax = fig.gca(projection='3d') 
ax.scatter(a[:, 0], a[:, 1], a[:, 2], c='r') 
ax.scatter(b[:, 0], b[:, 1], b[:, 2], c='b') 
ax.scatter(c[:, 0], c[:, 1], c[:, 2], c='g') 
scat = ax.scatter([], [], []) 
ani = animation.FuncAnimation(fig, update_plot, frames=np.arange(0, 1, 0.01)) 
ani.save('3d.gif', dpi=80, writer='imagemagick')