Сложность использования функции добавления при анимации в Matplotlib FuncAnimation - PullRequest
1 голос
/ 17 марта 2019

Итак, я написал простой код для создания анимированного графа с использованием FuncAnimation Matplotlib. Но нет выхода. Я думаю, что ошибка заключается в функции 'np.append', так как код работает, если я передам функции 'animate' предварительно созданные массивы x, y, z. Но я не могу понять, почему ЭТО не работает!

%matplotlib notebook

import numpy as np
import mpl_toolkits.mplot3d.axes3d as p3
import matplotlib.pyplot as plt
import matplotlib.animation as animation

del_t = 0.01 ##Time-step value

x=np.array([0.0])
y=np.array([10.0])
z=np.array([0.0])

#These functions give how (x, y, z) co-ordinate
#changes with time
def dx_dt(x, y, z):
    return 10*(y-x)
def dy_dt(x, y, z):
    return -x*z + 28*x - y
def dz_dt(x, y, z):
    return x*y-(8/3)*z

#Runge-Kutta Method for numerical solution of differential equations
#These functions give next (x, y, z) co-ordinate
def next_xpt(x, y, z):
    k1 = dx_dt(x, y, z) * del_t
    k2 = dx_dt(x + k1/2, y, z) * del_t
    k3 = dx_dt(x + k2/2, y, z) * del_t
    k4 = dx_dt(x + k3, y, z) * del_t
    return x + (k1 + 2*k2 + 2*k3 + k4)/6
def next_ypt(x, y, z):
    k1 = dy_dt(x, y, z) * del_t
    k2 = dy_dt(x, y + k1/2, z) * del_t
    k3 = dy_dt(x, y + k2/2, z) * del_t
    k4 = dy_dt(x, y + k3, z) * del_t
    return y + (k1 + 2*k2 + 2*k3 + k4)/6
def next_zpt(x, y, z):
    k1 = dz_dt(x, y, z) * del_t
    k2 = dz_dt(x, y, z + k1/2) * del_t
    k3 = dz_dt(x, y, z + k2/2) * del_t
    k4 = dz_dt(x, y, z + k3) * del_t
    return z + (k1 + 2*k2 + 2*k3 + k4)/6

fig = plt.figure()
ax = p3.Axes3D(fig)

#Creating a line object
line, = ax.plot3D([0.0],[10.0],[0.0],'-b') 

ax.set_xlim3d(-30,30)
ax.set_xlabel("X")
ax.set_ylim3d(-30,30)
ax.set_ylabel("Y")
ax.set_zlim3d(-30,30)
ax.set_zlabel("Z")
ax.set_title("Lorenz Strange Attractor")

def animate(i, x, y, z, line):
    np.append(x, next_xpt(x[i], y[i], z[i]))
    np.append(y, next_ypt(x[i], y[i], z[i]))
    np.append(z, next_zpt(x[i], y[i], z[i]))
    line.set_data(x[:i+1],y[:i+1])
    line.set_3d_properties(z[:i+1])
    return line

ani = animation.FuncAnimation(fig, animate, fargs = (x, y, z, line), interval=50, blit=False)

1 Ответ

0 голосов
/ 17 марта 2019

Вам необходимо сохранить результат добавления в массивах x, y и z.Причина, по которой вы увидели добавление, в том, что вы, скорее всего, тестировали его в интерактивном режиме.Но, как упомянул @hpaulj, для вашей цели вам придется хранить добавленный массив в функции.Более того, вам придется объявить x, y, z как global, чтобы отразить изменения, чтобы избежать IndexError.Чтобы инициализировать объект строки, вы можете определить функцию init, а затем просто передать итерируемый индекс i в вашем FuncAnimation

Скажем документы (выделено мной)

Возвращает: append: ndarray

Копия arr со значениями, добавленными к оси.Обратите внимание, что добавление не происходит на месте: новый массив выделен и заполнен .

Вам нужно будет сохранить новый массив

# Initizlise x, y, z here

def init():
    line.set_data([], [])
    line.set_3d_properties([])
    return line,

# dx_dt, dy_dt, dz_dt etc. functions here 

fig = plt.figure()
ax = p3.Axes3D(fig)

#Creating a line object
line, = ax.plot3D([0.0],[10.0],[0.0],'-b') 

# Setting axes limits here    

def animate(i):
    global x, y, z
    x = np.append(x, next_xpt(x[i], y[i], z[i]))
    y = np.append(y, next_ypt(x[i], y[i], z[i]))
    z = np.append(z, next_zpt(x[i], y[i], z[i]))
    line.set_data(x[:i+1],y[:i+1])
    line.set_3d_properties(z[:i+1])
    return line,

ani = animation.FuncAnimation(fig, animate, init_func=init, interval=50, blit=False)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...