Python >> Tutoriel Python >  >> Python Tag >> Matplotlib

Widgets Matplotlib - Création de tracés interactifs avec des curseurs

Cet article décrit comment générer des tracés interactifs en utilisant le .widgets package de la bibliothèque matplotlib. Comme on peut le déduire du nom, le .widgets permet de créer différents types de boutons interactifs, qui peuvent être utilisés pour modifier ce qui est affiché dans un graphique matplotlib.

En particulier, cet article se concentrera sur la création d'un bouton Slider qui sera ensuite utilisé pour changer le type de courbe Spline interpolant le tracé d'origine. De cette manière, il sera possible d'évaluer en temps réel l'effet de la modification de certains paramètres de la spline sur l'ajustement.

Mais commençons par la fin :voici le code que vous allez explorer et l'intrigue qui en résulte :

import numpy as np
from scipy.interpolate import UnivariateSpline
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider

# Initial x and y arrays
x = np.linspace(0, 10, 30)
y = np.sin(0.5*x)*np.sin(x*np.random.randn(30))

# Spline interpolation
spline = UnivariateSpline(x, y, s = 6)
x_spline = np.linspace(0, 10, 1000)
y_spline = spline(x_spline)

# Plotting
fig = plt.figure()
plt.subplots_adjust(bottom=0.25)
ax = fig.subplots()
p = ax.plot(x,y)
p, = ax.plot(x_spline, y_spline, 'g')

# Defining the Slider button
# xposition, yposition, width and height
ax_slide = plt.axes([0.25, 0.1, 0.65, 0.03])

# Properties of the slider
s_factor = Slider(ax_slide, 'Smoothing factor',
                  0.1, 6, valinit=6, valstep=0.2)

# Updating the plot
def update(val):
    current_v = s_factor.val
    spline = UnivariateSpline(x, y, s = current_v)
    p.set_ydata(spline(x_spline))
    #redrawing the figure
    fig.canvas.draw()
    
# Calling the function "update" when the value of the slider is changed
s_factor.on_changed(update)
plt.show()

La sortie est une fenêtre de tracé Python interactive qui vous permet de contrôler le graphique avec un curseur :

Vous pouvez essayer de l'exécuter dans votre navigateur dans le notebook Jupyter interactif suivant, que j'ai créé pour vous :

Plongeons-nous dans le code et explorons-le étape par étape.

Importer des bibliothèques

  • Tout d'abord, nous commençons par importer tous les packages qui seront utilisés dans cet exemple. Nous utiliserons Numpy pour définir la fonction initiale et UnivariateSpline , à partir du Scipy.interpolate package, pour créer la courbe spline qui interpolera la fonction initiale.
  • Après cela, nous devons importer matplotlib.pyplot pour tracer.
  • Enfin, nous importons le package Slider , à partir du matplotlib.widgets bibliothèque, cela nous permettra de modifier interactivement la courbe spline déjà tracée.

Les lignes de code suivantes décrivent l'importation des packages mentionnés ci-dessus.

import numpy as np
from scipy.interpolate import UnivariateSpline
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider 

Définir la fonction initiale qui sera ajustée par la spline

Pour définir la fonction initiale, nous créons deux tableaux "x" et "y" qui contiennent les points de données décrivant la fonction.

Le tableau "x" est défini en exploitant le .linspace() fonction de Numpy ; en particulier on initialise un tableau de 30 nombres de 0 à 10.

Le tableau "y" est décrit par une fonction plus complexe, afin de rendre l'approximation spline plus délicate et donc d'être en mesure d'apprécier l'effet de la modification des paramètres de définition de spline. Comme vous pouvez le voir dans les lignes de code suivantes, le tableau "y" est défini par la combinaison du .sin() et .random.randn() fonctions, toutes deux appartenant à la bibliothèque Numpy.

#initial x and y arrays
x = np.linspace(0, 10, 30)
y = np.sin(0.5*x)*np.sin(x*np.random.randn(30)) 

Création de la courbe spline

Nous poursuivons avec la génération de la courbe spline qui doit correspondre à la fonction initiale.

  • L'ensemble des fonctions décrivant la spline est affecté à la variable "spline".
  • La fonction utilisée pour générer l'interpolation spline est .UnivariateSpline() , du Scipy.interpolate bibliothèque.

Tutoriel associé : Si vous êtes intéressé par les courbes splines et leur implémentation en Python, vous trouverez ici un article dédié.

Les entrées obligatoires du .UnivariateSplin La fonction sont les tableaux "x" et "y", nous spécifions ensuite le facteur de lissage , un paramètre qui définit la précision de l'interpolation spline ; il indique essentiellement à la fonction quand arrêter le processus d'interpolation, en fonction de la différence entre les valeurs réelles et celles interpolées.

Pour la première spline, nous insérons "6" comme valeur initiale du facteur de lissage. Après avoir appelé la fonction spline, nous définissons les tableaux x et y qui contiennent les points décrivant la courbe spline, appelés x_spline et y_spline , respectivement.

#Spline interpolation
spline = UnivariateSpline(x, y, s = 6)
x_spline = np.linspace(0, 10, 1000)
y_spline = spline(x_spline)

Traçage

L'étape suivante consiste à tracer la fonction initiale et la courbe spline que nous venons de définir. On déplace la fenêtre dans laquelle sera affiché le tracé un peu vers le haut en exploitant la commande plt.subplots_adjust(bottom=0.25) dans lequel nous devons spécifier l'espace que nous voulons garder vide le long des bordures ; cette fois, nous voulons juste un peu d'espace dans la partie inférieure de la fenêtre, afin de pouvoir ajouter le curseur.

