Bonjour,

Je travaille sur un projet consistant à créer un programme python permettant de modéliser une expérience scientifique tout en pouvant changer certains paramètres à l'aide de curseur de matplotlib.

Nous avons décider de représenter des interférences d'onde. Pour cela nous avons deux sources envoyant chacune un signal sinusoïdal.

Voici le programme qui fonctionne avec l'animation :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import numpy as np               # Boîte à outils numériques
import pylab as py               # Boîte à outils graphiques
from matplotlib import animation # Pour l'animation en temps réel
 
taille=400                       # Largeur en pixels de l'image
lim=10                           # Largeur maximale de l'image
x=np.linspace(-lim,lim,taille)   # L'axe des x
y=x                              # Le même en y
 
X,Y=np.meshgrid(x,y,indexing='xy') # La "grille" sur laquelle seront évaluées les fonctions
 
y1=3                             # Position verticale de la première source
y2=-y1                           # Position verticale de la seconde source
r1=np.sqrt(X**2+(Y-y1)**2)       # Grille des distances à la première source
r2=np.sqrt(X**2+(Y-y2)**2)       # Pareil pour la seconde
 
w=4*np.pi                        # Pulsation des oscillations
delta_t=0.01                     # Intervalle de temps entre deux images
t=0                              # Temps initial
k=1.0*np.pi                      # Nombre d'onde
a1=1                             # Amplitude de la première source
a2=2                             # Amplitude de la seconde source
 
# Calcul de l'amplitude résultante (ne prend pas en compte la décroissance en 
# 1/r que devrait avoir les ondes)
S1 = a1*np.cos(k*r1-w*t)
S2 = a2*np.cos(k*r2-w*t)
amplitude= S1 + S2
 
# Préparation des figures
fig=py.figure(figsize=[16,8],facecolor='w')              # Taille globale
fig.add_axes([0.5,0.05,0.45,0.9],aspect='equal')         # Figure de droite
image=py.imshow(amplitude, extent = [-lim,lim,-lim,lim]) # La superposition
py.plot([0],y1,'wo',markersize=5)                        # Position source 1
py.plot([0],y2,'wo',markersize=5)                        # Position source 2
py.axis([-lim,lim,-lim,lim])                             # Avec axes gradués
#py.axis('off')                                          # ou sans (au choix)
fig.add_axes([0.05,0.05,0.4,0.4],aspect='equal')         # Figure en bas à gauche
image2=py.imshow(S1,  extent =[-lim,lim,-lim,lim])       # Action de S1 seule
py.plot([0],y1,'wo',markersize=5)                        # Position source 1
py.plot([0],y2,'wo',markersize=5)                        # Position source 2
py.axis([-lim,lim,-lim,lim])                             # Avec axes gradués
fig.add_axes([0.05,0.5,0.4,0.4],aspect='equal')          # Figure en haut à gauche
image3=py.imshow(S2, extent = [-lim,lim,-lim,lim])       # Action de S2 seule
py.plot([0],y1,'wo',markersize=5)                        # Position source 1
py.plot([0],y2,'wo',markersize=5)                        # Position source 2
#py.axis('off')                                          # ou sans
py.axis([-lim,lim,-lim,lim])                             # Avec axes gradués
#py.axis('off')                                          # ou sans
 
#py.savefig('PNG/S03_interferences_figure_init.png')
 
def animate(i): # Mise à jour des figures à chaque nouvelle frame
    t=i*delta_t                           # Nouveau temps
    print(t)                              # Feedback en cas de sauvegarde
    S1 = a1*np.cos(k*r1-w*t)              # Source 1
    S2 = a2*np.cos(k*r2-w*t)              # Source 2
    amplitude= S1 + S2                    # Superposition
    image.set_data(amplitude)             # Mise à jour données superposition
    py.title('t=%.2f s'%(t))              # Le titre avec l'instant choisi
    image2.set_data(S1)                   # Mise à jour source 1
    image3.set_data(S2)                   # Mise à jour source 2
 
# L'animation proprement dite
anim = animation.FuncAnimation(fig,animate,frames=int(3/delta_t),interval=20)
 
# À décommenter pour sauvegarder dans un fichier .mp4
#anim.save('PNG/S03_interferences_animation.mp4', fps=10)
 
# Sinon, on montre en direct
py.show()


Nous souhaiterions maintenant intégrer des curseurs afin de faire varier l'amplitude d'une des sources ainsi que sa fréquence.

Nous essayons de nous inspirer de cet exemple de curseur :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
 
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button, RadioButtons
fig, ax = plt.subplots()
plt.subplots_adjust(left=0.25, bottom=0.25)
t = np.arange(0.0, 1.0, 0.001)
a0 = 5
f0 = 3
s = a0*np.sin(2*np.pi*f0*t)
l, = plt.plot(t,s, lw=2, color='red')
plt.axis([0, 1, -10, 10])
axcolor = 'lightgoldenrodyellow'
axfreq = plt.axes([0.25, 0.15, 0.65, 0.03], axisbg=axcolor)
axamp  = plt.axes([0.25, 0.15, 0.65, 0.03], axisbg=axcolor)
 
 
 
sfreq = Slider(axfreq, 'Freq', 0.1, 30.0, valinit=f0)
 
samp = Slider(axamp, 'Amp', 0.1, 10.0, valinit=a0)
 
def update(val):
    amp = samp.val
    freq = sfreq.val
    l.set_ydata(amp*np.sin(2*np.pi*freq*t))
    fig.canvas.draw_idle()
sfreq.on_changed(update)
samp.on_changed(update)
resetax = plt.axes([0.8, 0.025, 0.1, 0.04])
button = Button(resetax, 'Reset', color=axcolor, hovercolor='0.975')
 
 
def reset(event):
    sfreq.reset()
    samp.reset()
button.on_clicked(reset)
axcolor = 'lightgoldenrodyellow'
rax = plt.axes([0.025, 0.6, 0.25, 0.25], axisbg=axcolor)
radio = RadioButtons(rax, ('red','green','blue'), active=0)
 
 
 
def colorfunc(label):
    l.set_color(label)
    fig.canvas.draw_idle()
radio.on_clicked(colorfunc)
plt.show()
Le problème est donc que nous n'arrivons pas à intégrer les curseurs au premier programme...
Est-ce que quelqu'un aurait une idée ?

merci beaucoup

Thibaut