2017-09-27 63 views
-1

我目前想要將3D-rawdata從我的Walabot設備中可視化,並將其顯示在使用matplotlib FuncAnimation創建的3D動畫中。我已經搜索了答案,但找不到有用的東西。 在我的情況下,我已經有了一個3維數組,每個索引都有一個特定的值,隨時間變化。我已經可以弄清楚如何在不同顏色和尺寸的3D圖表中顯示它,但現在我想更新自己。我發現一些示例代碼給了我一個很好的開始,但是我的圖表並沒有自行更新。我必須關閉窗口,然後窗口再次彈出3D數組中的不同值。你們知道如何解決這個問題嗎? 這裏是我到目前爲止的代碼:Matplotlib python 3D數組值的動畫

def update(plot, signal, figure): 
    plot.clear() 
    scatterplot = plot.scatter(x, y, z, zdir='z', s=signal[0], c=signal[0]) 
    figure.show() 
    return figure 

def calc_RasterImage(signal): 
    # 3D index is represnted is the following schema {i,j,k} 
    # sizeX - signal[1] represents the i dimension length 
    # sizeY - signal[2] represents the j dimension length 
    # sizeZ - signal[3] represents the k dimension length 
    # signal[0][i][j][k] - represents the walabot 3D scanned image (internal data) 

    #Initialize 3Dplot with matplotlib      
    fig = plt.figure() 
    ax = fig.add_subplot(111, projection='3d') 
    ax.set_xlim([xMin-1,xMax-1]) 
    ax.set_ylim([yMin-1,yMax-1]) 
    ax.set_zlim([zMin-1,zMax-1]) 
    ax.set_xlabel('X AXIS') 
    ax.set_ylabel('Y AXIS') 
    ax.set_zlabel('Z AXIS') 
    scatterplot = ax.scatter(x, y, z, zdir='z', s=signal[0], c= signal[0]) 
    cbar = plt.colorbar(scatterplot) 
    cbar.set_label('Density') 
    #def update(signal): 
    #  ax.clear() 
    #  scatterplot = ax.scatter(x, y, z, zdir='z', s=signal[0], c=signal[0]) 
    ani = anim.FuncAnimation(fig, update(ax, signal, plt), frames=10 , blit=True, repeat = True) 

def main(): 
    wlbt = Walabot() 
    wlbt.connect() 
    if not wlbt.isConnected: 
      print("Not Connected") 
    else: 
      print("Connected") 
    wlbt.start() 
    calc_index(wlbt.get_RawImage_values()) 
    while True: 
      #print_RawImage_values(wlbt.get_RawImage_values()) 
      calc_RasterImage(wlbt.get_RawImage_values()) 
    wlbt.stop() 

if __name__ == '__main__': 
    main() 

正如你看到的,行與

ani = anim.FuncAnimation(fig, update(ax, signal, plt), frames=10 , blit=True, repeat = True) 

需要從頂部的更新功能。此功能清除我的情節,並用不同的值重新創建一個新情節。但我總是需要先關閉劇情窗口,這是我想避免的。 這是怎麼樣的情節: 3D array plot with matplotlib scatter 你們有一個想法如何解決這個問題?

歡呼

回答

0

你的代碼是不是一個真正的最小工作示例,你不應該偷懶,實際上是來這之前閱讀FuncAnimation的文檔。這就是說,這樣的事情應該工作:

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 

""" 
Display walabot output. 
""" 

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

def display(walabot_instance): 

    # set x, y, z 

    fig = plt.figure() 
    ax = fig.add_subplot(111, projection='3d') 
    path_collection = ax.scatter(x, y, z, zdir='z') 

    # do your labelling, layout etc 

    def update(ignored, walabot_instance): 
     signal = walabot_instance.get_RawImage_values() 
     path_collection.set_sizes(signal[0]) 
     path_collection.set_color(signal[1]) 
     return path_collection, 

    return FuncAnimation(fig, update, fargs=[walabot_instance]) 

def main(): 
    wlbt = Walabot() 
    wlbt.connect() 
    if not wlbt.isConnected: 
     print("Not Connected") 
    else: 
     print("Connected") 
    wlbt.start() 

    plt.ion() 
    animation = display(wlbt) 
    raw_input("Press any key when done watching Walabot...") 


if __name__ == "__main__": 
    main() 

如果您有任何問題(閱讀文檔後!),請留下評論。

+0

