... | @@ -101,34 +101,48 @@ plt.title("test 3 : cmap discrète à partir de 'rainbow'") |
... | @@ -101,34 +101,48 @@ plt.title("test 3 : cmap discrète à partir de 'rainbow'") |
|
plt.show()
|
|
plt.show()
|
|
```
|
|
```
|
|
|
|
|
|
|
|
La [doc nous indique un moyen plus simple d'obtenir une légende quand il y a un nombre raisonnable de valeurs différentes](https://matplotlib.org/stable/gallery/lines_bars_and_markers/scatter_with_legend.html)
|
|
|
|
|
|
|
|
```python
|
|
|
|
# méthode quand c est un vecteur de valeurs, et que scatter se débrouille pour utiliser une cmap par défaut
|
|
|
|
points = plt.scatter(dates, liste_mois, c=liste_mois, cmap=cmap, norm=norm, s=[4 * (date.year - 1990) for date in dates], edgecolor='none')
|
|
|
|
legend1 = ax.legend(*points.legend_elements(), loc="lower left", title="Classes")
|
|
|
|
ax.add_artist(legend1)
|
|
|
|
|
|
### ajouter une colorbar discrète définie par un dictionnaire
|
|
### ajouter une colorbar discrète définie par un dictionnaire
|
|
|
|
|
|
On suppose ici que l'on va choisir a priori une correspondance entre valeurs et couleurs. Attention, ce n'est pas forcément une "bonne pratique" pour représenter des valeurs continues, mais cela peut se défendre si on a des catégories qui peuvent être liées à des couleurs. Ici on décide que l'hiver c'est gris, le printemps vert, l'été orange et l'automne bleu. Ca reste subjectif. On va donc d'abord créer un dictionnaire, en fait on reprend celui de l'atelier C, puis on transforme les valeurs en liste de couleurs. Ensuite, il faudra préciser dans la variable "bounds" que les "fourchettes" de valeurs sont centrées sur les entiers. En fait, le problème des limites est toujours de savoir laquelle est "incluse" et laquelle est "exclue". Avec des entiers, on peut se permettre de définir les limites entre les valeurs entières pour lever les ambiguités. Mais vous pouvez jouer avec les valeurs pour voir...
|
|
On suppose ici que l'on va choisir a priori une correspondance entre valeurs et couleurs. Attention, ce n'est pas forcément une "bonne pratique" pour représenter des valeurs continues, mais cela peut se défendre si on a des catégories qui peuvent être liées à des couleurs. Ici on décide que l'hiver c'est gris, le printemps vert, l'été orange et l'automne bleu. Ca reste subjectif. On va donc d'abord créer un dictionnaire, en fait on reprend celui de l'atelier C, puis on transforme les valeurs en liste de couleurs. Ensuite, il faudra préciser dans la variable "bounds" que les "fourchettes" de valeurs sont centrées sur les entiers. En fait, le problème des limites est toujours de savoir laquelle est "incluse" et laquelle est "exclue". Avec des entiers, on peut se permettre de définir les limites entre les valeurs entières pour lever les ambiguités. Mais vous pouvez jouer avec les valeurs pour voir...
|
|
| Colormap continue discrétisée | ListedColorMap : colormap discrète définie par une liste |
|
|
| Légende par colorbar | Légende construite à partir des classes de valeurs|
|
|
|-------------------------------|----------------------------------------------------------|
|
|
|-------------------------------|----------------------------------------------------------|
|
|
|  |  |
|
|
|  |
|
|
| on a défini les limites de classes avec BoundaryNorm | on a en plus customisé la colorbar pour comprendre |
|
|
```
|
|
|
|
|  |
|
|
|
|
| Colorbar basée sur la colormap continue discrétisée avec BoundaryNorm | méthode legend, arguments \*points.legend_elements() |
|
|
|
|
|
|
```python
|
|
\`\`\`python
|
|
DICO_COULEURS_MOIS = {1: "dimgrey", 2: "black", 3: "palegreen", 4: 'mediumspringgreen', 5: 'forestgreen', 6: 'gold', 7: 'orange', 8:'orangered', 9:'deepskyblue', 10:'royalblue', 11:'navy', 12:'silver'}
|
|
DICO_COULEURS_MOIS = {1: "dimgrey", 2: "black", 3: "palegreen", 4: 'mediumspringgreen', 5: 'forestgreen', 6: 'gold', 7: 'orange', 8:'orangered', 9:'deepskyblue', 10:'royalblue', 11:'navy', 12:'silver'}
|
|
|
|
|
|
# on place les valeurs du dictionnaire dans une liste de couleurs
|
|
\# on place les valeurs du dictionnaire dans une liste de couleurs
|
|
cmap = colors.ListedColormap(list(DICO_COULEURS_MOIS.values()))
|
|
cmap = colors.ListedColormap(list(DICO_COULEURS_MOIS.values()))
|
|
# on définit les limites de classe ; ici pour être sûr du résultat on place les limites entre les entiers et en plus ça permettra de bien tracer l'échelle ;
|
|
\# on définit les limites de classe ; ici pour être sûr du résultat on place les limites entre les entiers et en plus ça permettra de bien tracer l'échelle ;
|
|
# avec np.arange on crée un vecteur de 0.5 inclus à 13 exclu par pas de 1:
|
|
\# avec np.arange on crée un vecteur de 0.5 inclus à 13 exclu par pas de 1:
|
|
bounds =np.arange(0.5,13,1)
|
|
bounds =np.arange(0.5,13,1)
|
|
norm = colors.BoundaryNorm(bounds, cmap.N) # cmap.N = nb de couleurs de cmap
|
|
norm = colors.BoundaryNorm(bounds, cmap.N) # cmap.N = nb de couleurs de cmap
|
|
plt.scatter(dates, liste_mois, c=liste_mois, cmap=cmap, norm=norm, s=[4 * (date.year - 1990) for date in dates], edgecolor='none')
|
|
plt.scatter(dates, liste_mois, c=liste_mois, cmap=cmap, norm=norm, s=\[4 \* (date.year - 1990) for date in dates\], edgecolor='none')
|
|
|
|
|
|
# on place les ticks de 1 à 12 (13 exclus) ; les limites de classe sont issues de bounds
|
|
\# on place les ticks de 1 à 12 (13 exclus) ; les limites de classe sont issues de bounds
|
|
cbar = plt.colorbar(ticks=range(1,13), label="code couleur des mois")
|
|
cbar = plt.colorbar(ticks=range(1,13), label="code couleur des mois")
|
|
|
|
|
|
# facultatif : autre moyen d'écrire une légende customisée, en définissant la localisation du texte (= les 5 premières lettres de la couleur)
|
|
\# facultatif : autre moyen d'écrire une légende customisée, en définissant la localisation du texte (= les 5 premières lettres de la couleur)
|
|
for mois in range(1,13):
|
|
for mois in range(1,13):
|
|
cbar.ax.text(1.5, mois, f"{DICO_COULEURS_MOIS[mois][0:5]}", ha='center', va='center')
|
|
cbar.ax.text(1.5, mois, f"{DICO_COULEURS_MOIS\[mois\]\[0:5\]}", ha='center', va='center')
|
|
plt.title("test 4")
|
|
plt.title("test 4")
|
|
plt.show()
|
|
plt.show() |
|
|
```
|
|
|
|
|
|
| ListedColorMap : colormap discrète définie par une liste | header |
|
|
|
|
|----------------------------------------------------------|--------|
|
|
|
|
|  | |
|
|
|
|
| on a en plus customisé la colorbar pour comprendre | cell |
|
|
|
|
|
|
### définir la liste de couleurs item par item, légende customisée (cf Atelier C)
|
|
### définir la liste de couleurs item par item, légende customisée (cf Atelier C)
|
|
|
|
|
... | @@ -136,7 +150,15 @@ Variante : au lieu d'utiliser une colorbar, on peut aussi écrire une fonction p |
... | @@ -136,7 +150,15 @@ Variante : au lieu d'utiliser une colorbar, on peut aussi écrire une fonction p |
|
|
|
|
|

|
|

|
|
|
|
|
|
Si vous voulez détailler votre code couleur. vous avez la possibilité de tracer la légende des couleurs (colorbar, utilisée ci-dessus) ou de tracer une légende "customisée".
|
|
Comme on ne passe pas par de "colormap" avec cette méthode, il faut trouver une autre manière d'obtenir une légende des couleurs. La légende "standard" ne donne qu'un exemplaire du symbole, donc n'est pas très utile. La méthode indiquée dans la doc ne semble marcher que quand on passe à l'argument **c** un vecteur de valeurs, et que scatter se débrouille pour utiliser une cmap par défaut
|
|
|
|
|
|
|
|
```python
|
|
|
|
# méthode quand c est un vecteur de valeurs, et que scatter se débrouille pour utiliser une cmap par défaut
|
|
|
|
legend1 = ax.legend(*points.legend_elements(), loc="lower left", title="Classes")
|
|
|
|
ax.add_artist(legend1)
|
|
|
|
```
|
|
|
|
|
|
|
|
Dans notre cas, on va donc tracer une légende "customisée".
|
|
|
|
|
|
```python
|
|
```python
|
|
from matplotlib.lines import Line2D
|
|
from matplotlib.lines import Line2D
|
... | | ... | |