I search on internet how using a slider with 3D data and I find this algorithm which plot 3D data in 2D with a slider, so I copy-paste it and I tried to run it in order to adapt it (for solving my real problem : plotting 3D+time data and using a slider to interact with the time). This is my complete code :
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)
A window with the axis and the slider are on my screen but no data is plotted. The plot is just a big blue square and when I interact with the slider I have this error :
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
I don't understand why it doesn't work. All the functions and files that the console cite were added by the import
ation. And I know that the code written by mmensing is ok, so I missed something but what? I'm sure that I did a stupid error, but I don't know where.
To check if the data I created are ok, I write this code to see the 3d plot in 3D without slider :
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()
But it returns this error :
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. ")
What can I do ?
答案 0 :(得分: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)