批評失蹤的mcve似乎有點矛盾,仍然提供了一個答案,而答案本身沒有任何解釋。我想提醒提問者缺少問題的清晰度應該是一個評論;另一方面,如果你能回答這個問題,爲什麼還要擔心這個問題?或者相反:如果問題不清楚,爲什麼要提供答案?無論如何,拋出一段代碼,然後說「如果你想了解它,閱讀文檔」同樣很糟糕。 – ImportanceOfBeingErnest

+0

@ImportanceOfBeingErnest我讓他先閱讀文檔_first_,然後詢問其餘的問題。我會爭辯說,我實際上所說的和你如何描繪它有區別。 – Paul

0

感謝您的幫助!在嘗試完代碼並將其調整爲我的代碼後,它終於奏效了。我在看文檔(https://matplotlib.org/api/_as_gen/matplotlib.animation.FuncAnimation.html#matplotlib.animation.FuncAnimation),但我無法弄清楚如何正確使用它,因爲我在編碼方面不太好。反正這是我的新代碼:

def calc_index(signal): 
    for i in range(0, signal[1], 1): 
      for j in range(0, signal[2], 1): 
        for k in range(0, signal[3], 1): 
          #Location of Index 
          x.append(i) 
          y.append(j) 
          z.append(k) 

def display(walabot_instance): 
    # 3D index is represnted is the following schema {i,j,k} 
    # sizeX - signal[1] represents the i dimension length 
    # sizeY - signal[2] represents the j dimension length 
    # sizeZ - signal[3] represents the k dimension length 
    # signal[0][i][j][k] - represents the walabot 3D scanned image (internal data) 

    #Initialize 3Dplot with matplotlib      
    fig = plt.figure() 
    ax = fig.add_subplot(111, projection='3d') 
    signal = walabot_instance.get_RawImage_values() 
    path_collection = ax.scatter(x, y, z, zdir='z', s=signal[0], c=signal[0]) 

    #Plot labeling 
    ax.set_xlim([xMin-1,xMax-1]) 
    ax.set_ylim([yMin-1,yMax-1]) 
    ax.set_zlim([zMin-1,zMax-1]) 
    ax.set_xlabel('X AXIS') 
    ax.set_ylabel('Y AXIS') 
    ax.set_zlabel('Z AXIS') 
    cbar = plt.colorbar(path_collection) 
    cbar.set_label('Density') 

    def update(ignored, walabot_instance): 
      ax.clear() 
      signal_update = walabot_instance.get_RawImage_values() 
      path_collection = ax.scatter(x, y, z, zdir='z', s=signal_update[0], c=signal_update[0]) 
      return path_collection 

    return FuncAnimation(fig, update, fargs=[walabot_instance]) 

def main(): 
    wlbt = Walabot() 
    wlbt.connect() 
    if not wlbt.isConnected: 
      print("Not Connected") 
    else: 
      print("Connected") 
    wlbt.start() 

    calc_index(wlbt.get_RawImage_values()) 
    plt.ion() 
    animation = display(wlbt) 

    raw_input("Press any key when done watching Walabot...") 
    wlbt.stop() 

if __name__ == '__main__': 
    main() 

我仍然不被你在使用

fargs=[walabot_instance] 
在FuncAnimation功能

的理解?我只是不明白的文檔,這個.. 拿什麼

def func(fr: object, *fargs) -> iterable_of_artists: 

def gen_function() -> obj: 
的FUNC和幀參數FuncAnimation文檔中

?只是爲了更好地理解這個過程。

爲什麼更新需要忽略的參數輸入?它沒有用在任何地方..

非常感謝!

+0

'FuncAnimation'不是爲你的用例設計的。預期的用例是,您正在描述動態系統的演變,該動態系統的確定性可能是因爲您已經擁有所有的數據,或者因爲您知道描述系統狀態作爲時間函數的函數。 'update'因此需要一個浮點數或一個代表 時間的整數,它可以用來計算出系統的新狀態或新狀態本身(以函數或數據本身的形式)。 – Paul

+0

在你的情況下,系統的新狀態在 運行時確定。你也許可以將你的實例包裝在 看起來像一個生成器(它不會)的東西中,但似乎過於複雜了 。因此「框架」論證是多餘的,我忽略它。 – Paul

+0

'fargs'用於將更多參數傳遞給您的更新函數。看代碼,我只是意識到你可能甚至不需要傳入它(原來,我沒有將'update'函數設計爲閉包,在這種情況下,walabot實例不會在範圍內這樣你需要通過它)。 – Paul