Visualisation de données en Flask¶§
Avec Matplotlib¶§
Rappel sur Matplotlib¶§
from matplotlib.figure import Figure
bins = ["A", "B", "C", "D", "E", "F"]
values = [3, 5, 8, 4, 2, 1]
cumul = [3, 8, 16, 20, 22, 23]
fig = Figure()
ax1, ax2 = fig.subplots(2, 1)
fig.suptitle("Répartition par appréciation")
ax1.bar(bins, values)
ax2.bar(bins, cumul)
Sauvegarder dans un fichier¶§
fig.savefig("/tmp/test.png", format="png")
ou
with open("/tmp/test.png", 'wb') as f:
fig.savefig(f, format="png")
Formats supportés : png
(défaut), pdf
, svg
...
BytesIO¶§
La classe io.BytesIO
permet de créer un fichier virtuel,
dont le contenu est stocké en mémoire,
et accessible à l’aide de la méthode getvalue
.
from io import BytesIO
b = BytesIO()
b.write(b"hello")
b.write(b" world")
print(b.getvalue())
# affiche b'hello world'
Générer un graphique dans Flask¶§
@app.route("/foo/<bar>/baz.png")
def example_matplotlib(bar):
data = make_data_from(bar) # requête SQL ou autre...
fig = Figure()
# ... création du graphique à partir de data ...
b = BytesIO()
fig.savefig(b, format="png")
resp = make_response(b.getvalue())
resp.headers['content-type'] = 'image/png'
return resp
Initiation à SVG¶§
Qu’est-ce que SVG ?¶§
- SVG signifie Scalable Vector Graphics.
- C’est un langage à balise, similaire à HTML, pour décrire des objets graphiques.
- Il peut être utlisé à l’intérieur d’un document HTML.
Indice
Contrairement aux images raster comme PNG, qui sont discrétisées en pixels, les images vectorielles décrivent des formes mathématiques, qui peuvent donc être redimensionnées à volonté, sans perte de qualité.
Exemple¶§
<svg viewBox="-50 -50 100 100">
<circle cx="0" cy="0" r="40" style="fill:red" />
<rect x="-27.5" y="-7.5" width="55" height="15"
style="fill:white" />
</svg>
La balise svg
¶§
Elle contient tous les autres éléments SVG.
L’attribut
viewBox
définit la zone affichable :- x minimum (bord gauche)
- y minimum (bord haut)
- largeur
- hauteur
La taille réelle est fixée
- soit par CSS,
- soit par des attributs
«idth
etheight
directement dans la balisesvg
.
La balise circle
¶§
Elle décrit un cercle.
Elle utilise les attributs suivants :
cx
: abscisse du centrecy
: ordonnée du centrer
: rayon
Important
En SVG, les balises sans contenue doivent être explicitement fermée,
en les terminant par />
.
La balise rect
¶§
Elle décrit un rectangle.
Elle utilise les attributs suivants :
x
: abscisse du coin supérieur gauchey
: ordonnée du coin supérieur gauchewidth
: largeurheight
: hauteur
Attributs optionnels:
rx
: rayon horizontal des coinsry
: rayon vertical des coins (si différent derx
)
Exemples de rect
¶§
<svg viewBox="0 0 100 100">
<rect x="10" y="10" width="80" height="40" rx="10"
style="fill:teal"/>
<rect x="10" y="55" width="80" height="40" rx="20" ry="10"
style="fill:orange"/>
</svg>
La balise line
¶§
Elle décrit une ligne.
Elle utilise les attributs suivants :
x1
: abscisse du premier pointy1
: ordonnée du premier pointx2
: abscisse du second pointy2
: ordonnée du second point
Exemples de rect
¶§
<svg viewBox="0 0 100 100">
<line x1="10" y1="10" x2="50" y2="10" style="stroke:black"/>
<line x1="10" y1="20" x2="60" y2="30" style="stroke:black"/>
<line x1="10" y1="30" x2="80" y2="50" style="stroke:black"/>
</svg>
Attributs CSS pour SVG¶§
stroke
: couleur du trait/contourfill
: couleur de remplissagestroke-width
: largeur du traitstroke-dasharray
: largeurs des pointillés
Cette liste n’est pas exhaustive.
Ces attributs peuvent être spécifiés
- directement dans l’attribut
style
, ou - via une feuille de style,
- y compris via une classe.
Exemple CSS¶§
circle { stroke-width: 5 }
.foo { stroke: blue; fill: red }
.bar { stroke: green; fill: yellow }
<svg viewBow="0 0 200 100">
<circle cx="50" cy="50" r="45" class="foo" />
<circle cx="150" cy="50" r="45" class="bar" />
</svg>
CSS et interactivit鶧
CSS permet de plus d’ajouter un peu d’interactivité,
notamment avec la pseudo-classe CSS :hover
(documentation).
Liens en SVG¶§
<svg viewBox="0 0 100 100">
<a href="http://champin.net/">
<rect x="10" y="10" width="80" height="40" rx="10"
style="fill:teal"/></a>
<a href="http://www.univ-lyon1.fr/">
<rect x="10" y="55" width="80" height="40" rx="20" ry="10"
style="fill:orange"/></a>
</svg>
Visualisation de données en SVG¶§
SVG et matplotlib
¶§
matplotlib
permet de générer facilement des graphiques complexes.- Il génère du SVG “auto-suffisant” qu’on peut insérer dans une balise
img
mais pas directement dans le HTML, - ce qui limite les possibilités d’interaction.
SVG et template¶§
Les templates Jinja2 peuvent être utilisés pour générer du SVG.
Il sera cependant nécessaire de leur fournir des données « pré-traitées », dans lesquels les calculs géométriques compliqués ont été fait au préalable en Python.
Note
Les boucles {% for ... %}
peuvent être utilisée autour d’un ensemble de balise,
mais également à l’intérieur d’un attribut
(utile pour polyline
ou path
).
Exemple d’histogramme en SVG¶§
<svg viewBox="-10 -10 130 110">
<polyline points="0,90 0,0 110,0"/>
<path d="M 25,0 V -3 M 50,0 V -3 M 75,0 V -3 M 100,0 V -3"/>
<a href="#A">
<rect x="0" y="5" width="40" height="20"/>
<text x="0" y="5" dx="5" dy="12" text-anchor="middle">A</text></a>
<a href="#B">
<rect x="0" y="35" width="73" height="20" fill="teal"/>
<text x="0" y="35" dx="5" dy="12" text-anchor="middle">B</text></a>
<a href="#C">
<rect x="0" y="65" width="42" height="20" fill="teal"/>
<text x="0" y="65" dx="5" dy="12">C</text></a>
</svg>