5

我开始使用 Python(和 OOP)进行编程,但我在 Fortran(90/95)和 Matlab 编程方面拥有丰富的经验。

我正在开发一个在 tkinter 环境中使用动画的小工具。这个工具的目标是动画多行(一个数组而不是一个数据向量)。下面是我的问题的一个简单示例。我不明白为什么这两种绘制数据的方式的结果如此不同?

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()

如果您仅绘制“dline”,则每条线都将单独绘制并使用不同的颜色。如果您仅绘制“mline”,则所有线条都被链接并且只有一种颜色。

我的目标是制作一个动画,其中“mline”在每个循环中更改数据。这是一个简单的源代码,说明了我的目的:

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()

我希望我已经清楚地暴露了我的问题。

谢谢,尼古拉斯。

4

2 回答 2

5

正如@Rutger Kassies 在评论中指出的那样,

dline = plot(xx,data)

对输入数据进行一些神奇的解析,将您的数组分成一堆 xy 对并绘制它们。请注意,这dline是一个对象列表Line2D在这种情况下

mline, = plot([],[])
mline.set_data(xx.T,data.T)

您正在创建单个Line2D对象,并且库最好将 2D 数据推送到 1D 绘图对象中,并通过展平输入来实现。

N要为线条设置动画,您只需要N Line2D对象:

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

您也不需要预先分配data,并且在 python 中执行循环比让numpy他们为您执行循环要慢得多。

于 2013-10-22T15:11:27.493 回答
0

非常感谢 Rutger Kassies 和 tcaswell。这里与上面的示例相同,但现在它可以按我的意愿工作。我希望它能帮助其他python程序员。

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)
axis([0, Nx-1, 0, Ny])

xx    = zeros( ( Nx,Ny) )
data  = zeros( ( Nx,Ny) )
odata = zeros( ( Nx,Ny) )

for ii in range(0,Nx):
    xx[ii,:]    = float(ii)

for jj in range(0,Ny):
    odata[:,jj] = float(jj)

#dline = plot(xx,odata)

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, xx.T, data.T,):
       mline.set_data(x, d)

   return lines

anim = animation.FuncAnimation(fig, animate, 
                               init_func=init, 
                               frames=360, 
                               interval=5,
                               blit=True)

plt.show()
于 2013-10-23T08:31:51.583 回答