====== Faire un graphe polaire en python ======
Nous allons voir commetn faire plusieurs types de graph polaire en python pour, par exemple, afficher des données, faire apparaître des savoirs...
===== Avec matplotlib =====
Matplotlib est une bibliothèque de tracés Python en 2D pour des chiifres donnés. Pour générer des graphiques, des histogrammes, des spectres de puissance, des diagrammes à barres, des diagrammes d'erreurs, des diagrammes de dispersion, etc. avec seulement quelques lignes de code.
Dans cet exemple nous allons travailler sur la conception d'un graphique polaire visant à rendre visible les champs de compétences d'une personne.
Pour cela nous allons utiliser [[https://matplotlib.org/users/pyplot_tutorial.html|matplotlib.pyplot]]
* une collection de fonctions de style commande qui font fonctionner ''matplotlib'' comme ''MATLAB''. Chaque fonction ''pyplot'' apporte des modifications à une figure : par exemple,
* crée une figure,
* crée une zone de traçage dans une figure,
* trace quelques lignes dans une zone de traçage,
* décore la figure avec des étiquettes, etc.
Dans ''matplotlib.pyplot'', différents états sont conservés dans les appels de fonctions, de sorte qu'il garde la trace de choses comme la figure actuelle et la zone de traçage, et les fonctions de traçage sont dirigées vers les axes actuels.
===== Subjectiver les champs d'activités pro ====
Nous utliserons également [[https://www.numpy.org/|numpy]] pour afficher notre rendu graphique dans une image.
==== Installation matplotlib ====
$ sudo apt-get install python3-matplotlib # Debian / Ubuntu
$ sudo dnf install python3-matplotlib # Fedora
$ sudo yum install python3-matplotlib # Red Hat
$ sudo pacman -S python-matplotlib # Arch
==== Afficher un graphique polaire ====
Dans un fichier que nous nommons ''polar_cv.py''
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
A Graphy CV for transdisciplanary human being
by XavCC
GNU GENERAL PUBLIC LICENSE Version 3
"""
import numpy as np
import matplotlib.pyplot as plt
field = ['Arts', 'Sciences', 'Hacking', 'Engineering', 'Design']
ecology = [
72, # Arts
78, # Sciences
80, # Hacking
92, # Engineering
92, # Design
72, # Arts
]
digitaltech = [
65, # Arts
60, # Sciences
60, # Hacking
55, # Engineering
65, # Design
65, # Arts
]
teaching = [
55, # Arts
62, # Sciences
70, # Hacking
82, # Engineering
82, # Design
55, # Arts
]
# Initialise the spider plot by setting figure size and polar projection
plt.figure(figsize=(10, 6))
plt.subplot(polar=True)
theta = np.linspace(0, 2 * np.pi, len(ecology))
# Arrange the grid into number of capacties equal parts in degrees
(lines, labels) = plt.thetagrids(range(0, 360, int(360 / len(field))),
field)
# Plot Ecology capacities graph
plt.plot(theta, ecology)
plt.fill(theta, ecology, 'b', alpha=0.1)
# Plot Digital Techn capacities graph
plt.plot(theta, digitaltech)
# Plot Teaching capacities graph
plt.plot(theta, teaching)
# Add legend and title for the plot
plt.legend(labels=('Ecology', 'Digital Tech', 'Teaching'), loc= 4)
plt.title('My Graphy CV for transdisciplanary human being')
plt.show()
Ce qui avec la commande ''$ python3 polar_cv.py'' nous donne
{{ python_cv_1.png }}
==== Verifier le standard du code ====
Installons [[https://pylint.readthedocs.io/en/latest|pylint]]
$ sudo pip3 install pylint
Vérifions la qualité de notre substance nouvellement créée. Traquons les fautes de syntaxe ou de frappe, le style de notre code, en suivant les recommandations de style du langage Python (PEP8). Pour réaliser cela pylint est plus précis et plus verbeux que pep8 ou flake8 ou encore pycodestyle.
ensuite
`--> pylint polar_cv.py
************* Module polar_cv
cv_graphy.py:66:62: C0326: No space allowed after keyword argument assignment
plt.legend(labels=('Ecology', 'Digital Tech', 'Teaching'), loc= 4)
^ (bad-whitespace)
cv_graphy.py:13:0: C0103: Constant name "field" doesn't conform to UPPER_CASE naming style (invalid-name)
cv_graphy.py:14:0: C0103: Constant name "ecology" doesn't conform to UPPER_CASE naming style (invalid-name)
cv_graphy.py:22:0: C0103: Constant name "digitaltech" doesn't conform to UPPER_CASE naming style (invalid-name)
cv_graphy.py:30:0: C0103: Constant name "teaching" doesn't conform to UPPER_CASE naming style (invalid-name)
cv_graphy.py:44:0: C0103: Constant name "theta" doesn't conform to UPPER_CASE naming style (invalid-name)
cv_graphy.py:48:1: C0103: Constant name "lines" doesn't conform to UPPER_CASE naming style (invalid-name)
cv_graphy.py:48:8: C0103: Constant name "labels" doesn't conform to UPPER_CASE naming style (invalid-name)
------------------------------------------------------------------
Your code has been rated at 5.29/10 (previous run: 5.88/10, -0.59)
Nous avons :
* Une erreur ligne 66 qui apparaît, soit un espace non désiré dans la syntaxe ''[...] loc= 4)'' que nous corrigeons tel que ''[...] loc=4)''
* 5 erreur de type ''C0103'', PyLint émet ce message lorsqu’un objet a un nom qui ne correspond pas à la convention d’appellation associée à son type d’objet(( Python Regular expression operations : https://docs.python.org/3/library/re.html et PEP 8 Constants : https://legacy.python.org/dev/peps/pep-0008/#constants))
Pour s'affranchir des problèmes de pylint qui voudrait des majuscules, exécutons la règle en utilisant l’option ''--const-rgx='[a-z\_][a-z0-9\_]{2,30}$' ''
Ce qui nous donne
`--> pylint --const-rgx='[a-z\_][a-z0-9\_]{2,30}$' polar_cv.py
-------------------------------------------------------------------
Your code has been rated at 10.00/10 (previous run: 5.29/10, +4.71)
==== Corrigeons les erreurs graphiques ====
- La legende est placée de manière non optimum pour la lecture
- les mots ''Ingineering'' et ''hacking'' empiètent sur le graphique
=== La légende ===
Dans notre exemple elle est écrite
plt.legend(labels=('Ecology', 'Digital Tech', 'Teaching'), loc=4)
L'emplacement de la légende peut être spécifié par le mot-clé argument ''loc'' (documentation de [[https://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.legend|legend()]] pour plus de détails.)
Le mot-clé ''bbox_to_anchor'' donne un grand degré de contrôle pour le placement manuel des légendes.
__**Parametres: **__
''loc'' : ''int'' or ''string'' or ''pair of floats'', default: ‘upper right’
* The location of the legend. Possible codes are:
^Location String ^Location Code ^
| ''best'' |0 |
| ''upper right'' |1 |
| ''upper left'' |2 |
| ''lower left'' |3 |
| ''lower right'' |4 |
| ''right'' |5 |
| ''center left'' |6 |
| ''center right'' |7 |
| ''lower center'' |8 |
| ''upper center'' |9 |
| ''center'' |10 |
Alternativement, il peut s'agir d'un x, y à 2-tuple donnant x, y du coin inférieur gauche de la légende en coordonnées d'axes (auquel cas ''bbox_to_anchor'' sera ignoré).
Dans le but de fluidifier la lecture (passage du regard en diagonal sur l'interface) et de faire ressortir clairement les informations contenues dans la légénde, nou sprenons l'option de la placer en abs à droite entre ''Arts'' et ''Design'' et légèrement à cheval sur le graphique des données.
Nous remplaçons donc ''loc= 4'' par ''bbox_to_anchor=(0.9, 0.4)''
{{ python-cv_2.png }}
=== Pimp de style ===
''matpotlib'' contient un //package style// qui ajoute le support des "styles" de traçage faciles à changer avec les mêmes paramètres qu'un fichier matplotlibrc (est lu au démarrage pour configurer matplotlib).
Il existe un certain nombre de styles prédéfinis fournis par matplotlib. Pour les obtenir
$ python3
>>> import matplotlib.pyplot as plt
>>> print(plt.style.available)
['seaborn-colorblind', 'seaborn-white', 'seaborn-paper', 'seaborn-deep', 'grayscale', 'seaborn', 'seaborn-dark-palette', 'seaborn-notebook', 'seaborn-ticks', 'seaborn-whitegrid', 'dark_background', 'bmh', 'seaborn-muted', 'seaborn-bright', 'fast', 'Solarize_Light2', 'classic', 'seaborn-poster', 'fivethirtyeight', 'seaborn-dark', 'seaborn-darkgrid', 'seaborn-pastel', 'seaborn-talk', '_classic_test', 'ggplot']
Par exemple, il existe un style prédéfini que l'on peut uitliser en début de module tel que
import numpy as np
import matplotlib.pyplot as plt
# set plot style
plt.style.use('seaborn-notebook')
{{ figure_1-1.png?2000 }}
Avec '''greyscale'''
{{ figure_1-3.png }}
Avec '''seaborn-white'''
{{ figure_1-5.png }}
=== Police de caractères ===
* Pour le titre
plt.title('My Graphy CV for transdisciplanary human being', fontsize=20, family='cmtt10')
* Pour le text concernant les champs d'activité
* https://matplotlib.org/api/_as_gen/matplotlib.pyplot.title.html
* https://matplotlib.org/api/text_api.html#matplotlib.text.Text
* https://matplotlib.org/tutorials/text/text_props.html#sphx-glr-tutorials-text-text-props-py
En utilisant ''[[https://matplotlib.org/2.1.1/api/_as_gen/matplotlib.pyplot.tick_params.html?highlight=tick_params#matplotlib.pyplot.tick_params|tick_params]]'', afin de pouvoir modifier si l'on désir : emplacement, taille, couleur...
Par exemple :
plt.tick_params(direction='out', length=6, width=4, labelcolor='#911C14')
===== Autre représentation ====
I-A. IPython et le mode pylab
▲
IPython est une console interactive Python améliorée qui supporte un grand nombre de fonctionnalités très intéressantes parmi lesquelles les entrées/sorties nommées, l'utilisation directe de commandes shell, un système de débogage amélioré et bien plus encore.
En lançant cette console avec l'argument -pylab (--pylab depuis IPython version 0.12), l'on dispose immédiatement d'une session matplotlib interactive avec de nombreuses fonctionnalités du type Matlab™ / Mathematica™.
I-B. Pylab
▲
Pylab fournit une interface procédurale à la librairie graphique matplotlib orientée objet. Elle est basée sur un modèle très proche de Matlab™. De la sorte, la grande majorité des commandes pylab ont leur équivalent Matlab™ avec des arguments similaires. Les commandes les plus importantes sont expliquées avec des exemples en console interactive.
#!/usr/bin/python
# -*- coding: utf-8 -*-
from pylab import *
ax = axes([0.025, 0.025, 0.95, 0.95], polar=True)
N = 20
theta = np.arange(0.0, 2 * np.pi, 2 * np.pi / N)
radii = 10 * np.random.rand(N)
width = np.pi / 4 * np.random.rand(N)
bars = bar(theta, radii, width=width, bottom=0.0)
for (r, bar) in zip(radii, bars):
bar.set_facecolor(cm.jet(r / 10.))
bar.set_alpha(0.5)
ax.set_xticklabels([])
ax.set_yticklabels([])
show()
{{ figure_1-6.png }}
===== Autres Ressources externes =====
* [[https://matplotlib.org/examples/pylab_examples/polar_demo.html|Polar Demo matplotlib]]
* [[https://stackoverflow.com/questions/16605137/matplotlib-polar-plot-radial-axis-offset|Matplotlib polar plot radial axis offset]]
* [[https://matplotlib.org/gallery/color/color_demo.html[| Demo]]
* [[https://matplotlib.org/api/font_manager_api.html?highlight=font#module-matplotlib.font_manager|font manager]]
* [[https://chris.friedline.net/2015-12-15-rutgers/lessons/python2/06-plotting-with-matplotlib.html|Lesson bases]]