2016-04-15 102 views
1

我在互聯網上搜索如何使用滑塊與3D數據,我發現this algorithm哪些繪製2D與滑塊的3D數據,所以我複製粘貼它,我試圖按順序運行它以適應它(用於解決my real problem:繪製3D +時間數據並使用滑塊與時間交互)。 這是我的完整代碼:錯誤與滑塊繪圖(蟒蛇matplotlib)

import numpy as np 
import matplotlib.pyplot as plt 
from matplotlib.widgets import Slider, Button, RadioButtons 
import scipy.ndimage as ndi 

data = np.zeros((10, 10, 10)) 
data[5, 5, 5] = 10. 
data = ndi.filters.gaussian_filter(data, sigma=1) 
print(data.max()) 

def cube_show_slider(cube, axis=0, **kwargs): 
    """ 
    Display a 3d ndarray with a slider to move along the third dimension. 
    Extra keyword arguments are passed to imshow 
    """ 
    # check dim 
    if not cube.ndim == 3: 
     raise ValueError("cube should be an ndarray with ndim == 3") 
    # generate figure 
    fig = plt.figure() 
    ax = plt.subplot(111) 
    fig.subplots_adjust(left=0.25, bottom=0.25) 
    # select first image 
    s = [slice(0, 1) if i == axis else slice(None) for i in range(3)] 
    im = cube[s].squeeze() 
    # display image 
    l = ax.matshow(im, **kwargs) 
    cb = plt.colorbar(l) 
    cb.set_clim(vmin=data.min(), vmax=data.max()) 
    cb.draw_all() 
    # define slider 
    axcolor = 'lightgoldenrodyellow' 
    ax = fig.add_axes([0.25, 0.1, 0.65, 0.03], axisbg=axcolor) 
    slideryo = Slider(ax, 'Axis %i index' % axis, 0, cube.shape[axis] - 1, valinit=0, valfmt='%i') 
    slideryo.on_changed(update) 
    plt.show() 

def update(val): 
    ind = int(slider.val) 
    s = [slice(ind, ind + 1) if i == axis else slice(None) for i in range(3)] 
    im = cube[s].squeeze() 
    l.set_data(im, **kwargs) 
    cb.set_clim(vmin=data.min(), vmax=data.max()) 
    cb.formatter.set_powerlimits((0, 0)) 
    cb.update_ticks() 
    cb.draw_all() 
    fig.canvas.draw() 

cube_show_slider(data) 

與軸和滑動窗口是我的屏幕上,但沒有數據繪製。情節只是一個大的藍色方塊,當我與滑塊交互時,我有這個錯誤:

Traceback (most recent call last): 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/backend_bases.py", line 1952, in motion_notify_event 
     self.callbacks.process(s, event) 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/cbook.py", line 563, in process 
     proxy(*args, **kwargs) 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/cbook.py", line 430, in __call__ 
     return mtd(*args, **kwargs) 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/widgets.py", line 434, in _update 
     self.set_val(val) 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/widgets.py", line 448, in set_val 
     func(val) 
    File "<stdin>", line 2, in update 
     NameError: global name 'slider' is not defined 

我不明白爲什麼它不起作用。控制檯引用的所有功能和文件都是由import添加的。而且我知道由主編寫的代碼是好的,所以我錯過了什麼,但是什麼?我確信我做了一個愚蠢的錯誤,但我不知道在哪裏。

要檢查,如果我創建都OK的數據,我寫這篇文章的代碼以3D方式觀看3D圖無滑塊:

import matplotlib as mpl 
from mpl_toolkits.mplot3d import Axes3D 
import numpy as np 
import matplotlib.pyplot as plt 
import scipy.ndimage as ndi 

mpl.rcParams['legend.fontsize'] = 10 
fig = plt.figure() 
ax = fig.gca(projection='3d') 
data = np.zeros((10, 10, 10)) 
data[5, 5, 5] = 10. 
data = ndi.filters.gaussian_filter(data, sigma=1) 
ax.plot(data[0,:,:], data[1,:,:], data[2,:,:], label='my data') 
ax.legend()  
plt.show() 

但它返回此錯誤:

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
     File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mpl_toolkits/mplot3d/axes3d.py", line 1541, in plot 
lines = Axes.plot(self, xs, ys, *args[argsi:], **kwargs) 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/__init__.py", line 1812, in inner 
    return func(ax, *args, **kwargs) 
     File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/axes/_axes.py", line 1424, in plot 
for line in self._get_lines(*args, **kwargs): 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/axes/_base.py", line 386, in _grab_next_args 
    for seg in self._plot_args(remaining, kwargs): 
     File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/axes/_base.py", line 339, in _plot_args 
raise ValueError('third arg must be a format string') 
    ValueError: third arg must be a format string 
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/axes/_axes.py:519: UserWarning: No labelled objects found. Use label='...' kwarg on individual plots. 
    warnings.warn("No labelled objects found. ") 

能有什麼我做 ?

回答

0

我已經糾正你的代碼,你有一些錯誤,你可以通過比較發現:

  • 更新功能需要在子程序這樣定義:它是可訪問的還有,壓痕錯誤
  • 您的滑塊有不同位置的兩個不同名稱
  • 只有在定義了功能後纔會引用更新功能。

希望它現在有效。

import numpy as np 
import matplotlib.pyplot as plt 
from matplotlib.widgets import Slider, Button, RadioButtons 
import scipy.ndimage as ndi 

data = np.zeros((10, 10, 10)) 
data[5, 5, 5] = 10. 
data = ndi.filters.gaussian_filter(data, sigma=1) 
print(data.max()) 
print data.shape 

def cube_show_slider(cube, axis=0, **kwargs): 
    """ 
    Display a 3d ndarray with a slider to move along the third dimension. 
    Extra keyword arguments are passed to imshow 
    """ 
    # check dim 
    if not cube.ndim == 3: 
     raise ValueError("cube should be an ndarray with ndim == 3") 

    # generate figure 
    fig = plt.figure() 
    ax = plt.subplot(111) 
    fig.subplots_adjust(left=0.25, bottom=0.25) 

    # select first image 
    s = [slice(0, 1) if i == axis else slice(None) for i in range(3)] 
    im = cube[s].squeeze() 

    # display image 
    l = ax.matshow(im, **kwargs) 
    cb = plt.colorbar(l) 
    cb.set_clim(vmin=data.min(), vmax=data.max()) 
    cb.draw_all() 

    # define slider 
    axcolor = 'lightgoldenrodyellow' 
    ax = fig.add_axes([0.25, 0.1, 0.65, 0.03], axisbg=axcolor) 
    slideryo = Slider(ax, 'Axis %i index' % axis, 0, cube.shape[axis] - 1, valinit=0, valfmt='%i') 

    def update(val): 
     ind = int(slideryo.val) 
     s = [slice(ind, ind + 1) if i == axis else slice(None) for i in range(3)] 
     im = cube[s].squeeze() 
     l.set_data(im, **kwargs) 
     cb.set_clim(vmin=data.min(), vmax=data.max()) 
     cb.formatter.set_powerlimits((0, 0)) 
     cb.update_ticks() 
     cb.draw_all() 
     fig.canvas.draw() 

    slideryo.on_changed(update) 
    plt.show() 


cube_show_slider(data) 
+0

謝謝,它的工作原理!但是現在如果你能回答,我會利用這一點。我想知道:在我的問題的第二部分,我的錯誤是什麼? (關於3D圖)是這條線'ax.plot(data [0,:,],data [1,:,],data [2,:,],label ='my data')' ? – EaudeRoche