2017-09-27 92 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