Comment créer des boutons dans Jupyter

Interagissez avec vos fonctions en cliquant sur les boutons de votre bloc-notes

Photo par Owen Beard sur Unsplash

J'aime beaucoup les cahiers Jupyter. Lorsque j’en utilise un, j’ai l’impression d’être un livre de sorts interactif: capable d’afficher du texte, des images, des vidéos, y compris des formules mathématiques et du code, et de créer un environnement intérieur avec vos variables et fonctions. Comparé aux pierres à sculpter avec vos notes, cet outil vous donne l’impression de vous retrouver dans l’avenir.

Et il existe encore un aspect intéressant des blocs-notes que je n'ai pas encore mentionné: vous pouvez également interagir activement avec votre bloc-notes en manipulant directement les widgets et en autorisant un type spécifique d'interactions utilisateur-ordinateur. Voyons comment nous pouvons faire cela en utilisant ipywidgets, un paquet très cool avec tous les outils nécessaires pour construire une interface graphique simple.

Installation

Commençons par installer et activer le paquet en exécutant le code suivant sur votre terminal.

pip installer ipywidgets
jupyter nbextension enable --py widgetsnbextension

Si vous travaillez avec Jupyter Lab: vous devrez installer node.js et l'activer à l'aide d'une commande différente:

jupyter labextension install @ jupyter-widgets / jupyterlab-manager

Avant de commencer, il est important de distinguer deux types de widgets:

  • Certains d'entre eux prennent en charge les interactions avec l'utilisateur, par exemple les fenêtres de texte, les boutons et les cases à cocher.
  • Tandis que d'autres agissent en tant que conteneurs regroupant des widgets, par exemple des boîtes, des panneaux et des onglets.

Création de widgets

Maintenant que le paquet est installé, nous pouvons immédiatement instancier n'importe quel widget de notre bloc-notes. Vous pouvez cliquer ici pour consulter la liste des widgets actuellement disponibles avec le code afin de les initialiser. Voyons quelques exemples définissant certains widgets:

# quelques fonctions pratiques à utiliser avec les widgets
depuis l’affichage d’importation IPython.display, Markdown, clear_output
# paquets de widgets
importer ipywidgets en tant que widgets
# définir des widgets
text = widgets.Text (
       valeur = 'Mon texte',
       description = 'Titre',)
calendar = widgets.DatePicker (
           description = 'Choisir la date')
slider = widgets.FloatSlider (
         valeur = 1,
         min = 0,
         max = 10,0,
         step = 0.1,)
menu = widgets.Dropdown (
       options = ['rouge', 'bleu', 'vert'],
       valeur = 'rouge',
       description = 'Couleur:')
checkbox = widgets.Checkbox (
           description = 'Cocher pour inverser',)

Comme indiqué ci-dessus (et dans la plupart des cas), l’initialisation des widgets implique l’appel d’une fonction simple et la spécification d’arguments explicatifs, c’est très simple. Ici, nous avons défini un menu déroulant, un curseur, une case à cocher, une fenêtre de texte et un calendrier dans notre cahier. Vous pouvez afficher n'importe lequel d'entre eux en appelant l'objet dans une cellule:

m e n u

Mais pour les afficher complètement, nous devons utiliser un widget conteneur.

Création de conteneurs

Les plus courants sont définis à l'aide des fonctions VBox et HBox et servent à afficher nos widgets respectivement verticalement et horizontalement. Ils s'attendent à un seul argument: une liste de widgets.

box = widgets.VBox ([texte, curseur, menu, calendrier, case à cocher])
boîte

Les conteneurs VBox et HBox étant également des widgets, nous pouvons les utiliser les uns dans les autres. Voyons un exemple factice:

widgets.HBox ([box, box])
Notre conteneur VBox est maintenant affiché deux fois horizontalement avec HBox

Alternativement, nous pouvons utiliser un autre type de conteneur sur le dessus. Voyons le conteneur Tab. Bien que légèrement plus complexe, cela nous aide à mieux utiliser l'espace:

# définir une liste avec le contenu de nos fenêtres
enfants = [boîte, boîte]
# initialisation d'un onglet
tab = widgets.Tab ()
# réglage des fenêtres à onglet
tab.chenfants = enfants
# changer le titre de la première et de la deuxième fenêtre
tab.set_title (0, 'box')
tab.set_title (1, 'copie de la boîte')
languette
Maintien des conteneurs VBox dans deux fenêtres différentes à l'aide d'un onglet

Les widgets contiennent des attributs

Maintenant que nous savons instancier et mettre en page nos widgets, il est vraiment important de garder à l’esprit que chacun de ces widgets est défini en tant qu’objet et possède ses propres attributs. Vous pouvez dire que chaque widget a son propre ensemble de nuances. Par exemple, le menu a un attribut appelé options:

