0

I want to create a plot where there is 2 subplots : a cone plus a plane, and the volume corresponding when I move the plan height thanks to the slider. I would like to implement a text that changes every time I change the value of the slider.

Now, there is just one problem remaining : the text is adding up on each other, creating something completely useless. So my idea was to index the pyplot.text and remove the previous one after each change of the slider value. I understand why my solution is not working but I don't see any way to bypass the problem:

Here's the full code :

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$0000000$', horizontalalignment='center', fontsize=30, bbox=dict(facecolor='k', alpha=0.25),visible=False)

plt.show()

i won't go above 1 if the initialisation is in the def update(val): but it won't work if i is outside :

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

4

1 回答 1

1

You can update the text instead of recreating it. Having a text instance

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

You can update it using

text.set_text("new text")

Complete example:

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()
于 2017-04-24T13:14:06.947 回答