0

I'm trying to make an animation of plot_surface in Matplotlib 3. I saw an example of how to use FuncAnimation, but I understand that it the function call is slow it is better to first save all the frames and then use ArtistAnimation to animate them.

How can I transform the following code to work with ArtistAnimation (instead of plotting the surface each time steps as it is done here):

#!/usr/bin/env python
"""
Solving 2D Allen-Cahn Eq using pseudo-spectral with Implicit/Explicit
u_t= epsilon(u_{xx}+u_{yy}) + u - u^3
where u-u^3 is treated explicitly and u_{xx} and u_{yy} is treated implicitly
BC = Periodic
IC=v=sin(2*pi*x)+0.5*cos(4*pi*y)
"""

import math
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
from matplotlib.ticker import LinearLocator
import time

plt.ion()

# Setup the grid
N = 64; h = 1.0/N;
x = [h*i for i in range(1,N+1)]
y = [h*i for i in range(1,N+1)]
dt = 0.05
xx,yy = (np.mat(A) for A in (np.meshgrid(x,y)))

# Initial Conditions
u = np.array(np.sin(2*math.pi*xx) + 0.5*np.cos(4*math.pi*yy), dtype=float)

epsilon = 0.01

# (ik) and (ik)^2 vectors in x and y direction
I = complex(0,1)
k_x = 2*np.pi*np.array([I*n for n in np.concatenate((np.arange(0,N/2),np.array([0]),np.arange(-N/2+1,0)))])
k_y = k_x

kxx = np.zeros((N,N), dtype=complex)
kyy = np.zeros((N,N), dtype=complex)
for i in range(N):
    for j in range(N):
        kxx[i,j] = k_x[i]**2
        kyy[i,j] = k_y[j]**2

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
surf = ax.plot_surface(xx, yy, u,rstride=1, cstride=1, cmap=cm.jet,
        linewidth=0, antialiased=False)
fig.colorbar(surf, shrink=0.5, aspect=5)
plt.xlabel('x')
plt.ylabel('y')
plt.show()

v_hat = np.zeros((N,N), dtype=complex)
v_hat = np.fft.fft2(u)

for n in range(100):
    # calculate nonlinear term in real space
    v_nl = np.array(u**3, dtype=complex)
# FFT for nonlinear and linear terms
    v_nl = np.fft.fft2(v_nl)
    v_hat = (v_hat*(1+1/dt) - v_nl)
    v_hat=v_hat/(1/dt - (kxx+kyy)*epsilon) # Implicit/Explicit timestepping
    u = np.real(np.fft.ifft2(v_hat))
    # Remove old plot before drawing
    ax.collections.remove(surf)
    surf = ax.plot_surface(xx, yy, u,rstride=1, cstride=1, cmap=cm.jet,
         linewidth=0, antialiased=False)
    plt.draw()
plt.show()
Ohm
  • 2,312
  • 4
  • 36
  • 75
  • 1
    If the answer in the question you linked does not help you, have a look at [this one](https://stackoverflow.com/a/45713451/2454357) and please tell us which part you don't understand / have problems with. – Thomas Kühn Feb 12 '19 at 10:15
  • 1
    I would suspect that the total amount of time to create and run an animation is the same. In a FuncAnimation this time may equally divide by the number of steps, in an ArtistAnimation it may take longer till the animation starts, but potentially less time for each step. So it's not a priori clear that using an ArtistAnimation is beneficial here, especially since it is of course more memory intensive (due to *all* artists needing to be stored). In [this answer](https://stackoverflow.com/a/47421950/4124317) you find both methods compared. – ImportanceOfBeingErnest Feb 12 '19 at 18:51
  • @ThomasKühn this indeed answer my question, I will consider to remove this question – Ohm Feb 12 '19 at 20:03
  • 1
    Don't remove it, let's rather mark it as duplicate. This way the solution will be easier to find for others that have similar problems. – Thomas Kühn Feb 12 '19 at 20:15

0 Answers0