2016-11-18 222 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()