2016-04-15 103 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