Visualisation de données en Flask§

1

Avec Matplotlib§

2

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)
../_images/rappel_matplotlib.png
3

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...

4

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'
5

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
6

Initiation à SVG§

7

Qu'est-ce que SVG ?§

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é.

8

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>
9

La balise svg§

10

La balise circle§

Important

En SVG, les balises sans contenue doivent être explicitement fermée, en les terminant par />.

11

La balise rect§

12

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>
13

La balise line§

14

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>
15

Attributs CSS pour SVG§

Cette liste n'est pas exhaustive.

Ces attributs peuvent être spécifiés

16

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>
17

CSS et interactivité§

CSS permet de plus d'ajouter un peu d'interactivité, notamment avec la pseudo-classe CSS :hover (documentation).

18

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>
19

Autres balises SVG§

20

Pour en savoir plus§

21

Visualisation de données en SVG§

22

SVG et matplotlib§

23

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).

24

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>
A B C
25