滑块不会更改3D绘图中的值

时间:2017-04-19 08:25:52

标签: python matplotlib slider

这是我的问题:我想创建一个可以通过滑块修改的平面子图。平面的方程是 Z = 0.X + 0.Y + h ,我想修改 h

终端中的错误:

  

Exception in Tkinter callback Traceback (most recent call last): File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1437, in __call__ return self.func(*args) File "/usr/lib/pymodules/python2.7/matplotlib/backends/backend_tkagg.py", line 286, in button_press_event FigureCanvasBase.button_press_event(self, x, y, num, guiEvent=event) File "/usr/lib/pymodules/python2.7/matplotlib/backend_bases.py", line 1632, in button_press_event self.callbacks.process(s, mouseevent) File "/usr/lib/pymodules/python2.7/matplotlib/cbook.py", line 262, in process proxy(*args, **kwargs) File "/usr/lib/pymodules/python2.7/matplotlib/cbook.py", line 192, in __call__ return mtd(*args, **kwargs) File "/usr/lib/pymodules/python2.7/matplotlib/widgets.py", line 315, in _update self.set_val(val) File "/usr/lib/pymodules/python2.7/matplotlib/widgets.py", line 327, in set_val func(val) File "/home/echos/lagrelle/Stage/Divers/cone.py", line 55, in update l.set_zdata(0*X+0*Y+h) # here's the problem ! AttributeError: 'Poly3DCollection' object has no attribute 'set_zdata'

不要介意左侧子画,先验这与问题无关。所以这里是代码:

""" ---------------------- LIBRAIRIES -------------------------- """

import numpy as np
import matplotlib.pyplot as plt

from mpl_toolkits.mplot3d import Axes3D
from matplotlib.widgets import Slider, Button, RadioButtons


plt.close('all')                        #close the previous figures

fig = plt.figure()
plt.subplots_adjust(bottom=0.25)                #create a little space for the slider

""" ------------------------ The Cone -------------------------- """

ax = fig.add_subplot(121, projection='3d')          #create the space for the first window (the cone)


X= np.arange(-50,50,2)
Y=np.arange(-50,50,2)
X,Y = np.meshgrid(X,Y)

Z = np.sqrt((X**2+Y**2)/(np.tan(np.pi/120)))            #Cone equation
ax.plot_wireframe(X,Y,Z, rstride=3, cstride=3)          #Cone plot : wire frame
plt.axis('scaled')

""" ---------------------- The Plane ---------------------------- """

h0=0

ax2 = fig.add_subplot(122, projection='3d')         #create the space for the 2nd window (the plane)

Z2 = 0*X+0*Y+h0                         #Plane equation

l=ax2.plot_surface(X,Y,Z2,color='red',rstride=2, cstride=2) #Plane plot


""" -------------- The slider ---------------------- """

axhauteur = plt.axes([0.2, 0.1, 0.65, 0.03])            #dimensions of the slider
shauteur = Slider(axhauteur, 'Hauteur', 0.5, 10.0, valinit=h0)  #caracteristics of the slider : from h0 (=0) to 10.0 with a pitch of 0.5

def update(val):                # function defining the slider

    h = shauteur.val                #
    l.set_zdata(0*X+0*Y+h)          # here's the problem ! 
    fig.canvas.draw_idle()          #
shauteur.on_changed(update)         #


plt.show()

谢谢你, QL

1 个答案:

答案 0 :(得分:2)

不幸的是,没有直接set_data方法来更新曲面图 曲面图本身是Poly3DCollection。原则上可以使用.set_verts(verts)更新。但是,verts需要是路径上的点。您可以尝试自己计算它们,但我想更简单的解决方案是简单地重绘曲面图,即清除轴(ax.clear()并创建一个新的曲面图(plot_surface(X,Y,0*X+0*Y+h))。

完整代码:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.widgets import Slider, Button, RadioButtons


fig = plt.figure()
plt.subplots_adjust(bottom=0.25)                
ax = fig.add_subplot(121, projection='3d')        
X= np.arange(-50,50,2)
Y=np.arange(-50,50,2)
X,Y = np.meshgrid(X,Y)

Z = np.sqrt((X**2+Y**2)/(np.tan(np.pi/120)))            
ax.plot_wireframe(X,Y,Z, rstride=3, cstride=3)         
plt.axis('scaled')

h0=0

ax2 = fig.add_subplot(122, projection='3d') 
Z2 = 0*X+0*Y+h0         

l=ax2.plot_surface(X,Y,Z2,color='red',rstride=2, cstride=2)

axhauteur = plt.axes([0.2, 0.1, 0.65, 0.03])
shauteur = Slider(axhauteur, 'Hauteur', 0.5, 10.0, valinit=h0)

def update(val): 
    h = shauteur.val 
    ax2.clear()
    l=ax2.plot_surface(X,Y,0*X+0*Y+h,color='red',rstride=2, cstride=2)
    ax2.set_zlim(0,10)
    fig.canvas.draw_idle() 
shauteur.on_changed(update)
ax2.set_zlim(0,10)

plt.show()