Comment choisir les couleurs d’un graphique {ggplot2} ?

twitch
ggplot2
Rnewbies
graphique
Author

Marie Vaugoyeau

Published

19 May 2026

Note

Twitch du 19 mai 2026.

Le code est disponible sur GitHub au format pdf ou .qmd

La dataviz et la couleur

Avant de commencer

Si tu as déjà réalisé un graphique, quelque soit l’outil, tu as dû être confronté.e à ce choix : faut-il conserver les couleurs par défaut ?
En effet dans la plus part des outils, y compris le package {ggplot2}, proposent des palettes de couleurs par défaut.

Si cela facilite la réalisation de graphiques, il ne faut pas oublier que le choix des couleurs influence profondément la compréhension et l’interprétation des données.

Il faut donc bien comprendre que la couleur peut orienter la lecture graphique.
Lors du live sur Twitch j’ai montré quelques exemples, en voici d’autres tirés de ma présentation aux rencontres R 2026 de Nantes 😊

La couleur valorise les graphiques

Sur le graphique interactif ci-dessous, la couleur permet de voir facilement que plus les années passent plus la température globale augmente.

En effet, la couleur bleue associée aux températures plus basses est remplacée progressivement par une couleur rouge pour les températures les plus hautes.

Sauf quand elle perturbe le message

L’utilisation d’un cadre autour des graphiques rapellant une des couleurs utilisées conduit l’œil a percevoir les barres associées plus grandes qu’elles ne le sont !

La dataviz pour donner du sens aux données et communiquer un message – février 2024 par Éric MAUVIÈRE, icem7

Sauf quand les conventions brouillent la compréhension

NoteGauche ou droite ?

J’avoue que j’ai mis des années à comprendre que les républicains aux Etats-Unis étaient de droite et non de gauche 😬

Contrairement au reste du monde, le partie de gauche étasunien est représenté par la couleur bleue et le partie de droite en rouge

Sauf quand elle n’informe pas

Ici tu retrouve l’original et le résultat de l’impression d’un graphique de mon livre…

TipNouvelle version

J’ai le plaisir de t’annoncer que je travaille sur une nouvelle version qui n’aura plus ces erreurs et qui en plus présentera Quarto 🥰

Les questions à se poser

La principale

Et oui, tu l’auras compris, la première question à se poser est de savoir si réellement notre graphique a besoin de couleur 🙂

TipSi tu mets de la couleur

La couleur ne doit pas être la seule façon de passer une information

5 questions essentielles à se poser

  • Quel est le support de sortie ?

    • Si le graphique est imprimé, projeté sur un écran ou visible sur un smartphone, cela change tout
    • L’impression est-elle sur papier glacé, en noir et blanc ou en niveau de gris…
  • Suis-je limité.e dans les couleurs à utiliser ?

    • Si ton entreprise te limite dans le choix d’une couleur, tu peux utiliser le package {monochromeR} pour trouver des couleurs proches mais plus ou moins attenuées, mélangées à une autre couleur….
    • Limites toi à 8 couleurs max 🎨
  • Les couleurs sont-elles distinctes (pour les personnes daltoniennes mais aussi pour les autres) ?

  • Les teintes sont-elles cohérentes avec l’information ?

    • Fais particulièrement attention au couple rouge-bleu
    • Soit attentif au sens derrière en fonction du public
  • L’intensité des couleurs sont-elles équilibrées entre elles ?

    • Lorsque qu’une variable augmente, par convention, les plus petites valeurs sont en plus clairs
    • L’intensité se compare facilement en utilisant le code hsl de la couleur

Utiliser de la couleur dans un graphique

Exemple réalisé en live

library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.2.0     ✔ readr     2.1.6
✔ forcats   1.0.1     ✔ stringr   1.6.0
✔ ggplot2   4.0.2     ✔ tibble    3.3.1
✔ lubridate 1.9.5     ✔ tidyr     1.3.2
✔ purrr     1.2.1     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
penguins |> 
  ggplot() +
  aes(
    x = flipper_len,
    y = body_mass
  ) +
  geom_point() +
  theme_classic() +
  labs(
    title = "Condition corporelle des pingouins",
    x = "taille de la nageoire (mm)",
    y = "masse (g)"
  )
Warning: Removed 2 rows containing missing values or values outside the scale range
(`geom_point()`).