La dernière chose importante concernant cette étape est d'ajouter "," après la variable dans laquelle nous stockons le tracé ("p"); cela nous permet de décompresser la valeur unique en "p" et donne donc la possibilité d'agir dessus.

Les lignes de code suivantes expliquent comment tracer la fonction initiale et la courbe spline.

#Plotting
fig = plt.figure()
plt.subplots_adjust(bottom = 0.25)
ax = fig.subplots()
p = ax.plot(x,y)
p, = ax.plot(x_spline, y_spline, 'g')

Nous n'ajoutons pas le "plt.show() ” commande puisqu'il nous reste à inclure la définition du Slider.

Comment introduire le bouton curseur dans la fenêtre de tracé

Une fois que nous avons réussi à générer la fonction, la courbe spline et à les tracer, nous pouvons maintenant passer à la création du bouton Slider. La première chose à faire est de définir l'espace dans lequel le bouton sera affiché dans la fenêtre de tracé.

Pour cela, on crée d'abord l'espace qui sera dédié au slider en utilisant la fonction matlplotlib .axes() qui ajoute un axe à la figure actuelle (documentation complémentaire ici).

En entrée de cette fonction, nous insérons une liste de valeurs, ces valeurs représentent la position horizontale et verticale du curseur, sa largeur et sa hauteur, respectivement.

#Defining the Slider button
ax_slide = plt.axes([0.25, 0.1, 0.65, 0.03]) #xposition, yposition, width and height

Après avoir créé l'espace pour le slider, il faut maintenant préciser les caractéristiques du bouton. Nous le faisons en exploitant la fonction appropriée, Slider , dans lequel nous spécifions plusieurs propriétés liées au bouton.

La première entrée spécifie l'emplacement dans lequel le curseur sera situé, nous ajoutons "ax_slide ” qui est la variable référencée à l'espace qui vient d'être créé à l'étape précédente. Après cela, nous pouvons spécifier l'étiquette qui apparaîtra à côté du curseur (nous utilisons "Smoothing factor ”), les valeurs minimum et maximum, la valeur initiale et l'incrément d'unité.

Vous pouvez trouver une description complète de tous ces paramètres ici :https://matplotlib.org/3.3.3/api/widgets_api.html.

#Properties of the slider
s_factor = Slider(ax_slide, 'Smoothing factor', 0.1, 6, valinit=6, valstep=0.2)

Le tableau 1 résume les paramètres utilisés lors de l'appel de la fonction "Slider".

Fonction curseur
Syntaxe : Curseur
Paramètres : ax Axes définissant l'espace dans lequel le curseur sera situé
label Libellé qui apparaît sur le bouton du curseur
valmin Valeur minimale du curseur
valmax Valeur maximale du curseur
valinit Valeur initiale du curseur
valstep Incrémentation du curseur
Valeur de retour None

Tableau 1 : définition de la fonction Slider et de ses paramètres.

Mise à jour du tracé lors de la modification de la valeur du curseur

A ce stade, nous avons créé le curseur, si nous le traçons, nous sommes déjà capables de modifier sa valeur mais nos actions ne généreront aucune modification dans le tracé; c'est parce que nous devons toujours relier les valeurs du curseur à celles qui sont tracées dans la figure.

Pour accomplir cette tâche, nous devons définir une fonction qui contient la liste des actions qui seront prises chaque fois que la valeur du curseur est modifiée. La fonction s'appellera « mise à jour » et n'acceptera en entrée qu'une seule valeur numérique, correspondant à la valeur sélectionnée sur le curseur. Dans cette fonction, nous créons une variable locale "current_v » dans lequel on stocke la valeur du slider en appliquant la méthode « .val ” au Slider que nous avons créé précédemment (“s_factor ”).

Maintenant que nous avons stocké la valeur mise à jour du curseur, nous devons répéter l'étape d'interpolation spline, afin de mettre à jour la courbe spline ; dans cet appel, nous insérons "current_v ” comme valeur du nouveau facteur de lissage.

Ainsi, à chaque changement de curseur, la fonction répétera l'interpolation spline en utilisant la nouvelle valeur indiquée sur le curseur, comme nouveau facteur de lissage. On fixe ensuite les nouvelles valeurs sur le tracé par la commande .set_ydata() appliqué à la variable décrivant le tracé (“p ”). La dernière étape consiste à redessiner la figure actuelle avec les données mises à jour, ceci est accompli par la fonction matplotlib .draw()

Connexe :Ici vous trouvez la documentation officielle :https://matplotlib.org/3.3.3/api/_as_gen/matplotlib.pyplot.draw.html

#Updating the plot
def update(val):
    current_v = s_factor.val
    spline = UnivariateSpline(x, y, s = current_v)
    p.set_ydata(spline(x_spline))
    fig.canvas.draw()  #redrawing the figure

La toute dernière chose à spécifier est l'événement qui déclenchera l'appel de la fonction « mise à jour ».

Nous voulons que le tracé soit mis à jour chaque fois que la valeur du curseur est modifiée ; nous pouvons le faire en exploitant la méthode .on_changed() , appliqué à la variable "s_factor ”, qui fait référence au curseur.

En tant qu'entrée de cette commande, nous devons spécifier ce qu'il faut faire lorsque la valeur du curseur est modifiée ; comme dit précédemment, nous souhaitons que la fonction « update » soit lancée à chaque modification du slider, afin d'itérer la procédure d'interpolation spline.

Après cela, nous pouvons enfin taper "plt.show() ” pour tracer le graphique et commencer à jouer avec notre bouton curseur ! Comme vous pouvez le remarquer, plus nous diminuons le facteur de lissage, meilleure est l'interpolation spline.

#calling the function "update" when the value of the slider is changed
s_factor.on_changed(update) 
plt.show() 

Le GIF suivant affiche le résultat final de cet exemple.