无法在滑块中索引一些 plt.text

Impossibility to index some plt.text within a slider

我想创建一个有 2 个子图的图:一个圆锥加一个平面,以及当我通过滑块移动平面高度时对应的体积。 我想实现一个每次更改滑块值时都会更改的文本。

现在,只剩下一个问题了:文本相互叠加,形成了完全无用的东西。所以我的想法是索引 pyplot.text 并在每次更改滑块值后删除前一个。 我明白为什么我的解决方案不起作用,但我没有看到任何绕过问题的方法:

完整代码如下:

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


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




""" --------- The Cone & The Plane ----------------------- """

Z = np.sqrt(X**2+Y**2)            #Cone equation

h0 = 10

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

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


l=ax.plot_surface(X,Y,Z2,color='#ff00ff',rstride=3, cstride=3,lw=0.1, alpha=0.2)        #Plane plot
ax.plot_surface(X,Y,Z,color='#dd9900', rstride=2, cstride=2,lw=0.05,alpha=0.4)              #Cone plot : wire frame
#plt.axis('scaled')


""" ----------- The Volume ------------------- """

ax2 = fig.add_subplot(122)                  #create the space for the 2nd window (the vol)

X2 = np.arange(0,250,1)



b= np.pi/3
Vol = b*X2**3     #equation of the cone volume

ax2.plot(X2,Vol,'k')


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

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

i=0
def update(val):                    # function defining the slider

    h = shauteur.val 

    ax.clear()                              #the first plot is cleared and then redraw
    l=ax.plot_surface(X,Y,0*X+0*Y+h,color='#ff00ff',rstride=3, cstride=3,lw=0.1,alpha=0.2)
    ax.plot_surface(X,Y,Z,color='#dd9900', rstride=2, cstride=2,lw=0.05,alpha=0.4)  


    ax2.clear()                             #the 2nd plot is cleared and then redraw

    ax2.plot(X2,Vol,'k')

    ax2.axvline(x=h,   linewidth=1, color = 'r')
    ax2.axhline(y=b*h**3,linewidth=1, color = 'r')

    #ax2.set_xlim(0,2*h)
    #ax2.set_ylim(0,2*b*h**3)

    fig.canvas.draw_idle()

    V=b*h**3

#here, a reset for the plt.text is needed ! The indexing is not working yet

    t_i=plt.text(13,10,'$  Volume =  $\n' '$%s $'%(V), horizontalalignment='center', fontsize=30, bbox=dict(facecolor='k', alpha=0.25))
    t_i.set_visible(False)
    i=i+1               
    print i




shauteur.on_changed(update)


#plt.text(13,10,'$  Volume =  $\n[=11=]00000$', horizontalalignment='center', fontsize=30, bbox=dict(facecolor='k', alpha=0.25),visible=False)

plt.show()

i 如果初始化在 def update(val): 中则不会超过 1 但如果 i在外面:

UnboundLocalError: local variable 'i' referenced before assignment which is also totally understandable.

您可以更新文本而不是重新创建它。 有一个文本实例

text= plt.text( x,y, "some text" )

您可以使用

更新它
text.set_text("new text")

完整示例:

import numpy as np
import matplotlib.pyplot as plt

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

h0 = 10
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)     
zmax = 200
Z2 = 0*X+0*Y+h0
X2 = np.arange(0,250,1) 
b= np.pi/3
Vol = b*X2**3  


fig = plt.figure()
plt.subplots_adjust(bottom=0.25)           
ax = fig.add_subplot(221, projection='3d')  
ax2 = fig.add_subplot(122)        

l=ax.plot_surface(X,Y,Z2,color='#ff00ff',rstride=3, cstride=3,lw=0.1, alpha=0.2)    
ax.plot_surface(X,Y,Z,color='#dd9900', rstride=2, cstride=2,lw=0.05,alpha=0.4)        

ax2.plot(X2,Vol,'k')

text = fig.text(0.3,0.3,"", ha='center', fontsize=20, bbox=dict(facecolor='k', alpha=0.25))

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

def update(val):
    ax.clear()           
    ax2.clear()
    h = shauteur.val 

    l=ax.plot_surface(X,Y,0*X+0*Y+h,color='#ff00ff',rstride=3, cstride=3,lw=0.1,alpha=0.2)
    ax.plot_surface(X,Y,Z,color='#dd9900', rstride=2, cstride=2,lw=0.05,alpha=0.4)  

    ax2.plot(X2,Vol,'k')
    ax2.axvline(x=h,   linewidth=1, color = 'r')
    ax2.axhline(y=b*h**3,linewidth=1, color = 'r')

    V=b*h**3
    tx = '$  Volume =  $\n ${:.2f}$'.format(V)
    text.set_text(tx)
    fig.canvas.draw_idle()

shauteur.on_changed(update)

plt.show()