Pour pouvoir différencier les espèces il faut utiliser un paramètre graphique comme la forme des points ou la couleur.

library(tidyverse)

penguins |> 
  ggplot() +
  aes(
    x = flipper_len,
    y = body_mass,
    shape = species
  ) +
  geom_point() +
  theme_classic() +
  labs(
    title = "Condition corporelle des pingouins",
    x = "taille de la nageoire (mm)",
    y = "masse (g)"
  )
Warning: Removed 2 rows containing missing values or values outside the scale range
(`geom_point()`).

Le problème c’est que la distinction ne se fait pas bien.
La couleur est un des critères qui permet une distinction facile.

Ajout de la couleur automatiquement

library(tidyverse)

penguins |> 
  ggplot() +
  aes(
    x = flipper_len,
    y = body_mass,
    shape = species,
    color = species
  ) +
  geom_point() +
  theme_classic() +
  labs(
    title = "Condition corporelle des pingouins",
    x = "taille de la nageoire (mm)",
    y = "masse (g)"
  )
Warning: Removed 2 rows containing missing values or values outside the scale range
(`geom_point()`).

Lorsqu’une couleur est affectée automatiquement, elle n’est pas gardé entre les graphiques, par exemple entre @fig_couleur et @fig_couleur_varie.

library(tidyverse)

penguins |> 
  filter(species != "Adelie") |> 
  ggplot() +
  aes(
    x = flipper_len,
    y = body_mass,
    shape = species,
    color = species
  ) +
  geom_point() +
  theme_classic() +
  labs(
    title = "Condition corporelle des pingouins",
    x = "taille de la nageoire (mm)",
    y = "masse (g)"
  )
Warning: Removed 1 row containing missing values or values outside the scale range
(`geom_point()`).

Il est donc préférable de définir une palette par modalité.

library(tidyverse)

vecteur_couleur <- c(
  "Adelie" = "blue",
  "Chinstrapp" = "red",
  "Gentoo" = "green"
)

penguins |> 
  filter(species != "Adelie") |> 
  ggplot() +
  aes(
    x = flipper_len,
    y = body_mass,
    shape = species,
    color = species
  ) +
  geom_point() +
  scale_color_manual(values = vecteur_couleur) +
  theme_classic() +
  labs(
    title = "Condition corporelle des pingouins",
    x = "taille de la nageoire (mm)",
    y = "masse (g)"
  )
Warning: Removed 1 row containing missing values or values outside the scale range
(`geom_point()`).

La moindre erreur de frappe fait disparaitre la modalité en la transformant en gris, la couleur des valeurs manquantes par défaut.

library(tidyverse)

vecteur_couleur <- c(
  "Adelie" = "blue",
  "Chinstrap" = "red",
  "Gentoo" = "green"
)

penguins |> 
  filter(species != "Adelie") |> 
  ggplot() +
  aes(
    x = flipper_len,
    y = body_mass,
    shape = species,
    color = species
  ) +
  geom_point() +
  scale_color_manual(values = vecteur_couleur) +
  theme_classic() +
  labs(
    title = "Condition corporelle des pingouins",
    x = "taille de la nageoire (mm)",
    y = "masse (g)"
  )
Warning: Removed 1 row containing missing values or values outside the scale range
(`geom_point()`).

Pour vérifier la compatibilité d’une palette au près des personnes daltonniennes tu peux utiliser le package {colorblindcheck}

library(tidyverse)

vecteur_couleur <- c(
  "Adelie" = "blue",
  "Chinstrap" = "red",
  "Gentoo" = "green"
)

colorblindcheck::palette_plot(vecteur_couleur)

penguins |> 
  # filter(species != "Adelie") |> 
  ggplot() +
  aes(
    x = flipper_len,
    y = body_mass,
    shape = species,
    color = species
  ) +
  geom_point() +
  scale_color_manual(values = vecteur_couleur) +
  theme_classic() +
  labs(
    title = "Condition corporelle des pingouins",
    x = "taille de la nageoire (mm)",
    y = "masse (g)"
  )
Warning: Removed 2 rows containing missing values or values outside the scale range
(`geom_point()`).

Pour finir

Et voilà, n’hésites pas à me faire des retours sur contact@marievaugoyeau.fr ou LinkedIn ✍️

Note

Tu peux aussi t’inscrire à la newsletter pour être au courant du prochain live 📺

Bonne journée 😊

Back to top