2016-11-18 190 views
0

我试图编写一个简单的脚本,它为每个时间步更新散点图t。我想尽可能简单地做到这一点。但它所做的只是打开一个我什么都看不到的窗口。窗户刚刚冻结。这可能只是一个小错误,但我找不到它。Python Matplotlib更新散点图

的该data.dat的格式

   x  y 
Timestep 1  1  2 
       3  1 
Timestep 2  6  3 
       2  1 

(该文件仅包含数字)

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

# Load particle positioins 
with open('//home//user//data.dat', 'r') as fp: 
    particles = [] 
    for line in fp: 
     line = line.split() 
     if line: 
      line = [float(i) for i in line] 
      particles.append(line) 

T = 100 
numbParticles = 2 

x, y = np.array([]), np.array([]) 

plt.ion() 
plt.figure() 
plt.scatter(x,y) 
for t in range(T): 
    plt.clf() 
    for k in range(numbP): 
      x = np.append(x, particles[numbParticles*t+k][0]) 
      y = np.append(y, particles[numbParticles*t+k][1]) 
    plt.scatter(x,y) 
    plt.draw() 
    time.sleep(1) 
    x, y = np.array([]), np.array([]) 

回答

2

做动画的最简单,最彻底的方法是使用matplotlib.animation module

由于散点图返回matplotlib.collections.PathCollection,更新它的方法是调用它的set_offsets方法。您可以将它传递给一个形状数组(N,2)或一个N 2元组列表 - 每个2元组是一个(x,y)坐标。

例如,

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

T = 100 
numbParticles = 2 
particles = np.random.random((T,numbParticles)).tolist() 
x, y = np.array([]), np.array([]) 

def init(): 
    pathcol.set_offsets([[], []]) 
    return [pathcol] 

def update(i, pathcol, particles): 
    pathcol.set_offsets(particles[i]) 
    return [pathcol] 

fig = plt.figure() 
xs, ys = zip(*particles) 
xmin, xmax = min(xs), max(xs) 
ymin, ymax = min(ys), max(ys) 
ax = plt.axes(xlim=(xmin, xmax), ylim=(ymin, ymax)) 
pathcol = plt.scatter([], [], s=100) 

anim = animation.FuncAnimation(
    fig, update, init_func=init, fargs=(pathcol, particles), interval=1000, frames=T, 
    blit=True, repeat=True) 
plt.show() 
+0

我不需要循环吗?我没有看到我每次通过我的数字清单的位置。你能解释一下吗? – Samuel

+1

循环驻留在对['FuncAnimation()'](http://matplotlib.org/api/animation_api.html#matplotlib.animation.FuncAnimation)的调用中。对于每个时间步(这里是每1000毫秒),函数'update'被调用一个递增的值'i'。 – ImportanceOfBeingErnest

+0

@ImportanceOfBeingErnest我不明白'i'在哪里增加。我期望像'i = i + 1'这样的东西。 – Samuel

0

我终于找到了解决方案。你可以简单地通过使用这个脚本来完成。我试图保持简单:

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

# Helps me to get the data from the file I want to plot 
N = 0 

# Load particle positioins 
with open('//home//user//data.dat', 'r') as fp: 
    particles = [] 
    for line in fp: 
     line = line.split() 
     particles.append(line) 

# Create new Figure and an Axes which fills it. 
fig = plt.figure(figsize=(7, 7)) 
ax = fig.add_axes([0, 0, 1, 1], frameon=True) 
border = 100 
ax.set_xlim(-border, border), ax.set_xticks([]) 
ax.set_ylim(-border, border), ax.set_yticks([]) 

# particle data 
p = 18 # number of particles 
myPa = np.zeros(p, dtype=[('position', float, 2)]) 

# Construct the scatter which we will update during animation 
scat = ax.scatter(myPa['position'][:, 0], myPa['position'][:, 1]) 

def update(frame_number): 
    # New positions 
    myPa['position'][:] = particles[N*p:N*p+p] 

    # Update the scatter collection, with the new colors, sizes and positions. 
    scat.set_offsets(myPa['position']) 
    increment() 

def increment(): 
    global N 
    N = N+1 

# Construct the animation, using the update function as the animation director. 
animation = FuncAnimation(fig, update, interval=20) 

plt.show()