forked from juba/tidyverse
-
Notifications
You must be signed in to change notification settings - Fork 0
/
08-ggplot2.Rmd
1051 lines (699 loc) · 39.5 KB
/
08-ggplot2.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# Visualiser avec `ggplot2` {#ggplot2}
```{r setup_ggplot2, echo = FALSE}
library(knitr)
opts_chunk$set(echo = TRUE,
cache = TRUE)
```
`ggplot2` est une extension du *tidyverse* qui permet de générer des graphiques avec une syntaxe cohérente et puissante. Elle nécessite l'apprentissage d'un "mini-langage" supplémentaire, mais permet la construction de graphiques complexes de manière efficace.
Une des particularités de `ggplot2` est qu'elle part du principe que les données relatives à un graphique sont stockées dans un tableau de données (*data frame*, *tibble* ou autre).
## Préparation
`ggplot2` fait partie du coeur du *tidyverse*, elle est donc chargée automatiquement avec :
```{r message=FALSE, warning=FALSE}
library(tidyverse)
```
On peut également la charger explicitement avec :
```{r}
library(ggplot2)
```
Dans ce qui suit on utilisera le jeu de données issu du recensement de la population de 2012 inclus dans l'extension `questionr` (résultats partiels concernant les communes de plus de 2000 habitants de France métropolitaine). On charge ces données et on en extrait les données de 5 départements (l'utilisation de la fonction `filter` sera expliquée dans la section \@ref(filter) de la [partie sur `dplyr`](#dplyr) :
```{r}
library(questionr)
data(rp2012)
rp <- filter(rp2012, departement %in% c("Oise", "Rhône", "Hauts-de-Seine", "Lozère", "Bouches-du-Rhône"))
```
## Initialisation
Un graphique `ggplot2` s'initialise à l'aide de la fonction `ggplot()`. Les données représentées graphiquement sont toujours issues d'un tableau de données (*data frame* ou *tibble*), qu'on passe en argument `data` à la fonction :
```{r eval=FALSE}
ggplot(data = rp)
## Ou, équivalent
ggplot(rp)
```
On a défini la source de données, il faut maintenant ajouter des éléments de représentation graphique. Ces éléments sont appelés des `geom`, et on les ajoute à l'objet graphique de base avec l'opérateur `+`.
Un des `geom` les plus simples est `geom_histogram`. On peut l'ajouter de la manière suivante :
```{r eval=FALSE}
ggplot(rp) + geom_histogram()
```
Reste à indiquer quelle donnée nous voulons représenter sous forme d'histogramme. Cela se fait à l'aide d'arguments passés via la fonction `aes()`. Ici nous avons un paramètre à renseigner, `x`, qui indique la variable à représenter sur l'axe des x (l'axe horizontal). Ainsi, si on souhaite représenter la distribution des communes du jeu de données selon le pourcentage de cadres dans leur population active (variable `cadres`), on pourra faire :
```{r warning=FALSE, warning=FALSE, message=FALSE}
ggplot(rp) + geom_histogram(aes(x = cadres))
```
Si on veut représenter une autre variable, il suffit de changer la valeur de `x` :
```{r warning=FALSE, warning=FALSE, message=FALSE}
ggplot(rp) + geom_histogram(aes(x = ouvr))
```
```{block type='rmdnote'}
Quand on spécifie une variable, inutile d'indiquer le nom du tableau de données sous la forme `rp$ouvr`, car `ggplot2` recherche automatiquement la variable dans le tableau de données indiqué avec le paramètre `data`. On peut donc se contenter de `ouvr`.
```
Certains `geom` prennent plusieurs paramètres. Ainsi, si on veut représenter un nuage de points, on peut le faire en ajoutant un `geom_point`. On doit alors indiquer à la fois la position en `x` (la variable sur l'axe horizontal) et en `y` (la variable sur l'axe vertical) de ces points, il faut donc passer ces deux arguments à `aes()` :
```{r}
ggplot(rp) + geom_point(aes(x = dipl_sup, y = cadres))
```
On peut modifier certains attributs graphiques d'un `geom` en lui passant des arguments supplémentaires. Par exemple, pour un nuage de points, on peut modifier la couleur des points avec l'argument `color`, leur taille avec l'argument `size`, et leur transparence avec l'argument `alpha` :
```{r}
ggplot(rp) +
geom_point(aes(x = dipl_sup, y = cadres),
color = "darkgreen", size = 3, alpha = 0.3)
```
On notera que dans ce cas les arguments sont dans la fonction `geom` mais à l'extérieur du `aes()`. Plus d'explications sur ce point dans quelques instants.
## Exemples de `geom`
Il existe un grand nombre de `geom`, décrits en détail dans la [documentation officielle](http://ggplot2.tidyverse.org/reference/). Outre les `geom_histogram` et `geom_point` que l'on vient de voir, on pourra noter les `geom` suivants.
### `geom_boxplot`
`geom_boxplot` permet de représenter des boîtes à moustaches. On lui passe en `y` la variable numérique dont on veut étudier la répartition, et en `x` la variable qualitative contenant les classes qu'on souhaite comparer. Ainsi, si on veut comparer la répartition du pourcentage de maisons en fonction du département de la commune, on pourra faire :
```{r}
ggplot(rp) + geom_boxplot(aes(x = departement, y = maison))
```
On peut personnaliser la présentation avec différents argument supplémentaires comme `fill` ou `color` :
```{r}
ggplot(rp) +
geom_boxplot(aes(x = departement, y = maison), fill = "wheat", color = "tomato4")
```
Un autre argument utile, `varwidth`, permet de faire varier la largeur des boîtes en fonction des effectifs de la classe (donc, ici, en fonction du nombre de communes de chaque département) :
```{r}
ggplot(rp) +
geom_boxplot(aes(x = departement, y = maison), varwidth = TRUE)
```
### `geom_violin`
`geom_violin` est très semblable à `geom_boxplot`, mais utilise des graphes en violon à la place des boîtes à moustache.
```{r}
ggplot(rp) + geom_violin(aes(x = departement, y = maison))
```
Les graphes en violon peuvent donner une lecture plus fine des différences de distribution selon les classes.
### `geom_bar`
`geom_bar` permet de produire un graphique en bâtons (*barplot*). On lui passe en `x` la variable qualitative dont on souhaite représenter l'effectif de chaque modalité.
Par exemple, si on veut afficher le nombre de communes de notre jeu de données pour chaque département :
```{r}
ggplot(rp) + geom_bar(aes(x = departement))
```
Un cas assez fréquent mais un peu plus complexe survient quand on a déjà calculé le tri à plat de la variable à représenter. Dans ce cas on souhaite que `geom_bar` représente les effectifs sans les calculer : cela se fait en indiquant un mappage `y` pour la variable contenant les effectifs précalculés, et en ajoutant l'argument `stat = "identity"`.
Par exemple, si on a les données sous cette forme :
```{r, echo=FALSE}
df <- data.frame(table(rp$departement))
names(df) <- c("departement", "n")
df
```
On peut obtenir le graphique souhaité ainsi :
```{r}
ggplot(df) + geom_bar(aes(x = departement, y = n), stat = "identity")
```
À noter qu'on peut aussi utiliser `geom_col` qui est un raccourci pour appliquer un `geom_bar` avec `stat = "identity"`. La commande précédente est donc équivalente à :
```{r}
ggplot(df) + geom_col(aes(x = departement, y = n))
```
Là aussi, on peut modifier l'apparence du graphique avec des arguments supplémentaires comme `fill` ou `width` :
```{r}
ggplot(rp) + geom_bar(aes(x = departement), fill = "darkblue", width = .5)
```
### `geom_text`
`geom_text` permet d'afficher des étiquettes de texte. On doit lui passer `x` et `y` pour la position des étiquettes, et `label` pour leur texte.
Par exemple, si on souhaite représenter le nuage croisant la part des diplômés du supérieur et la part de cadres, mais en affichant le nom de la commune (variable `commune`) plutôt qu'un simple point, on peut faire :
```{r}
ggplot(rp) + geom_text(aes(x = dipl_sup, y = cadres, label = commune))
```
On peut personnaliser l'apparence et la position du texte avec des arguments comme `size`, `color`, etc.
```{r}
ggplot(rp) +
geom_text(aes(x = dipl_sup, y = cadres, label = commune),
color = "darkred", size = 2)
```
### `geom_label`
`geom_label` est identique à `geom_text`, mais avec une présentation un peu différente.
```{r}
ggplot(rp) + geom_label(aes(x = dipl_sup, y = cadres, label = commune))
```
### `geom_density`
`geom_density` permet d'afficher l'estimation de densité d'une variable numérique. Son usage est similaire à celui de `geom_histogram`.
Ainsi, si on veut afficher la densité de la répartition de la part des cadres dans les communes de notre jeu de données :
```{r}
ggplot(rp) + geom_density(aes(x = cadres))
```
On peut utiliser différents arguments pour ajuster le calcul de l'estimation de densité, parmi lesquels `kernel` et `bw` (voir la page d'aide de la fonction `density` pour plus de détails). `bw` (abbréviation de *bandwidth*, bande passante) permet de régler la "finesse" de l'estimation de densité, un peu comme le choix du nombre de classes dans un histogramme :
```{r}
ggplot(rp) + geom_density(aes(x = cadres), bw = 1)
```
### `geom_line`
`geom_line` trace des lignes connectant les différentes observations entre elles. Il est notamment utilisé pour la représentation de séries temporelles. On passe à `geom_line` deux paramètres : `x` et `y`. Les observations sont alors connectées selon l'ordre des valeurs passées en `x`.
Comme il n'y a pas de données adaptées pour ce type de représentation dans notre jeu de données d'exemple, on va utiliser ici le jeu de données `economics` inclus dans `ggplot2` et représenter l'évolution du taux de chômage aux États-Unis (variable `unemploy`) dans le temps (variable `date`) :
```{r}
data("economics")
economics
```
```{r}
ggplot(economics) + geom_line(aes(x = date, y = unemploy))
```
## Mappages
Un *mappage*, dans `ggplot2`, est une mise en relation entre **un attribut graphique** du `geom` (position, couleur, taille...) et **une variable** du tableau de données.
Ces mappages sont passés aux différents `geom` via la fonction `aes()` (abbréviation d'*aesthetic*).
### Exemples de mappages
On a déjà vu les mappages `x` et `y` pour un nuage de points. Ceux-ci signifient que la position d'un point donné horizontalement (`x`) et verticalement (`y`) dépend de la valeur des variables passées comme arguments `x` et `y` dans `aes()` :
```{r}
ggplot(rp) +
geom_point(aes(x = dipl_sup, y = cadres))
```
Mais on peut ajouter d'autres mappages. Par exemple, `color` permet de faire varier la couleur des points automatiquement en fonction des valeurs d'une troisième variable. Ainsi, on peut vouloir colorer les points selon le département de la commune correspondante :
```{r}
ggplot(rp) +
geom_point(aes(x = dipl_sup, y = cadres, color = departement))
```
On peut aussi faire varier la taille des points avec `size`. Ici, la taille dépend de la population totale de la commune :
```{r}
ggplot(rp) +
geom_point(aes(x = dipl_sup, y = cadres,
color = departement, size = pop_tot))
```
On peut même associer la transparence des points à une variable avec `alpha` :
```{r}
ggplot(rp) +
geom_point(aes(x = dipl_sup, y = cadres,
color = departement, size = pop_tot, alpha = maison))
```
Chaque `geom` possède sa propre liste de mappages.
### `aes()` or not `aes()` ?
Comme on l'a déjà vu, parfois on souhaite changer un attribut sans le relier à une variable. Par exemple, on veut représenter tous les points en rouge. Dans ce cas on utilise toujours l'attribut `color`, mais comme il ne s'agit pas d'un mappage, on le définit **à l'extérieur** de la fonction `aes()` :
```{r}
ggplot(rp) + geom_point(aes(x = dipl_sup, y = cadres), color = "red")
```
Par contre, si on veut faire varier la couleur en fonction des valeurs prises par une variable, on réalise un mappage, et on doit donc placer l'attribut `color` **à l'intérieur** de `aes()`.
```{r}
ggplot(rp) + geom_point(aes(x = dipl_sup, y = cadres, color = departement))
```
On peut évidemment mélanger attributs liés à une variable (mappage, donc dans `aes()`) et attributs constants (donc à l'extérieur). Dans l'exemple suivant, la taille varie en fonction de la variable `pop_tot`, mais la couleur est constante pour tous les points :
```{r}
ggplot(rp) + geom_point(aes(x = dipl_sup, y = cadres, size = pop_tot), color = "royalblue")
```
```{block type='rmdimportant'}
**La règle est donc simple mais très importante :**
Si on établit un lien entre les valeurs d'une variable et un attribut graphique, on définit un mappage, et on le déclare dans `aes()`. Sinon, on modifie l'attribut de la même manière pour tous les points, et on le définit en-dehors de la fonction `aes()`.
```
### `geom_bar` et `position`
Un des mappages possibles de `geom_bar` est l'attribut `fill`, qui permet de tracer des barres de couleur différentes selon les modalités d'une deuxième variable :
```{r}
ggplot(rp) + geom_bar(aes(x = departement, fill = pop_cl))
```
L'attribut `position` de `geom_bar` permet d'indiquer comment les différentes barres doivent être positionnées. Par défaut on a `position = "stack"` et elles sont donc "empilées". Mais on peut préciser `position = "dodge"` pour les mettre côte à côte :
```{r}
ggplot(rp) + geom_bar(aes(x = departement, fill = pop_cl), position = "dodge")
```
Ou encore `position = "fill"` pour représenter non plus des effectifs, mais des proportions :
```{r}
ggplot(rp) + geom_bar(aes(x = departement, fill = pop_cl), position = "fill")
```
## Représentation de plusieurs `geom`
On peut représenter plusieurs `geom` simultanément sur un même graphique, il suffit de les ajouter à tour de rôle avec l'opérateur `+`.
Par exemple, on peut superposer la position des points au-dessus d'un boxplot. On va pour cela ajouter un `geom_point` après avoir ajouté notre `geom_boxplot` :
```{r}
ggplot(rp) +
geom_boxplot(aes(x = departement, y = maison)) +
geom_point(aes(x = departement, y = maison), col = "red", alpha = 0.2)
```
```{block type='rmdnote'}
Quand une commande `ggplot2` devient longue, il peut être plus lisible de la répartir sur plusieurs lignes. Dans ce cas, il faut penser à placer l'opérateur `+` en fin de ligne, afin que R comprenne que la commande n'est pas complète et qu'il prenne en compte la suite.
```
Pour un résultat un peu plus lisible, on peut remplacer `geom_point` par `geom_jitter`, qui disperse les points horizontalement et facilite leur visualisation :
```{r}
ggplot(rp) +
geom_boxplot(aes(x = departement, y = maison)) +
geom_jitter(aes(x = departement, y = maison), col = "red", alpha = 0.2)
```
Pour simplifier un peu le code, plutôt que de déclarer les mappages dans chaque `geom`, on peut les déclarer dans l'appel à `ggplot()`. Ils seront automatiquement "hérités" par les `geom` ajoutés (sauf s'ils redéfinissent les mêmes mappages) :
```{r}
ggplot(rp, aes(x = departement, y = maison)) +
geom_boxplot() +
geom_jitter(color = "red", alpha = 0.2)
```
Autre exemple, on peut vouloir ajouter à un nuage de points une ligne de régression linéaire à l'aide de `geom_smooth` :
```{r}
ggplot(rp, aes(x = dipl_sup, y = cadres)) +
geom_point(alpha = 0.2) +
geom_smooth(method = "lm")
```
Et on peut même superposer une troisième visualisation de la répartition des points dans l'espace avec `geom_density2d` :
```{r}
ggplot(rp, aes(x = dipl_sup, y = cadres)) +
geom_point(alpha = 0.2) +
geom_density2d(color = "red") +
geom_smooth(method = "lm")
```
### Plusieurs sources de données
On peut aussi associer à différents `geom` des sources de données différentes. Supposons qu'on souhaite afficher sur un nuage de points les noms des communes de plus de 50000 habitants. On peut commencer par créer un tableau de données avec seulement ces communes à l'aide de la fonction `filter` :
```{r}
com50 <- filter(rp, pop_tot >= 50000)
```
On fait ensuite le nuage de points comme précédemment :
```{r}
ggplot(data = rp, aes(x = dipl_sup, y = cadres)) +
geom_point(alpha = 0.2)
```
Pour superposer les noms de communes de plus de 50 000 habitants, on peut ajouter un `geom_text`, mais en spécifiant que les données proviennent du nouveau tableau `com50` et non de notre tableau initial `rp`. On le fait en passant un argument `data` spécifique à `geom_text` :
```{r}
ggplot(data = rp, aes(x = dipl_sup, y = cadres)) +
geom_point(alpha = 0.2) +
geom_text(data = com50, aes(label = commune), color = "red", size = 3)
```
Ainsi, on obtient un graphique avec deux `geom` superposés, mais dont les données proviennent de deux tableaux différents.
## Faceting
Le *faceting* permet d'effectuer plusieurs fois le même graphique selon les valeurs d'une ou plusieurs variables qualitatives.
Par exemple, on a vu qu'on peut représenter l'histogramme du pourcentage de cadres dans nos communes avec le code suivant :
```{r, message=FALSE}
ggplot(data = rp) +
geom_histogram(aes(x = cadres))
```
On peut vouloir comparer cette répartition de la part des cadres selon le département, et donc faire un histogramme pour chacun de ces départements. C'est ce que permettent les fonctions `facet_wrap` et `facet_grid`.
Les deux fonctions prennent en paramètre une formule de la forme `~variable`, où `variable` est le nom de la variable en fonction de laquelle on souhaite faire les différents graphiques.
Avec `facet_wrap`, les différents graphiques sont affichés les uns à côté des autres et répartis automatiquement dans la page :
```{r, message=FALSE}
ggplot(data = rp) +
geom_histogram(aes(x = cadres)) +
facet_wrap(~departement)
```
Pour `facet_grid`, les graphiques sont disposés selon une grille. La formule est alors de la forme `variable en ligne ~ variable en colonne`. Si on n'a pas de variable dans l'une des deux dimensions, on met un point (`.`) :
```{r, message=FALSE}
ggplot(data = rp) +
geom_histogram(aes(x = cadres)) +
facet_grid(.~departement)
```
Un des intérêts du faceting dans `ggplot2` est que tous les graphiques générés ont les mêmes échelles, ce qui permet une comparaison directe.
Enfin, notons qu'on peut même faire du faceting sur plusieurs variables à la fois. On peut par exemple faire des histogrammes de la répartition de la part des cadres pour chaque croisement des variables `departement` et `pop_cl` :
```{r, message=FALSE}
ggplot(data = rp) +
geom_histogram(aes(x = cadres)) +
facet_grid(departement~pop_cl)
```
L'histogramme en haut à gauche représente la répartition du pourcentage de cadres parmi les communes de 2000 à 3000 habitants dans les Bouches-du-Rhône, etc.
## Scales
On a vu qu'avec `ggplot2` on définit des mappages entre des attributs graphiques (position, taille, couleur, etc.) et des variables d'un tableau de données. Ces mappages sont définis, pour chaque `geom`, via la fonction `aes()`.
Les *scales* dans `ggplot2` permettent de modifier la manière dont un attribut graphique va être relié aux valeurs d'une variable, et dont la légende correspondante va être affichée. Par exemple, pour l'attribut `color`, on pourra définir la palette de couleur utilisée. Pour `size`, les tailles minimales et maximales, etc.
Pour modifier une *scale* existante, on ajoute un nouvel élément à notre objet `ggplot2` avec l'opérateur `+`. Cet élément prend la forme `scale_<attribut>_<type>`.
Voyons tout de suite quelques exemples.
### `scale_size`
Si on souhaite modifier les tailles minimales et maximales des objets quand on a effectué un mappage de type `size`, on peut utiliser la fonction `scale_size` et son argument `range` :
```{r}
ggplot(rp) +
geom_point(aes(x = dipl_sup, y = cadres, size = pop_tot)) +
scale_size(range = c(0,20))
```
À comparer par exemple à :
```{r}
ggplot(rp) +
geom_point(aes(x = dipl_sup, y = cadres, size = pop_tot)) +
scale_size(range = c(2,8))
```
On peut ajouter d'autres paramètres à `scale_size`. Le premier argument est toujours le titre donné à la légende :
```{r}
ggplot(rp) +
geom_point(aes(x = dipl_sup, y = cadres, size = pop_tot)) +
scale_size("Population", range = c(0,15))
```
On peut aussi définir manuellement les éléments de légende représentés :
```{r}
ggplot(rp) +
geom_point(aes(x = dipl_sup, y = cadres, size = pop_tot)) +
scale_size("Population", range = c(0,15), breaks = c(1000,5000,10000,50000))
```
### `scale_x`, `scale_y`
Les *scales* `scale_x` et `scale_y` modifient les axes `x` et `y` du graphique.
`scale_x_continuous` et `scale_y_continuous` s'appliquent lorsque la variable `x` ou `y` est numérique (quantitative).
C'est le cas de notre nuage de points croisant part de cadres et part de diplômés du supérieur :
```{r}
ggplot(rp) +
geom_point(aes(x = dipl_sup, y = cadres))
```
Comme on représente des pourcentages, on peut vouloir forcer les axes `x` et `y` à s'étendre des valeurs 0 à 100. On peut le faire en ajoutant un élément `scale_x_continuous` et un élément `scale_y_continuous`, et en utilisant leur argument `limits` :
```{r}
ggplot(rp) +
geom_point(aes(x = dipl_sup, y = cadres)) +
scale_x_continuous(limits = c(0,100)) +
scale_y_continuous(limits = c(0,100))
```
Là aussi, on peut modifier les étiquettes des axes en indiquant une chaîne de caractères en premier argument :
```{r}
ggplot(rp) +
geom_point(aes(x = dipl_sup, y = cadres)) +
scale_x_continuous("Part des diplômés du supérieur (%)", limits = c(0,100)) +
scale_y_continuous("Part des cadres (%)", limits = c(0,100))
```
On peut utiliser `scale_x_log10` et `scale_y_log10` pour passer un axe à une échelle logarithmique :
```{r}
ggplot(rp) +
geom_point(aes(x = dipl_sup, y = cadres)) +
scale_x_log10("Diplômés du supérieur")
```
`scale_x_discrete` et `scale_y_discrete` s'appliquent quant à elles lorsque l'axe correspond à une variable discrète (qualitative). C'est le cas de l'axe des `x` dans un diagramme en bâtons :
```{r}
ggplot(rp) +
geom_bar(aes(x = departement)) +
scale_x_discrete("Département")
```
L'argument `limits` de `scale_x_discrete` permet d'indiquer quelles valeurs sont affichées et dans quel ordre.
```{r}
ggplot(rp) +
geom_bar(aes(x = departement)) +
scale_x_discrete("Département", limits = c("Oise", "Lozère", "Rhône"))
```
### `scale_color`, `scale_fill` {#scalecolor}
Ces *scales* permettent, entre autre, de modifier les palettes de couleur utilisées pour le dessin (`color`) ou le remplissage (`fill`) des éléments graphiques. Dans ce qui suit, pour chaque fonction `scale_color` présentée il existe une fonction `scale_fill` équivalente et avec en général les mêmes arguments.
#### Variables quantitatives
Le graphique suivant colore les points selon la valeur d'une variable numérique quantitative (ici la part de chômeurs) :
```{r}
ggplot(rp) +
geom_point(aes(x = dipl_sup, y = cadres, color = chom))
```
On peut modifier les couleurs utilisées avec les arguments `low` et `high` de la fonction `scale_color_gradient`. Ici on souhaite que la valeur la plus faible soit blanche, et la plus élevée rouge :
```{r}
ggplot(rp) +
geom_point(aes(x = dipl_sup, y = cadres, color = chom)) +
scale_color_gradient("Taux de chômage", low = "white", high = "red")
```
On peut aussi utiliser des palettes prédéfinies. L'une des plus populaires est la palette *viridis*, accessible depuis l'extension du même nom. On l'ajoute en utilisant `scale_color_viridis` :
```{r message=FALSE}
library(viridis)
ggplot(rp) +
geom_point(aes(x = dipl_sup, y = cadres, color = chom)) +
scale_color_viridis("Taux de chômage")
```
L'extension `viridis` propose également trois autres palettes, *magma*, *inferno* et *plasma*, accessibles via l'argument `option` :
```{r}
ggplot(rp) +
geom_point(aes(x = dipl_sup, y = cadres, color = chom)) +
scale_color_viridis("Taux de chômage", option = "plasma")
```
On peut aussi utiliser `scale_color_distiller`, qui transforme une des palettes pour variable qualitative de `scale_color_brewer` en palette continue pour variable numérique :
```{r}
ggplot(rp) +
geom_point(aes(x = dipl_sup, y = cadres, color = chom)) +
scale_color_distiller("Taux de chômage", palette = "Spectral")
```
La liste des palettes de `scale_color_brewer` est indiquée en fin de section suivante.
#### Variables qualitatives
Si on a fait un mappage avec une variable discrète (qualitative), comme ici avec le département :
```{r}
ggplot(rp) +
geom_point(aes(x = dipl_sup, y = cadres, color = departement))
```
Une première possibilité est de modifier la palette manuellement avec `scale_color_manual` et son argument `values` :
```{r}
ggplot(rp) +
geom_point(aes(x = dipl_sup, y = cadres, color = departement)) +
scale_color_manual("Département",
values = c("red", "#FFDD45", rgb(0.1,0.2,0.6), "darkgreen", "grey80"))
```
```{block type='rmdnote'}
L'exemple précédent montre plusieurs manières de définir manuellement des couleurs dans R :
- Par code hexadécimal : `"#FFDD45"`
- En utilisant la fonction `rgb` et en spécifiant les composantes rouge, vert, bleu par des nombres entre 0 et 1 (et optionnellement une quatrième composante d'opacité, toujours entre 0 et 1) : `rgb(0.1,0.2,0.6)`
- En donnant un nom de couleur : `"red"`, `"darkgreen"`
La liste complète des noms de couleurs connus par R peut être obtenu avec la fonction `colors()`. Vous pouvez aussi retrouver en ligne [la liste des couleurs et leur nom](http://www.stat.columbia.edu/~tzheng/files/Rcolor.pdf) (PDF).
```
Il est cependant souvent plus pertinent d'utiliser des palettes prédéfinies. Celles du site [Colorbrewer](http://colorbrewer2.org/), initialement prévues pour la cartographie, permettent une bonne lisibilité, et peuvent être adaptées pour certains types de daltonisme.
Ces palettes s'utilisent via la fonction `scale_color_brewer`, en passant le nom de la palette via l'argument `palette`. Par exemple, si on veut utiliser la palette `Set1` :
```{r}
ggplot(rp) +
geom_point(aes(x = dipl_sup, y = cadres, color = departement)) +
scale_color_brewer("Département", palette = "Set1")
```
Le graphique suivant, accessible via la fonction `display.brewer.all()`, montre la liste de toutes les palettes disponibles via `scale_color_brewer`. Elles sont réparties en trois familles : les palettes séquentielles (pour une variable quantitative), les palettes qualitatives, et les palettes divergentes (typiquement pour une variable quantitative avec une valeur de référence, souvent 0, et deux palettes continues distinctes pour les valeurs inférieures et pour les valeurs supérieures).
```{r eval=FALSE}
RColorBrewer::display.brewer.all()
```
```{r fig.height=10, fig.width=4, echo=FALSE}
par(mar = c(0, 3, 0, 0))
RColorBrewer::display.brewer.all()
```
Il existe d'autres méthodes pour définir les couleurs : pour plus d'informations on pourra se reporter à [l'article de la documentation officielle sur ce sujet](http://ggplot2.tidyverse.org/articles/ggplot2-specs.html#colour).
## Thèmes
Les thèmes permettent de contrôler l'affichage de tous les éléments du graphique qui ne sont pas reliés aux données : titres, grilles, fonds, etc.
Il existe un certain nombre de thèmes préexistants, par exemple le thème `theme_bw` :
```{r warning = FALSE, message = FALSE}
ggplot(data = rp) +
geom_histogram(aes(x = cadres)) +
theme_bw()
```
Ou le thème `theme_minimal` :
```{r warning = FALSE, message = FALSE}
ggplot(data = rp) +
geom_histogram(aes(x = cadres)) +
theme_minimal()
```
On peut cependant modifier manuellement les différents éléments. Par exemple, les fonctions `ggtitle`, `xlab` et `ylab` permettent d'ajouter ou de modifier le titre du graphique, ainsi que les étiquettes des axes `x` et `y` :
```{r warning = FALSE, message = FALSE}
ggplot(data = rp) +
geom_histogram(aes(x = cadres)) +
ggtitle("Un bien bel histogramme") +
xlab("Pourcentage de cadres") +
ylab("Effectif")
```
Les éléments personnalisables étant nombreux, un bon moyen de se familiariser avec tous les arguments est sans doute l'addin RStudio `ggThemeAssist`. Pour l'utiliser il suffit d'installer le package du même nom, de sélectionner dans son script RStudio le code correspondant à un graphique `ggplot2`, puis d'aller dans le menu *Addins* et choisir *ggplot Theme Assistant*. Une interface graphique s'affiche alors permettant de modifier les différents éléments. Si on clique sur *Done*, le code sélectionné dans le script est alors automatiquement mis à jour pour correspondre aux modifications effectuées.
Ce qui permet d'obtenir très facilement des résultats extrêmement moches :
```{r warning = FALSE, message = FALSE}
ggplot(data = rp) + geom_histogram(aes(x = cadres)) +
theme(panel.grid.major = element_line(colour = "dodgerblue",
size = 0.5, linetype = "dotdash"), axis.title = element_text(family = "serif",
size = 18, face = "italic", colour = "white"),
axis.text = element_text(family = "serif",
size = 15, face = "bold"), axis.text.x = element_text(family = "mono"),
plot.title = element_text(family = "serif"),
legend.text = element_text(family = "serif"),
legend.title = element_text(family = "serif"),
panel.background = element_rect(fill = "coral"),
plot.background = element_rect(fill = "blueviolet"))
```
## L'add-in `esquisse`
`esquisse` est un package développé notamment par [Victor Perrier](https://twitter.com/_pvictorr) de [dreamRs](https://www.dreamrs.fr/) et qui fournit une interface graphique pour la construction de graphiques avec `ggplot2`.
Pour l'utiliser, il faut évidemment préalablement installer l'extension :
```{r eval = FALSE}
install.packages("esquisse")
```
Pour lancer l'interface, ouvrez le menu *Addins* dans la barre d'outils de RStudio, et cliquez sur *'ggplot2' builder*^[Vous pouvez aussi lancer la commande `esquisser::esquisse()` dans la Console.].
![](resources/screenshots/esquisse_addin_menu.png)
Une fenêtre s'ouvre : la première étape consiste à choisir un *data frame* de votre environnement, et éventuellement à ne sélectionner que certaines de ses variables.
![Choix d'un data frame](resources/screenshots/esquisse_choose_dataset.png)
Une fois le choix effectué, cliquez sur *Validate imported data*.
L'interface principale s'affiche alors. La liste des variables du *data frame* apparaît en haut, et vous pouvez les faire glisser dans les zones *X*, *Y*, *Fill*, *Color*, *Size* et *Facet* pour créer des mappages. Le graphique se met automatiquement à jour.
![](resources/screenshots/esquisse_plot.png)
Par défaut, `esquisse` sélectionne le type de graphique le plus approprié selon la nature de vos variables. Mais vous pouvez choisir un autre type de graphique à l'aide de l'icône en haut à gauche.
Enfin, une série de menus en bas de l'interface vous permettent de personnaliser les titres, les labels, la présentation ou de filtrer des valeurs de vos variables.
Quand vous avez généré un graphique que vous souhaitez conserver, ouvrez le menu *Export & code* :
![](resources/screenshots/esquisse_export.png)
Vous y trouverez le code R correspondant au graphique actuellement affiché. Vous pouvez dès lors le copier pour le coller dans votre script, ou cliquer sur *Insert code in script* pour l'insérer directement dans votre script à l'endroit où se trouve votre curseur.
`esquisse` ne propose pas (encore) tous les `geom` ou toutes les possibilités de `ggplot2`, mais ça peut être un outil très utile et pratique pour une exploration rapide de données ou lorsqu'on est un peu perdu dans la syntaxe et les fonctions de l'extension.
Pour plus d'informations, vous pouvez vous référer à la [page du projet sur GitHub](https://github.com/dreamRs/esquisse) (en anglais).
## Ressources
[La documentation officielle](http://ggplot2.tidyverse.org/index.html) (en anglais) de `ggplot2` est très complète et accessible en ligne.
Une "antisèche" (en anglais) résumant en deux pages l'ensemble des fonctions et arguments et disponible soit directement depuis RStudio (menu *Help > Cheatsheets > Data visualization with ggplot2*) ou [en ligne](https://www.rstudio.com/resources/cheatsheets/).
Les parties [Data visualisation](http://r4ds.had.co.nz/data-visualisation.html) et [Graphics for communication](http://r4ds.had.co.nz/graphics-for-communication.html) de l'ouvrage en ligne *R for data science*, de Hadley Wickham, sont une très bonne introduction à `ggplot2`.
Plusieurs ouvrages, toujours en anglais, abordent en détail l'utilisation de `ggplot2`, en particulier [ggplot2: Elegant Graphics for Data Analysis](http://www.amazon.fr/ggplot2-Elegant-Graphics-Data-Analysis/dp/0387981403/), toujours de Hadley Wickham, et le [R Graphics Cookbook](http://www.amazon.fr/R-Graphics-Cookbook-Winston-Chang/dp/1449316956) de Winston Chang.
Le [site associé](http://www.cookbook-r.com/Graphs/) à ce dernier ouvrage comporte aussi pas mal d'exemples et d'informations intéressantes.
Enfin, si `ggplot2` présente déjà un très grand nombre de fonctionnalités, il existe aussi un système d'extensions permettant d'ajouter des `geom`, des thèmes, etc. Le site [ggplot2 extensions](http://www.ggplot2-exts.org/) est une très bonne ressource pour les parcourir et les découvrir, notamment grâce à sa [galerie](http://www.ggplot2-exts.org/gallery/).
## Exercices
Pour les exercices qui suivent, on commence par charger les extensions nécessaires et les données du jeu de données `rp2012`. On crée alors un objet `rp69` comprenant uniquement les communes du Rhône et de la Loire.
```{r, echo = TRUE}
library(tidyverse)
library(questionr)
data(rp2012)
rp69 <- filter(rp2012, departement %in% c("Rhône", "Loire"))
```
**Exercice 1**
Faire un nuage de points croisant le pourcentage de sans diplôme (`dipl_aucun`) et le pourcentage d'ouvriers (`ouvr`).
```{r echo = FALSE}
ggplot(rp69) + geom_point(aes(x = dipl_aucun, y = ouvr))
```
<div class="solution">
\iffalse
```{r eval=FALSE}
ggplot(rp69) + geom_point(aes(x = dipl_aucun, y = ouvr))
```
\fi
</div>
**Exercice 2**
Faire un nuage de points croisant le pourcentage de sans diplôme et le pourcentage d'ouvriers, avec les points en rouge et de transparence 0.2.
```{r echo = FALSE}
ggplot(rp69) + geom_point(aes(x = dipl_aucun, y = ouvr), color = "red", alpha = 0.2)
```
<div class="solution">
\iffalse
```{r eval=FALSE}
ggplot(rp69) +
geom_point(aes(x = dipl_aucun, y = ouvr), color = "red", alpha = 0.2)
```
\fi
</div>
**Exercice 3**
Représenter la répartition du pourcentage de propriétaires (variable `proprio`) selon la taille de la commune en classes (variable `pop_cl`) sous forme de boîtes à moustache.
```{r echo = FALSE}
ggplot(rp69) + geom_boxplot(aes(x = pop_cl, y = proprio))
```
<div class="solution">
\iffalse
```{r eval=FALSE}
ggplot(rp69) + geom_boxplot(aes(x = pop_cl, y = proprio))
```
\fi
</div>
**Exercice 4**
Représenter la répartition du nombre de communes selon la taille de la commune en classes sous la forme d'un diagramme en bâtons.
```{r echo = FALSE}
ggplot(rp69) + geom_bar(aes(x = pop_cl))
```
<div class="solution">
\iffalse
```{r eval=FALSE}
ggplot(rp69) + geom_bar(aes(x = pop_cl))
```
\fi
</div>
**Exercice 5**
Faire un nuage de points croisant le pourcentage de sans diplôme et le pourcentage d'ouvriers. Faire varier la couleur selon le département (`departement`).
```{r echo = FALSE}
ggplot(rp69) +
geom_point(aes(x = dipl_aucun, y = ouvr, color = departement))
```
<div class="solution">
\iffalse
```{r eval=FALSE}
ggplot(rp69) +
geom_point(aes(x = dipl_aucun, y = ouvr, color = departement))
```
\fi
</div>
Sur le même graphique, faire varier la taille des points selon la population totale de la commune (`pop_tot`).
```{r echo = FALSE}
ggplot(rp69) +
geom_point(aes(x = dipl_aucun, y = ouvr, color = departement, size = pop_tot))
```
<div class="solution">
\iffalse
```{r eval=FALSE}
ggplot(rp69) +
geom_point(aes(x = dipl_aucun, y = ouvr, color = departement, size = pop_tot))
```
\fi
</div>
Enfin, toujours sur le même graphique, rendre les points transparents en plaçant leur opacité à 0.5.
```{r echo = FALSE}
ggplot(rp69) +
geom_point(aes(x = dipl_aucun, y = ouvr, color = departement, size = pop_tot), alpha = 0.5)
```
<div class="solution">
\iffalse
```{r eval=FALSE}
ggplot(rp69) +
geom_point(aes(x = dipl_aucun, y = ouvr, color = departement, size = pop_tot), alpha = 0.5)
```
\fi
</div>
**Exercice 6**
Représenter la répartition du pourcentage de propriétaires (variable `proprio`) selon la taille de la commune en classes (variable `pop_cl`) sous forme de boîtes à moustache. Faire varier la couleur de remplissage (attribut `fill`) selon le département.
```{r echo = FALSE}
ggplot(rp69) +
geom_boxplot(aes(x = pop_cl, y = proprio, fill = departement))
```
<div class="solution">
\iffalse
```{r eval=FALSE}
ggplot(rp69) +
geom_boxplot(aes(x = pop_cl, y = proprio, fill = departement))
```
\fi
</div>
**Exercice 7**
Représenter la répartition du nombre de communes selon la taille de la commune en classes (variable `pop_cl`) sous forme de diagramme en bâtons, avec une couleur différente selon le département.
```{r echo = FALSE}
ggplot(rp69) + geom_bar(aes(x = pop_cl, fill = departement))
```
<div class="solution">
\iffalse
```{r eval=FALSE}
ggplot(rp69) + geom_bar(aes(x = pop_cl, fill = departement))
```
\fi
</div>
Faire varier la valeur du paramètre `position` pour afficher les barres les unes à côté des autres.
```{r echo = FALSE}
ggplot(rp69) + geom_bar(aes(x = pop_cl, fill = departement), position = "dodge")
```
<div class="solution">
\iffalse
```{r eval=FALSE}
ggplot(rp69) +
geom_bar(aes(x = pop_cl, fill = departement),
position = "dodge")
```
\fi
</div>
Changer à nouveau la valeur du paramètre `position` pour représenter les proportions de communes de chaque département pour chaque catégorie de taille.
```{r echo = FALSE}
ggplot(rp69) + geom_bar(aes(x = pop_cl, fill = departement), position = "fill")
```
<div class="solution">
\iffalse
```{r eval=FALSE}
ggplot(rp69) +
geom_bar(aes(x = pop_cl, fill = departement),
position = "fill")
```
\fi
</div>
**Exercice 8**
Faire le nuage de points du pourcentage de cadres (`cadres`) par le pourcentage de diplômés du supérieur (`dipl_sup`). Représenter ce nuage par deux graphiques différents selon le département en utilisant `facet_grid`.
```{r echo = FALSE}
ggplot(rp69) +
geom_point(aes(x=cadres, y=dipl_sup)) +
facet_grid(~departement)
```
<div class="solution">
\iffalse
```{r eval=FALSE}
ggplot(rp69) +
geom_point(aes(x=cadres, y=dipl_sup)) +
facet_grid(~departement)
```
\fi
</div>
Sur le même graphique, faire varier la taille des points selon la population totale de la communes (variable `pop_tot`) et rendre les points transparents.
```{r echo = FALSE}
ggplot(rp69) +
geom_point(aes(x=cadres, y=dipl_sup, size = pop_tot), alpha = 0.5) +
facet_grid(~departement)
```
<div class="solution">
\iffalse
```{r eval=FALSE}
ggplot(rp69) +
geom_point(aes(x=cadres, y=dipl_sup, size = pop_tot), alpha = 0.5) +
facet_grid(~departement)
```
\fi