I'm starting programming in Python (and OOP), but I have a solid experience in Fortran (90/95) and Matlab programming.
I'm developing a little tool using animation on tkinter environment. The goal of this tool is to animate multi-lines (an array and not a vector of data). Below, a simple example of my problem. I don't understand why the result of these two ways of plotting data are so different ?
from pylab import *
Nx=10
Ny=20
xx = zeros( ( Nx,Ny) )
data = zeros( ( Nx,Ny) )
for ii in range(0,Nx):
for jj in range(0,Ny):
xx[ii,jj] = ii
data[ii,jj] = jj
dline = plot(xx,data)
mline, = plot([],[])
mline.set_data(xx.T,data.T)
show()
If you plot only "dline" each line is plotted separately and with a different color. If you plot only "mline" all the lines are linked and with only one color.
My goal is to make an animation with "mline" changing the data at each loop. Here a simple source code illustrating my purposes :
from pylab import *
from matplotlib import animation
Nx=10
Ny=20
fig = plt.figure()
fig.set_dpi(100)
fig.set_size_inches(7, 6.5)
ax = plt.axes(xlim=(0, Nx), ylim=(0, Ny))
xx = zeros( ( Nx,Ny) )
data = zeros( ( Nx,Ny) )
odata = zeros( ( Nx,Ny) )
for ii in range(0,Nx):
for jj in range(0,Ny):
xx[ii,jj] = ii
odata[ii,jj] = jj
data[ii,jj] = 0.
#dline = plot(xx,odata)
mline, = plot([],[])
def init():
mline.set_data([],[])
return mline,
def animate(coef):
for ii in range(0,Nx):
for jj in range(0,Ny):
data[ii,jj] = odata[ii,jj] * (1.-float(coef)/360.)
mline.set_data(xx.T,data.T)
return mline,
anim = animation.FuncAnimation(fig, animate,
init_func=init,
frames=360,
interval=5,
blit=True)
plt.show()
I hope that I have clearly exposed my problem.
Thanks, Nicolas.
as @Rutger Kassies points out in the comments,
dline = plot(xx,data)
does some magic parsing on the input data, separates your arrays into a bunch of x-y pairs and plots those. Note that dline
is a list of Line2D
objects. In this case
mline, = plot([],[])
mline.set_data(xx.T,data.T)
you are creating a single Line2D
object and the library does it's best to shove 2D data, into a 1D plotting objects and does so by flattening the input.
To animate N
lines, you just need N
Line2D
objects:
lines = [plot([],[])[0] for j in range(Ny)] # make a whole bunch of lines
def init():
for mline in lines:
mline.set_data([],[])
return lines
def animate(coef):
data = odata * (1.-float(coef)/360.)
for mline, x, d in zip(lines, data.T, xx.T):
mline.set_data(x, d)
return lines
You also don't need to pre-allocate data
and doing the loops in python is much slower than letting numpy
do them for you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With