Matplotlib
Le thème propose des fonctionnalités pour faciliter l'intégration de graphiques réalisés avec matplotlib
dans la documentation, créés à partir de données/codes dans pyodide.
Ces outils sont une évolution d'un travail proposé initialement par Nicolas Révéret.
Principe général#
L'idée générale pour que cela fonctionne est la suivante :
- Insérer dans le fichier markdown un élément html (une
<div>
) qui accueillera la figure une fois qu'elle sera créée. - Importer
matplotlib
depuis pyodide. - Configurer
matplotlib
pour interagir avec le DOM. - Construire les données et afficher les courbes souhaitées dans la
div
créée au point 1.
- L'étape 1 est facilitée par l'utilisation de la macro
{{ figure(...) }}
. - L'étape 2 est faite par l'utilisateur, normalement depuis la section
env
du fichier python associé à une macroIDE
,terminal
,py_btn
ourun
. - L'étape 3 est gérée automatiquement par le thème, lorsqu'un import de
matplotlib
est détecté (étape 2). - L'étape 4 est facilitée par l'utilisation d'objets de la classe
PyodidePlot
(déclarée automatiquement par le thème, lors de l'étape 2), qui permettent de tracer les figures directement au bon emplacement dans le DOM (ladiv
du point 1, donc).
Exemples#
Exemple simple#
Concrètement, pour la situation la plus simple où une seule figure doit être affichée dans la page, il suffit d'insérer un appel de macro figure et l'élément comportant le code python (IDE
, terminal
, py_btn
ou run
).
Remarques :
- Dans l'IDE ci-dessous, tous les codes sont groupés dans la section
code
, mais il est possible de mettre une partie de la logistique dans la sectionenv
, afin que l'utilisateur ne voit pas ce qui concerne les objetsPyodidePlot
. - L'installation de
matplotlib
peut être très longue...
{{ IDE('exemples/plot_1') }}
{{ figure() }}
Permet d'obtenir :
Votre figure
Plusieurs figures#
Pour tracer plusieurs figures dans la même page, il faut utiliser des id
html différents pour les deux figures, et il faut ensuite cibler chaque figure avant d'y démarrer les tracés :
{{ IDE('exemples/plot_2') }}
!!! help ""
{{ figure('cible_1') }}
{{ figure('cible_2') }}
Permet d'obtenir :
# Tests
(insensible à la casse)(Ctrl+I)
(Alt+: ; Ctrl pour inverser les colonnes)
(Esc)
Votre figure
Votre figure
La classe PyodidePlot
#
Disponibilité de la classe PyodidePlot
La classe PyodidePlot
n'est déclarée dans l'environnement pyodide qu'après que matplotlib
ait été installé.
Cela signifie que la classe ne peut être utilisée dans une section que si matplotlib
y est également importé, ou s'il a déjà été importé précédemment.
L'utilisation des objets PyodidePlot a été simplifiée
Les objets de la classe PyodidePlot permettent en fait de faire plus que simplement pointer vers la bonne balise/figure, mais ces fonctionnalités se sont révélées trop spécifiques et la méthode target
permet normalement de couvrir tous les besoins en restant au plus proche d'une utilisation normale de matplotlib
dans l'environnement du thème.
Les informations ci-dessous sont donc fournies à fins de complétude et restent d'actualité, même si elles ne sont à priori plus nécessaires.
Généralités#
Cette classe est déclarée automatiquement au premier import de matplotlib
dans pyodide.
- Son constructeur prend un seul argument, optionnel, qui est l'identifiant html (
id
) de la balisediv
qui devra accueillir la figure. - Si cet argument n'est pas fourni, c'est la valeur par défaut pour l'argument
div_id
de la macrofigure
qui est utilisé. - Ceci est compatible avec la configuration via les fichiers
.meta.pmt.yml
et les entêtes des fichiers markdown.
L'objet PyodidePlot
ainsi créé peut ensuite être utilisé en remplacement de matplotlib.pyplot
: il relaie automatiquement tous les appels de méthodes à la fonction correspondant du module pyplot
. Deux exceptions à cela :
-
La méthode
PyodidePlot.plot
met en place le tracé de la figure dans ladiv
voulue, avant de relayer l'appel àpyplot.plot
. Il faut donc ne surtout pas utiliserpyplot.plot
-
La méthode
PyodidePlot.plot_func
n'existe pas dans le modulepyplot
. C'est un ajout du thème, qui permet d'obtenir en un seul appel le tracé d'une fonction sur un domaine donné, en prenant en charge la construction des ordonnées, le titre éventuel de la figure et l'appel final àpyplot.show()
.
Accéder au code de la classe
Il est possible d'utiliser l'un des scripts du thème pour voir le code complet de la classe :
python -m pyodide_mkdocs_theme --plot
La classe utilisée dans le thème est rigoureusement identique à celle présente dans ce fichier.
Certaines instructions au tout début du fichier ne correspondent par contre pas au code utilisé dans le thème, car le but de ce fichier est de pouvoir exécuter les fichiers pythons de la documentation utilisant matplotlib
en local (voir l'admonition suivante).
Exécution locale de fichier python utilisant la classe PyodidePlot
Si vous souhaitez exécuter des fichiers python utilisant matplotlib
en local, il faut "ruser" un peu, mais le thème fournit les outils nécessaires :
-
Installer
matplotlib
sur la machine/dans l'environnement, si ce n'est pas déjà fait.Ne pas ajouter
matplotlib
au fichierrequirements.txt
La bibliothèque
matplotlib
est ici une dépendance de développement, et non une dépendance de la documentation. -
Utiliser la commande ci-dessous, pour récupérer le fichier
pyodide_plot.py
du thème et le placer à la racine du projet :python -m pyodide_mkdocs_theme --plot -F pyodide_plot.py
-
Ajouter ceci au tout début du fichier python de la documentation que vous voulez exécuter en local :
# --- PYODIDE:ignore --- # from pyodide_plot import PyodidePlot
Ce code ne sera exécuté qu'en local, les sections
ignore
des fichiers n'étant pas récupérées pour le site construit avec mkdocs.
Documentation complète de la classe PyodidePlot
PyodidePlot(div_id: str = '')
#
Helper class, to draw figures from pyodide runtime, into a specified html element.
If no argument is provided, the default div_id
is used (arguments configuration of
the plugin).
import matplotlib.pyplot as plt
PyodidePlot().target()
plt.plot(xs, ys, ...)
plt.title("...")
plt.show()
In case you want to target more than one figure in the same page, pass the html id of the
div tag to target to the PyodidePlot
constructor:
fig1 = PyodidePlot("figure_id1")
fig2 = PyodidePlot("figure_id2")
fig1.target() # Draw in "figure_id1"
plt.plot(...)
fig2.target() # Draw in "figure_id2"
plt.plot(...)
target(keep_fig=False)
#
Close any previously created figure, then setup the current run to draw in
the div tag targeted by the current instance.
If keep_fig is set to True, the automatic Figure N
will be kept, above the
drawn figure.
plot_func(func: Callable, rng: Sequence, fmt: str = None, title: str = None, *, show: bool = True, keep_figure_num: bool = False, **kw)
#
Draw an automatic graph for the given function on the given range, then "show" automatically the resulting graph in the correct figure element in the page.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
func |
Callable
|
Callable, func(x) -> y |
required |
rng |
Sequence
|
Sequence of xs |
required |
fmt |
str
|
Curve formatting (just like |
None
|
title |
str
|
If given, will be added as title of the graph. |
None
|
show |
bool
|
Call |
True
|
keep_figure_num |
bool
|
if False (by default), the |
False
|
plot(*args, keep_figure_num: bool = False, **kw)
#
Generic interface, strictly equivalent to pyplot.plot
, except the PyodidePlot
instance will automatically apply the drawing to the desired html element it is
related to.
Use specifically this method to "plot" ! You then can rely on pyplot
to finalize
the figure as you prefer.
# Tests
(insensible à la casse)(Ctrl+I)
(Alt+: ; Ctrl pour inverser les colonnes)
(Esc)