Que faudrait-il pour intégrer une figure Matplotlib en direct dans un message ?

Je sais que cela sort du cadre de la plupart des communautés, mais nous sommes une communauté scientifique, utilisant Python et beaucoup de graphiques (Matplotlib) que nous partageons entre nous sur Discourse.

Ce serait incroyable de pouvoir partager un graphique interactif au lieu d’un jpg/png statique.

Considérez cet exemple :

import matplotlib.pyplot as plt
import mpld3
import numpy as np

Fs = 4000
f = 100
sample = 200
x = np.arange(sample)
y = np.sin(2 * np.pi * f * x / Fs)
fig, ax = plt.subplots(1,1)
ax.plot(x, y, marker=".")
html_str = mpld3.fig_to_html(fig)
Html_file= open("index.html","w")
Html_file.write(html_str)
Html_file.close()

Vous pourriez ouvrir le fichier index.html et il montrerait cela (sauf que ce serait INTERACTIF…)

Donc, j’ai l’impression que nous sommes à mi-chemin, n’est-ce pas ?
Peut-être simplement télécharger le fichier html pour qu’il s’exécute dans un iframe ?

La méthode que vous avez décrite serait possible via un plugin personnalisé, combinant à la fois un plugin de style markdown-it et potentiellement un bon stockage d’objets pour les HTML. Cependant, je serais prudent quant à sa sécurité, car laisser du code entré par l’utilisateur s’exécuter n’importe où sur le serveur. Discourse fait déjà beaucoup de travail juste pour assainir un message pour que le HTML et le JS soient analysés en toute sécurité dans le backend.

Vous auriez peut-être plus de succès en essayant d’intégrer un interpréteur Python dans le navigateur et en le laissant exécuter le code côté client, en évitant toute la création de HTML. JupyterLite vous permettrait d’exécuter JupyterLab dans le navigateur avec une interface utilisateur. D’après la documentation, il semble que vous puissiez exécuter automatiquement du code lors de la création de l’iframe. Vous pouvez fournir le code avec un plugin HighlightJS personnalisé qui créera un bouton actionnable sur n’importe quel bloc de code Python, ou le faire exécuter automatiquement.

Donc, quelque chose comme ceci :

  1. L’utilisateur voit un message avec un bloc de code Python.
  2. L’utilisateur survole le bloc de code, où un bouton apparaît pour lui permettre d’exécuter le code dans le navigateur.
  3. L’utilisateur clique sur le bouton, ce qui crée une iframe vers JupyterLite sous le code, important le code du bloc de code.

Comme il ne s’agirait que d’un plugin HighlightJS qui crée simplement une iframe vers JupyterLite, vous pouvez tout créer dans un composant de thème, sans code serveur nécessaire.

Une chose à noter : JupyterLite est décrit comme n’étant pas complet par rapport à JupyterLab, et je ne suis pas sûr de la façon dont il gère les importations de paquets, vous pourriez donc devoir l’héberger vous-même. JupyterLite utilise Pyodide, qui prend en charge n’importe quelle roue sur PyPI, donc cela devrait aller.

3 « J'aime »

Je pense que le risque de sécurité n’est pas très grand si index.html s’exécute côté client (dans le navigateur de l’utilisateur, pas sur le serveur Discourse).

De plus, l’avantage de l’approche mpld3 est qu’il s’agit d’un fichier unique sans dépendances. Si vous exécutez du Python brut, vous devez également pouvoir télécharger toutes les dépendances telles que les fichiers CSV, les fichiers de données, etc., qui sont la source de ce que vous voulez tracer.

Cela dit, pouvoir exécuter des scripts Python bruts dans un message Discourse serait tout simplement fabuleux !

2 « J'aime »

Oh ! J’ai complètement mal compris comment le HTML serait généré. Si l’utilisateur pré-génère le HTML, vous pourriez lui faire faire un iframe à partir d’un site externe, avec le domaine dans la liste blanche.

Par exemple, codepen, qui devrait être autorisé par défaut :

<iframe height="300" width="800" style="width: 100%;" scrolling="no" title="mplD3 example, actually working" src="https://codepen.io/gully/embed/BawMGr?default-tab=result" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
  See the Pen <a href="https://codepen.io/gully/pen/BawMGr">
  mplD3 example, actually working</a> by gully (<a href="https://codepen.io/gully">@gully</a>)
  on <a href="https://codepen.io">CodePen</a>.
</iframe>
<iframe height="300" width="800" style="width: 100%;" scrolling="no" title="mplD3 example, actually working" src="https://codepen.io/gully/embed/BawMGr?default-tab=result" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
  See the Pen <a href="https://codepen.io/gully/pen/BawMGr">
  mplD3 example, actually working</a> by gully (<a href="https://codepen.io/gully">@gully</a>)
  on <a href="https://codepen.io">CodePen</a>.
</iframe>
3 « J'aime »

Cela peut absolument être fait :

Si vous avez beaucoup d’utilisateurs, vous pourriez avoir besoin d’aide pour automatiser une partie de la configuration.

Je peux vous aider si vous avez un budget.

5 « J'aime »

C’est vraiment génial !
J’ai quelques questions :

  1. Pensez-vous que cela fonctionnera avec ipympl (sinon les figures ne sont pas interactives, ce qui invalide tout l’intérêt) ?
  2. Pensez-vous que cela peut fonctionner avec un dossier de projet sous-jacent où nous pouvons définir la variable d’environnement PYTHONPATH avant de lancer Jupyter afin que les utilisateurs puissent importer des fonctions et des dépendances du projet commun ?

Et oui, j’ai un budget si cela est raisonnable et réalisable et peut être contribué en open source pour toute la communauté Discourse.

2 « J'aime »

Très probablement

Je vois une façon de créer un environnement collaboratif.

N’hésitez pas à m’envoyer un message privé, nous pourrons en discuter lors d’un appel.

2 « J'aime »

@Alteras Merci, cette solution est très simple et fonctionne si vous trouvez un moyen de téléverser le fichier « index.heml » sur Discourse (ce qui permet d’activer facilement le téléversement de .html) et de le servir dans le code de l’iframe. Le seul problème est que cela ne fonctionne pas réellement… lorsque j’essaie cela, il télécharge simplement index.html au lieu de le rendre dans l’iframe. Peut-être y a-t-il une balise meta pour dire à l’iframe d’afficher le fichier au lieu de le télécharger ?

Ahh, je vois. Discourse, par défaut, définit toutes les pièces jointes non-image avec la disposition du contenu comme « pièce jointe », ce qui les traite uniquement comme un téléchargement.

Vous pourriez être en mesure de faire quelque chose de similaire aux aperçus PDF en ligne, qui semble gérer ce même problème, mais pour les téléchargements de PDF.

1 « J'aime »

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.