DarthSpeedious
DarthSpeedious

Reputation: 1007

imshow.set_data() not working for FuncAnimation

I am writing a program for 2D FDTD light propagation, in this code, when I run the program with ax.imshow() command in the animate function, the program works fine whereas when I use the im.set_data() command, it gives me a blank image. Can somebody please tell me what am I doing wrong? Also, can somebody tell me how to set the colormap at the beginning so that I dont have to update it during the animation loop. The point is I don't want the imshow() command to draw everything everytime the loop is run. Thanks for all the help. I am learning programming please suggest me what to do.

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation


xdim = 100        
ydim = 100
epsilon = np.ones([xdim,ydim])*8.854187817*10**(-12)
mu = np.ones([xdim,ydim])*4*np.pi*10**(-7)
c = 299792458
delta = 10**-6
deltat =  delta/(c*(2**0.5))

Hz = np.zeros([xdim,ydim])
Ey = np.zeros([xdim,ydim])
Ex = np.zeros([xdim,ydim])


fig = plt.figure()
ax = plt.axes()
im = ax.imshow(Hz)

Hz[xdim/2,ydim/2]=1

def init():
    im.set_data(np.zeros(Hz.shape))
    return

def animate(n, *args, **kwargs):
    Ex[0:xdim-1,0:ydim-1]=Ex[0:xdim-1,0:ydim-1]+(deltat/(delta*mu[0:xdim-1,0:ydim-1]))*(Hz[1:xdim,0:ydim-1]-Hz[0:xdim-1,0:ydim-1])
    Ey[0:xdim-1,0:ydim-1]=Ey[0:xdim-1,0:ydim-1]-(deltat/(delta*mu[0:xdim-1,0:ydim-1]))*(Hz[0:xdim-1,1:ydim]-Hz[0:xdim-1,0:ydim-1])

    Hz[1:xdim,1:ydim]=Hz[1:xdim,1:ydim]+(deltat/(delta*epsilon[1:xdim,1:ydim]))*(Ex[1:xdim,1:ydim]-Ex[0:xdim-1,1:ydim]-Ey[1:xdim,1:ydim]+Ey[1:xdim,0:ydim-1])
    if(n==0):Hz[xdim/2,ydim/2]=0
    #im.set_data(Hz)                 
    ax.imshow(Hz)     # Delete this command and try running the program with the above command. 
    return

ani = animation.FuncAnimation(fig, animate, init_func=init, frames = 200, interval = 10, blit = False, repeat = False)
fig.show()

Upvotes: 2

Views: 7288

Answers (2)

Ajean
Ajean

Reputation: 5659

Actually, your first version was working just fine also. The problem was that because im is initialized with an array of zeros, the vmin and vmax for the colorscale were both zero. Updates to im after that using set_data did not update vmin and vmax, whereas ax.imshow automatically rescales the color ranges. If you set the color ranges at the beginning to something reasonable, it works fine:

ax.imshow(Hz, vmin=-0.2, vmax=0.2)

That's the only thing you need to change from the code in the question to make it work (with im.set_data in the animation function).

Upvotes: 1

DarthSpeedious
DarthSpeedious

Reputation: 1007

I got the program to work by making a few changes, though i cannot understand why it is not working the way i wrote it in the question. Here is what i changed:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation


xdim = 100
ydim = 100
epsilon = np.ones([xdim,ydim])*8.854187817*10**(-12)
mu = np.ones([xdim,ydim])*4*np.pi*10**(-7)
c = 299792458
delta = 10**-6
deltat =  delta/(c*(2**0.5))

Hz = np.zeros([xdim,ydim])
Ey = np.zeros([xdim,ydim])
Ex = np.zeros([xdim,ydim])



Hz[xdim/2,ydim/2]=1

def init():
    global fig, ax, im
    fig = plt.figure()
    ax = plt.axes()
    im = ax.imshow(Hz, cmap="jet")
    im.set_data(np.zeros(Hz.shape))
    return

def animate(n):
    Ex[0:xdim-1,0:ydim-1]=Ex[0:xdim-1,0:ydim-1]+(deltat/(delta*mu[0:xdim-1,0:ydim-1]))*(Hz[1:xdim,0:ydim-1]-Hz[0:xdim-1,0:ydim-1])
    Ey[0:xdim-1,0:ydim-1]=Ey[0:xdim-1,0:ydim-1]-(deltat/(delta*mu[0:xdim-1,0:ydim-1]))*(Hz[0:xdim-1,1:ydim]-Hz[0:xdim-1,0:ydim-1])

    Hz[1:xdim,1:ydim]=Hz[1:xdim,1:ydim]+(deltat/(delta*epsilon[1:xdim,1:ydim]))*(Ex[1:xdim,1:ydim]-Ex[0:xdim-1,1:ydim]-Ey[1:xdim,1:ydim]+Ey[1:xdim,0:ydim-1])
    if(n==0):Hz[xdim/2,ydim/2]=0
    im.set_data(Hz)                 
    return

init()
ani = animation.FuncAnimation(fig, animate, frames = 500, interval = 10, blit = False, repeat = False)
fig.show()

Upvotes: 1

Related Questions