【问题标题】:A slider doesn't change a value in a 3D plot滑块不会更改 3D 绘图中的值
【发布时间】:2017-04-19 17:25:51
【问题描述】:

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

【问题讨论】:

  • 哪一行? .请粘贴整个错误消息
  • @Abhimanyusingh 我已经编辑了问题
  • 一种解决方法是使用ax2.cla() 清除轴,然后使用更新的值重新绘制它。
  • 我是 Matplot lib 的新手,但从 python 的角度来看,我建议尝试print dir(l) 以获取支持的属性列表

标签: python matplotlib slider


【解决方案1】:

很遗憾,没有直接的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()

【讨论】:

  • 谢谢。我正是试图通过重绘来绕过这个问题。那么,非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-15
  • 1970-01-01
相关资源
最近更新 更多