2012-10-15 144 views
4

我嘗試以這種方式調整動畫散點圖 - 示例,以便實時顯示我開發的基於代理的模型的結果。但是,圖中顯示的結果並不是我除了他們之外的東西。 更新這些值時出錯,並出現代理傾向於在對角線中聚簇的奇怪模式。 我添加了一些簡單的代碼來說明這個問題。有沒有人有一個想法出了什麼問題?使用Matplotlib動畫散點圖數據

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

n = 25 ## nr of agents 
x,y = 10, 10 ## matrix of x by y dimension 
dataX, dataY, binaryRaster = [],[],[] 

class AnimatedScatter(object): 
    """An animated scatter plot using matplotlib.animations.FuncAnimation.""" 
    def __init__(self): 
     global n 
     self.numpoints = n 
     self.stream = self.data_stream() 
     self.fig, self.ax = plt.subplots() 
     self.ax.set_title("My first Agent Based Model (ABM)",fontsize=14) 
     self.ax.grid(True,linestyle='-',color='0.75') 
     self.ani = animation.FuncAnimation(self.fig, self.update, interval=100, 
              init_func=self.setup_plot, blit=True, 
              repeat=False) 

    def setup_plot(self): 
     """Initial drawing of the scatter plot.""" 
     global x,y 
     dataX,dataY = next(self.stream) 
     self.scat = self.ax.scatter(dataY, dataX, c="tomato", s=20, animated=True) 
     self.ax.axis([0, y, x, 0]) 
     return self.scat, 

    def data_stream(self): 
     """Generate a random walk (brownian motion). Data is scaled to produce 
     a soft "flickering" effect.""" 
     global x,y, n 

     dataX,dataY = self.createRandomData() 

     #printing results to ascii for validation 
     lines = [] 
     binaryData = np.zeros((x,y), dtype=np.int) 
     for i in range(n): 
      binaryData[dataX,dataY] =1 
     for i in range(x): 
      line = "" 
      for j in range(y): 
       line += str(binaryData[i,j])+ "," 
      line= line[:-1]+ "\n" 
      lines.append(line) 
     lines.append("\n") 

     yx = np.array([dataY,dataX]) 
     cnt = 0 
     while cnt < 10: 
      dataX,dataY = self.createRandomData() 
      yx = np.array([dataY,dataX]) 

      #printing results to ascii for validation 
      binaryData = np.zeros((x,y), dtype=np.int) 
      for i in range(n): 
       binaryData[dataX,dataY] =1 
      for i in range(x): 
       line = "" 
       for j in range(y): 
        line += str(binaryData[i,j])+ "," 
       line= line[:-1]+ "\n" 
       lines.append(line) 
      lines.append("\n") 

      cnt+=1 
      yield yx 

     #printing results to ascii for validation 

     outNm = os.getcwd()+"\\ScatterValidation.txt" 
     outfile = open(outNm, "w") 
     outfile.writelines(lines) 
     outfile.close() 
     return 

    def update(self, i): 
     """Update the scatter plot.""" 
     data = next(self.stream) 
     self.scat.set_offsets(data[:2, :]) 
     return self.scat, 

    def show(self): 
     plt.show() 

    def createRandomData(self): 
     """Positions n agents randomly on a raster of x by y cells. 
     Each cell can only hold a single agent.""" 

     global x,y,n 
     binaryData = np.zeros((x,y), dtype=np.int) 
     newAgents = 0 
     dataX,dataY = [],[] 
     while newAgents < n: 
      row = np.random.randint(0,x,1)[0] 
      col = np.random.randint(0,y,1)[0] 
      if binaryData[row][col] != 1: 
       binaryData[row][col] = 1 
       newAgents+=1 

     for row in range(x): 
      for col in range(y): 
       if binaryData[row][col] == 1: 
        dataX.append(row) 
        dataY.append(col) 
     return dataX, dataY 

def main(): 
    global n, x, y, dataX, dataY, binaryRaster 
    a = AnimatedScatter() 
    a.show() 
    return 

if __name__ == "__main__": 
    main() 

回答

5

您可以通過兩種方式解決你的腳本,都涉及改變update功能:

  1. 在更新功能,使用分散的呼叫,更清晰,我認爲
  2. 移調之前的數據陣列在更新中調用set_offsets

使用分散調用是最清晰的修復,您可以在運行期間增加代理:

def update(self, i): 
    """Update the scatter plot.""" 
    dataX, dataY = next(self.stream) 
    self.scat = self.ax.scatter(dataX, dataY, c="tomato", s=20, animated=True) 
    return self.scat, 

移調的偏移量數組也將工作:

def update(self, i): 
    """Update the scatter plot.""" 
    data = next(self.stream) 
    self.scat.set_offsets(data.transpose()) 
    return self.scat, 

偏移給定爲每2項的n個元組,而數據陣列被給定爲2元組具有N個項的每個,轉置數據數組將解決您的問題。

注意:如果你不改變全局變量,你不需要有一個全球性的語句中指定的全局變量,因此在setup_plot__init__等可以刪除global n,x,y線。 我會將n,xy作爲您班級的實例變量,並且您不需要在腳本的頂部定義dataXdataYbinaryRasted

+0

Dear Arjenve,Great answers!我已經認爲這個「更新」 - 功能發生故障。你的選擇都很完美。 – user1746593

+0

+1轉置爲我工作。萬分感謝。 – pwagner