Options de menu
Un tuple de nos options définies

La redéfinition de cet attribut changerait les options actuelles de notre widget.

menu.options = ('rouge', 'bleu', 'vert', 'noir')
m e n u

À l'exception des conteneurs, un attribut commun à tous les widgets que nous avons définis ci-dessus est value et pourrait bien être le plus utile. Cela signifie exactement ce qu'il devrait faire: l'appelant renvoie la valeur actuelle du widget.

# valeur actuelle du texte, de la case à cocher et du calendrier
print ('Le texte du widget a une valeur {}, de {}'. format (text.value, type (text.value)))
print ('La case à cocher du widget a la valeur {}, de {}'. format (checkbox.value, type (checkbox.value)))
print ('Le calendrier du widget a une valeur {}, de {}'. format (calendar.value, type (calendar.value)))
Notez que différents widgets contiennent différents types de valeurs!

Pouvoir récupérer la valeur de notre widget est ce qui vous permet vraiment de les faire interagir avec votre code. Voyons un exemple factice en utilisant menu.

# Nous allons utiliser la valeur de menu pour afficher un tracé et son titre
importer matplotlib.pyplot en tant que plt
plt.plot ([1,2,3], color = valeur de menu)
plt.title ('A {} line'.format (menu.value))
plt.show ()

Changer la valeur de notre menuwidget et ré-exécuter le code ci-dessus changera le titre et la couleur de la ligne. Nous pouvons le faire parce que les options de menu correspondent à des valeurs valides pour la couleur de l'argument de plt.plot.

Cela met en évidence une propriété utile des widgets: vous pouvez les utiliser pour contrôler des éléments sans avoir à les taper explicitement.

Création de boutons

Vous avez peut-être remarqué que tout ce que nous avons fait ci-dessus consiste à cliquer sur les widgets et à sélectionner des éléments. Mais pour pouvoir réellement déclencher quelque chose, nous avons exécuté des lignes de code. Nous avons besoin d'un widget capable de déclencher une réponse et d'exécuter du code, nous avons besoin de la puissance du bouton.

L'instanciation d'un bouton ressemble à la façon dont nous avons défini les widgets:

button = widgets.Button (description = 'Mon bouton')
Rien ne se passe…

Mais pour rendre notre bouton fonctionnel, nous devons également définir ce qui se passe lorsque vous appuyez dessus. En termes simples, ceci est réalisé par:

  • Définir un widget de sortie qui affiche la réponse.
  • Définir une fonction à exécuter.
  • Lier notre bouton, la sortie et la fonction ensemble.

Voici un petit extrait que j’utilise tout le temps lors de la création d’un nouveau bouton: ce sera le modèle de nos exemples.

button = widgets.Button (description = 'Mon bouton')
out = widgets.Output ()
def on_button_clicked (_):
      # "fonction de liaison avec la sortie"
      sans pour autant:
          # qu'est-ce qui se passe quand on appuie sur le bouton
          clear_output ()
          print ('Quelque chose se passe!')
# reliant le bouton et fonctionnent ensemble en utilisant la méthode d'un bouton
button.on_click (on_button_clicked)
# affichant le bouton et sa sortie ensemble
widgets.VBox ([button, out])
Remarquez comment nous utilisons VBox pour afficher verticalement le bouton et sa sortie

La fonction clear_output rafraîchit notre affichage chaque fois que l'on appuie sur notre bouton. Si nous omettons cette fonction, appuyer plusieurs fois sur le bouton affichera plusieurs fois «Il se passe quelque chose!», Ce qui semble indésirable. Le widget de sortie est vraiment intéressant: nous pouvons l’utiliser pour afficher des instructions d’impression (comme nous l’avons fait ci-dessus), des graphiques, des vidéos, des images et, en gros

tout ce qui s'affiche bien dans un bloc-notes Jupyter sera également bien affiché dans le widget Sortie.

Voyons un exemple trivial de la façon dont nous pouvons l’utiliser pour afficher Markdown.

depuis IPython.display, importez Markdown
# Utilisation de la sortie pour afficher Markdown
markdown_out = widgets.Output ()
avec markdown_out:
    display (Markdown ('La valeur du curseur est $ {} $'. format (slider.value)))
markdown_out
Utilisation de Markdown pour afficher la valeur du widget

Notez que nous rendons la valeur du curseur sous forme d'expression mathématique en entourant l'espace réservé de symboles $.

Exemples

Maintenant que nous avons eu un aperçu de la façon de définir, d’organiser et d’utiliser divers widgets, nous avons vu tous les outils nécessaires pour assembler quelque chose de sympa. Voyons quelques exemples pratiques! Assurez-vous de les coller dans vos cahiers pour voir les widgets en action.

