---
title: "Visualiser les données d'enquête : des figures qui montrent quelque chose"
---
```{r}
#| label: setup-analyse
#| include: false
source("R/04-initialiser-analyse.R")
```
::: {.callout-important title="Question de départ"}
Comment construire une figure qui rende immédiatement visible un résultat substantiel, tout en indiquant clairement s'il s'agit de données brutes, d'estimations pondérées ou de prédictions issues d'un modèle ?
:::
## Objectifs d'apprentissage
À la fin de ce chapitre, vous saurez :
- utiliser la grammaire de `ggplot2` sans confondre esthétique et raisonnement analytique ;
- distinguer **figure de diagnostic**, **figure exploratoire** et **figure de résultat** ;
- choisir entre effectifs, proportions, distributions et estimations pondérées ;
- représenter des estimations et leur incertitude sans surcharger le graphique ;
- utiliser petits multiples, ordre des catégories et échelles de manière défendable ;
- harmoniser titres, axes, légendes et couleurs avec `theme_enqueter()` ;
- rendre une figure lisible en noir et blanc et compréhensible sans dépendre uniquement de la couleur ;
- construire une figure qui soutient une interprétation sociologique plutôt qu'une simple démonstration de code.
## Avant `ggplot()`, préciser le statut de la figure
Un graphique n'est pas seulement une façon de « montrer les données ». Il encode une population, un dénominateur, une transformation, une échelle et parfois un modèle. Une distinction simple évite beaucoup d'ambiguïtés.
| Statut | Question principale | Exemples | Ce qu'il faut annoncer |
|---|---|---|---|
| **Diagnostic** | le fichier est-il cohérent ? | valeurs extrêmes, tailles de cellules, données manquantes | données observées, règles de contrôle |
| **Exploratoire** | quelle structure mérite d'être étudiée ? | histogramme, nuage de points, boxplot | données brutes ou pondérées, transformations |
| **Résultat** | quel paramètre ou contraste voulons-nous communiquer ? | proportions pondérées, IC, probabilités prédites | estimand, plan/modèle, incertitude |
La grammaire de `ggplot2` sépare données, esthétiques, géométries, échelles et thème [@wickham2016ggplot2]. Cette modularité est particulièrement utile pour les enquêtes : on peut préparer l'estimation avec `{survey}`, puis demander à `ggplot2` de **communiquer** le résultat sans lui déléguer le calcul du plan d'échantillonnage.
## Diagnostic 1 — regarder les effectifs avant les pourcentages
```{r}
#| label: plot-ch12-diplome-brut
#| fig-alt: "Diagramme en barres des effectifs observés dans les quatre niveaux de diplôme."
ggplot(
enqueter |> filter(!is.na(diplome_4)),
aes(x = diplome_4)
) +
geom_bar(fill = couleurs_enqueter[["secondaire"]], width = .72) +
labs(
x = NULL,
y = "Effectif observé",
title = "Avant l'estimation, vérifier combien d'observations portent chaque catégorie",
subtitle = "Effectifs non pondérés parmi les réponses valides",
caption = "Jeu pédagogique synthétique enqueter."
) +
theme_enqueter() +
theme(axis.text.x = element_text(angle = 15, hjust = 1))
```
Ce graphique ne décrit pas la population cible : il décrit **la quantité d'information réellement observée** dans chaque catégorie. Il est donc particulièrement utile avant un modèle ou une interaction.
## Résultat 2 — mettre brut et pondéré sur la même figure
Plutôt que de montrer deux graphiques séparés, comparons directement les parts brutes et pondérées. Le lecteur voit alors immédiatement si la pondération modifie ou non la composition estimée.
```{r}
#| label: plot-ch12-diplome-brut-pondere
#| fig-alt: "Pour chaque niveau de diplôme, deux points comparent la part brute et la proportion pondérée ; les estimations pondérées sont accompagnées d'intervalles de confiance."
brut_diplome <- enqueter |>
filter(!is.na(diplome_4)) |>
count(diplome_4) |>
mutate(
estimation = n / sum(n),
type = "Part brute",
bas = NA_real_,
haut = NA_real_
)
est_diplome <- survey::svymean(~diplome_4, design, na.rm = TRUE)
ci_diplome <- confint(est_diplome)
pond_diplome <- tibble(
diplome_4 = factor(levels(enqueter$diplome_4), levels = levels(enqueter$diplome_4)),
estimation = as.numeric(coef(est_diplome)),
bas = ci_diplome[, 1],
haut = ci_diplome[, 2],
type = "Estimation pondérée"
)
plot_diplome_compare <- bind_rows(
brut_diplome |> select(diplome_4, estimation, bas, haut, type),
pond_diplome
)
ggplot(plot_diplome_compare, aes(x = estimation, y = diplome_4, colour = type)) +
geom_errorbarh(
data = pond_diplome,
aes(y = diplome_4, xmin = bas, xmax = haut),
height = .10,
colour = couleurs_enqueter[["gris"]],
inherit.aes = FALSE
) +
geom_point(size = 3) +
scale_colour_manual(
values = c(
"Part brute" = couleurs_enqueter[["gris"]],
"Estimation pondérée" = couleurs_enqueter[["principal"]]
)
) +
scale_x_continuous(labels = scales::percent_format(accuracy = 1)) +
labs(
x = "Part",
y = NULL,
colour = NULL,
title = "Brut et pondéré peuvent être proches — mais ils ne répondent pas à la même question",
subtitle = "Les IC concernent uniquement l'estimation pondérée",
caption = "Les effectifs observés ne sont pas remplacés par les poids : les deux informations sont complémentaires."
) +
theme_enqueter()
```
::: {.callout-note title="Un graphique = un niveau de lecture clairement annoncé"}
Le point gris répond à « quelle part des lignes observées appartient à cette catégorie ? ». Le point vert répond à « quelle proportion estimons-nous après prise en compte du plan ? ». Leur proximité éventuelle n'efface pas cette différence conceptuelle.
:::
## Exploration 3 — une distribution quantitative avant son résumé
```{r}
#| label: plot-ch12-age-histogramme
#| fig-alt: "Histogramme de l'âge des répondants entre 18 et 79 ans."
ggplot(enqueter, aes(x = age)) +
geom_histogram(
binwidth = 5,
boundary = 0,
fill = couleurs_enqueter[["principal"]],
colour = "white",
linewidth = .25,
na.rm = TRUE
) +
geom_vline(
xintercept = mean(enqueter$age, na.rm = TRUE),
linetype = "dashed",
colour = couleurs_enqueter[["accent"]],
linewidth = .8
) +
labs(
x = "Âge (ans)",
y = "Effectif",
title = "Une moyenne ne montre pas la forme de la distribution",
subtitle = "Histogramme par classes de cinq ans ; trait = moyenne brute",
caption = "Figure exploratoire sur les données observées."
) +
theme_enqueter()
```
La largeur des classes (`binwidth`) influence ce que l'on perçoit. Il est raisonnable d'en tester plusieurs en exploration. Dans une publication, il faut ensuite conserver un découpage lisible et éviter de donner l'impression qu'un choix arbitraire de classes constitue une propriété naturelle de la population.
## Exploration 4 — comparer des distributions sans les réduire à une moyenne
Le revenu selon le diplôme est un bon exemple : une moyenne par groupe masque la dispersion interne et l'asymétrie.
```{r}
#| label: plot-ch12-revenu-diplome
#| fig-alt: "Quatre boxplots comparent la distribution du revenu mensuel selon le niveau de diplôme."
ggplot(
enqueter |> filter(!is.na(diplome_4)),
aes(x = diplome_4, y = revenu_mensuel)
) +
geom_boxplot(
fill = couleurs_enqueter[["gris_clair"]],
colour = couleurs_enqueter[["principal"]],
outlier.alpha = .25,
na.rm = TRUE
) +
scale_y_continuous(labels = scales::label_number(big.mark = "\u202f")) +
labs(
x = NULL,
y = "Revenu mensuel net (€)",
title = "Le gradient scolaire ne résume pas toute la dispersion des revenus",
subtitle = "Boxplots bruts : médiane, quartiles et dispersion intra-groupe",
caption = "Un point au-delà des moustaches n'est pas automatiquement une erreur de données."
) +
theme_enqueter() +
theme(axis.text.x = element_text(angle = 15, hjust = 1))
```
::: {.callout-warning title="Un boxplot ne nettoie pas les données"}
Les observations au-delà des moustaches sont atypiques selon une convention descriptive. Elles ne doivent pas être supprimées sans justification documentaire ou analytique. Une règle graphique n'est pas une règle de qualité des données.
:::
## Résultat 5 — montrer estimation et incertitude
Le gradient diplôme–sport fournit une figure de résultat typique : quatre estimations comparables, une unité claire et des intervalles de confiance.
```{r}
#| label: plot-ch12-sport-diplome
#| fig-alt: "La proportion estimée de pratique sportive au moins hebdomadaire augmente du niveau inférieur au bac au supérieur long ; chaque point est accompagné d'un intervalle de confiance."
sport_diplome <- survey::svyby(
~sport_regulier,
~diplome_4,
design,
survey::svymean,
na.rm = TRUE,
vartype = c("se", "ci")
)
sport_plot <- svyby_ci_df(sport_diplome, "sport_regulier")
ggplot(sport_plot, aes(x = estimation, y = diplome_4)) +
geom_errorbarh(
aes(xmin = bas, xmax = haut),
height = .12,
colour = couleurs_enqueter[["gris"]]
) +
geom_point(size = 3.2, colour = couleurs_enqueter[["principal"]]) +
scale_x_continuous(
labels = scales::percent_format(accuracy = 1),
limits = c(0, .60)
) +
labs(
x = "Pratique sportive au moins hebdomadaire (IC 95 %)",
y = NULL,
title = "Le gradient scolaire est visible dans l'ordre de grandeur des estimations",
subtitle = "Estimations pondérées tenant compte des strates et des grappes",
caption = "Jeu pédagogique synthétique : les niveaux ne décrivent aucune population réelle."
) +
theme_enqueter()
```
```{r}
#| label: ch12-sport-texte
#| include: false
sport_low <- sport_plot[sport_plot$diplome_4 == "Inférieur au bac", "estimation"][[1]]
sport_high <- sport_plot[sport_plot$diplome_4 == "Supérieur long", "estimation"][[1]]
```
La figure rend immédiatement visible un passage d'environ **`r fmt_pct(sport_low, .1)`** à **`r fmt_pct(sport_high, .1)`** entre les deux extrêmes scolaires du jeu synthétique. C'est l'amplitude qui constitue le premier message ; l'incertitude indique ensuite la précision avec laquelle chaque niveau est estimé.
## Résultat 6 — petits multiples plutôt qu'une légende impossible
Une figure devient vite illisible lorsqu'on superpose plusieurs indicateurs sur des unités différentes. Une solution est de standardiser la présentation, pas les valeurs, et d'utiliser des **petits multiples**.
```{r}
#| label: plot-ch12-gradients-multiples
#| fig-alt: "Quatre petits graphiques montrent séparément le revenu, le nombre de livres lus, la confiance dans la science et les heures de télévision selon le diplôme."
indicateurs <- list(
revenu_mensuel = "Revenu mensuel (€)",
livres_12m = "Livres lus en 12 mois",
confiance_science = "Confiance dans la science (1–5)",
heures_tv = "Télévision (heures/jour)"
)
gradients <- purrr::imap_dfr(indicateurs, function(libelle, variable) {
obj <- survey::svyby(
stats::as.formula(paste0("~", variable)),
~diplome_4,
design,
survey::svymean,
na.rm = TRUE,
vartype = "ci"
)
tmp <- svyby_ci_df(obj, variable)
tmp$indicateur <- libelle
tmp
})
ggplot(gradients, aes(x = diplome_4, y = estimation, group = 1)) +
geom_errorbar(
aes(ymin = bas, ymax = haut),
width = .08,
colour = couleurs_enqueter[["gris"]]
) +
geom_line(colour = couleurs_enqueter[["secondaire"]], linewidth = .7) +
geom_point(colour = couleurs_enqueter[["principal"]], size = 2.5) +
facet_wrap(~indicateur, scales = "free_y", ncol = 2) +
labs(
x = NULL,
y = "Estimation pondérée",
title = "Un même gradient scolaire peut prendre des formes différentes selon l'indicateur",
subtitle = "Chaque panneau conserve son unité d'origine ; IC à 95 %",
caption = "Les échelles verticales diffèrent volontairement : comparer la forme, pas la hauteur entre panneaux."
) +
theme_enqueter() +
theme(axis.text.x = element_text(angle = 20, hjust = 1))
```
Cette figure est plus informative qu'un axe double ou qu'une standardisation implicite. Elle montre que la structuration sociale ne se résume pas à un seul résultat : plusieurs ressources et pratiques peuvent évoluer dans le même sens, à des amplitudes différentes.
::: {.callout-note title="Lecture sociologique"}
Dans le jeu pédagogique, le diplôme organise conjointement des ressources économiques, des pratiques culturelles et certains rapports à l'information. Ce faisceau invite à penser en termes de **position sociale, ressources et socialisations**, plutôt qu'à isoler chaque variable comme un résultat sans contexte. La figure ne permet cependant pas de déterminer le mécanisme qui produit ces associations.
:::
## Nuage de points — utile pour la forme, risqué pour l'histoire que l'on raconte
```{r}
#| label: plot-ch12-age-satisfaction
#| fig-alt: "Nuage de points de satisfaction de vie selon l'âge avec une courbe lissée."
ggplot(enqueter, aes(x = age, y = satisfaction_vie)) +
geom_jitter(
width = .25,
height = .08,
alpha = .10,
colour = couleurs_enqueter[["gris"]],
na.rm = TRUE
) +
geom_smooth(
method = "loess",
se = TRUE,
colour = couleurs_enqueter[["principal"]],
fill = couleurs_enqueter[["gris_clair"]],
na.rm = TRUE
) +
labs(
x = "Âge (ans)",
y = "Satisfaction de vie (0–10)",
title = "Une courbe lissée sert d'abord à voir une forme",
subtitle = "Exploration brute : elle n'est ni un effet d'âge ni un modèle causal",
caption = "Les points sont légèrement décalés pour rendre la densité visible."
) +
theme_enqueter()
```
Une courbe LOESS est une aide exploratoire. Dans une enquête transversale, elle ne permet pas de distinguer âge, génération, sélection et composition. Le chapitre 17 montrera comment passer d'une forme observée à une spécification de modèle, puis comment revenir à des prédictions interprétables.
## Huit règles éditoriales pour une figure de qualité
1. **Nommer l'estimand** : effectif, part brute, proportion pondérée, différence ou prédiction ?
2. **Conserver une unité interprétable** : euros, points, pourcentage, nombre attendu.
3. **Montrer l'incertitude lorsqu'elle fait partie du résultat**.
4. **Ordonner les catégories** selon une logique substantielle plutôt qu'alphabétique.
5. **Éviter les axes doubles** : ils permettent trop facilement de fabriquer visuellement des rapprochements.
6. **Ne pas dépendre uniquement de la couleur** : position, forme, facettes et libellés doivent rester informatifs.
7. **Limiter la précision graphique** : afficher 31,864 % n'apporte rien si l'IC s'étend sur plusieurs points.
8. **Faire porter au titre un message descriptif, pas un verdict causal**.
::: {.callout-tip title="Une bonne figure se lit en trois secondes puis se vérifie en trente"}
En trois secondes, le lecteur doit identifier la comparaison principale. En trente secondes, il doit pouvoir retrouver l'unité, le dénominateur, l'incertitude et le statut de la figure.
:::
## Mini-exercice
Transformez le graphique brut de diplôme en une figure pondérée avec IC. Écrivez ensuite une phrase expliquant la différence entre les deux figures.
::: {.callout-caution collapse="true" title="Correction"}
La première figure décrit les répondants observés ; la seconde estime une distribution de population sous le plan. Elles peuvent produire des ordres de grandeur proches, mais elles ne portent pas sur le même objet statistique.
:::
## Exercice de synthèse
### Niveau A — Appliquer
Produisez une figure pour `livres_12m`, puis une figure pondérée de `sport_regulier` selon `age_classe_f`.
### Niveau B — Choisir
Pour chacune des questions suivantes, choisissez une géométrie et justifiez-la :
1. décrire la forme du revenu ;
2. comparer les proportions sportives entre quatre groupes ;
3. montrer une relation potentiellement non linéaire entre âge et satisfaction ;
4. comparer quatre indicateurs de gradient scolaire.
### Niveau C — Analyser
Construisez une figure « publication-ready » répondant à une question sociologique du jeu `enqueter`. Fournissez : titre, sous-titre, axes, IC si pertinent, texte alternatif et un paragraphe séparant **ce que montre la figure** de **ce qu'elle ne permet pas d'établir**.
## À retenir
- Une figure possède un statut : diagnostic, exploration ou résultat.
- Les données brutes, les estimations pondérées et les prédictions ne doivent jamais être présentées comme si elles étaient interchangeables.
- `ggplot2` communique la structure préparée en amont ; le calcul du plan complexe reste du ressort de `{survey}` [@survey2026].
- Les petits multiples sont souvent préférables aux axes doubles et aux légendes surchargées.
- Une bonne figure montre les ordres de grandeur et l'incertitude sans exagérer la précision.
- La visualisation peut révéler une structuration sociale ; elle ne choisit pas à elle seule entre les mécanismes qui pourraient l'expliquer.
## Pour aller plus loin
Le chapitre suivant transforme les mêmes principes en **tableaux de résultats** : dénominateurs, effectifs observés, estimations pondérées, incertitude et hiérarchie de l'information.