这是我的问题:我想创建一个可以通过滑块修改的平面子图。平面的方程是 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
答案 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()