2017-02-17 34 views
1

У меня есть матрица точек, как:Animate + Плавно интерполировать между матрицами

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'); 

И это дает мне:

enter image description here

Я пытаюсь создать GIF/анимацию, показывающую точки двигаясь вдоль гладкого пути от красного до синего. Я пытался использовать что-то вроде what is discussed here и scipy's interpolate discussed here, но я не могу понять это.

Любая помощь будет отличной.

Bonus: решение, которое будет работать в 3D, а также

EDIT: Чтобы было ясно, что я хотел бы некоторые нелинейное гладкий путь, по которому каждая синяя точка движется, чтобы достичь красные точки. Примечание. Приведенный выше пример составлен. На самом деле есть только куча синих точек и куча красных очков. Подумайте о анимации между двумя разными графиками разброса.

+0

Можете ли вы быть более конкретно? Что вы имеете в виду «показывая точки, движущиеся вдоль некоторого гладкого пути от красного до синего»? Что не работает? – PrestonH

+0

Кроме того, где бы добавить измерение? – fuglede

+0

@PrestonH Я добавил, что редактирование выше. – user79950

ответ

6

Вы можете просто создать линейный путь между каждой из пар точек; сочетая это с 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)) 

Linear path between points

Edit: Отредактированные вопросы теперь просят нелинейную интерполяцию вместо; замена 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, 

вы получите вместо

Nonsensical path between points

Edit # 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, 

мы в конечном итоге с

Interpolation with colors

относительно "бонус": 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') 

3D example

Редактировать относительно комментарий ниже о том, как сделать это в несколько этапов: Можно достичь этого путем включения 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') 

Example using path composition

+0

спасибо @fuglede! Можете ли вы опубликовать полный рабочий код?Кроме того, я имел в виду больше - вдоль некоторой * кривой *, как сплайн или что-то – user79950

+0

Линейные пути - это как кривые, так и сплайны. Кроме того, вне '.save ('scatterplots.gif', dpi = 80, writer = 'imagemagick')', это фактически полный рабочий код. – fuglede

+0

Hm. Хорошо, спасибо, я поиграю с тем, что вы мне дали - последний вопрос. Чтобы я мог интерполировать цвет, мне нужно было бы создать соответствующую цветовую карту? – user79950

 Смежные вопросы

  • Нет связанных вопросов^_^