Explorer les variables globales

Certaines personnes aiment voir facilement quelles variables sont définies dans votre environnement de travail. Faisons un peu d’aide pour cela. Nous allons créer un menu pour sélectionner une option parmi nos variables globales. Appuyez sur le bouton pour vérifier son type et l’imprimer.

  • Ligne 4: en utilisant globals nous obtenons la liste de toutes les variables globales définies dans notre scope.
  • Nous excluons les variables avec des traits de soulignement et utilisons le reste comme options pour notre menu (ligne 12).
  • Nous créons un bouton, une sortie et une fonction sur laquelle nous imprimons le type de variable sélectionnée (lignes 14 à 20).
  • Liez le bouton et sa fonction ensemble (ligne 22) et affichez un conteneur avec nos widgets (ligne 24).
Nous utilisons l'extrait de bouton

Explorer un jeu de données

Faisons une autre démonstration de ce que vous pouvez faire pour explorer un jeu de données en utilisant à nouveau un menu et un bouton. Nous allons utiliser les utilisateurs du menu pour sélectionner une valeur spécifique. Appuyez sur le bouton pour calculer diverses informations à partir du jeu de données en fonction de celui-ci et afficher les résultats à l'aide de Markdown.

  • À la ligne 8, nous définissons les utilisateurs de notre menu avec les valeurs uniques de notre colonne df ["Utilisateurs"].
  • Aux lignes 16, 17 et 18, nous définissons un bouton, une sortie et une fonction. La fonction utilisera users.value pour sous-définir notre jeu de données et calculer certaines variables.
  • Ceux-ci sont passés à l'intérieur des espaces réservés dans la chaîne (lignes 40 à 48). A la ligne 50, nous associons notre bouton à la fonction avec la méthode du bouton .on_click ().
  • À la ligne 52, nous affichons enfin notre menu, notre bouton et notre sortie à l’intérieur de la conteneurVBox.
Les widgets ne font rien par eux-mêmes, vous devez donc écrire un peu de code pour aller quelque part. Cet exemple permet une manière intuitive de visualiser et de partager les résultats dans les données: il renvoie une liste d'observations.

Graphique 2D / 3D

Si vous le souhaitez, vous pouvez également afficher du code HTML dans un bloc-notes. Lançons une démonstration de l’assemblage de widgets pour créer un graphe d’expressions mathématiques utilisant Graph3d (une bibliothèque Javascript) et matplotlib. Nous appellerons la valeur d'une fenêtre de texte (équation) à l'intérieur de la fonction exec, qui exécute le code python sous forme de chaîne. Chaque fois que vous appuyez sur le bouton, nous calculons les points de notre graphique en exécutant l’intérieur de équation.value sous forme de code python. (Je comprends qu'il pourrait y avoir une meilleure façon de faire ceci).

J'ai écrit quelques instructions sur la façon de l'utiliser:

Graphique 2D

Taper X ou Y dans la zone de texte de l'équation fera un tracé en deux dimensions. Si nous saisissons à la fois X et Y, un tracé 3D apparaîtra.

Graphique 3D

Ici, nous utilisons les mêmes étapes que précédemment: nous définissons un bouton, une sortie et une fonction (qui utilise les valeurs de nos autres widgets) et les relions ensemble. C’est l’essentiel que vous devez retenir si vous souhaitez utiliser des boutons pour interagir avec votre code. Espérons que cela soit maintenant suffisamment clair.

Voici le code que j'ai utilisé pour le faire:

Réutilisation de vos interfaces graphiques

Une fois que vous avez essayé d’assembler une interface graphique, vous souhaitez pouvoir l’invoquer chaque fois que vous en avez besoin. Il existe un moyen rapide d'appeler vos widgets pour obtenir de l'aide à l'aide de% run, une commande magique intégrée de Jupyter. Vous pouvez l'utiliser pour exécuter sans effort le code des autres cahiers de votre cahier actuel. est très pratique.

Supposons qu'il y a longtemps que vous avez défini des widgets dans un fichier nommé math_widgets.ipynb et que vous souhaitez les appeler dans votre carnet actuel. Tout ce que vous avez à faire est d’appeler la commande magique en spécifiant le chemin du fichier:

% exécuter math_widgets.ipynb

Conclusions

  • L'ajout de widgets à vos cahiers vous permet d'agir en tant que médiateur entre le code et la sortie en interagissant avec les variables.
  • Il est particulièrement bien adapté à l’exploration et au changement dynamique des appels de fonctions.
  • Ce n’est peut-être pas toujours la chose la plus productive à faire.

C’est tout, j’espère que ce tutoriel vous encourage à créer et à utiliser des widgets dans vos cahiers!