ggplot2 - Combiner plusieurs graphiques sur la m?me page - Logiciel R et visualisation de donn?es
Pour combiner plusieurs graphes de ggplot2 sur la m?me page, les fonctions standard de R - par() et layout() - ne peuvent ?tre utilis?es.
Ce tutoriel R va vous montrer, ?tape par ?tape, comment mettre plusieurs ggplots sur une seule page.
Les fonctions grid.arrange()[dans le package gridExtra] et plot_grid()[dans le package cowplot], seront utilis?es.
Installer et charger les packages n?cessaires
Installer et charger le package gridExtra
install.packages("gridExtra")
library("gridExtra")
Installer et charger le package cowplot
cowplot peut ?tre install? comme suit:
install.packages("cowplot")
OU
comme suit en utilisant le package devtools (devtools devrait ?tre install? avant d?utiliser le code ci-dessous):
devtools::install_github("wilkelab/cowplot")
Charger cowplot:
library("cowplot")
Pr?parer des donn?es
Le jeu de donn?es ToothGrowth peut ?tre utilis? :
df <- ToothGrowth
# Convertir la colonne dose en facteur
df$dose <- as.factor(df$dose)
head(df)
## len supp dose
## 1 4.2 VC 0.5
## 2 11.5 VC 0.5
## 3 7.3 VC 0.5
## 4 5.8 VC 0.5
## 5 6.4 VC 0.5
## 6 10.0 VC 0.5
Cowplot: Graphs pr?t-?-publier
Le package cowplot est une extension de ggplot2 et il peut ?tre utiliser pour g?n?rer des graphiques pr?t-?-publier.
Graph simples
library(cowplot)
# Graphe par d?faut
bp <- ggplot(df, aes(x=dose, y=len, color=dose)) +
geom_boxplot() +
theme(legend.position = "none")
bp
# Ajouter les grilles
bp + background_grid(major = "xy", minor = "none")
Rappelons que, la fonction ggsave() [dans le package ggplot2] peut ?tre utilis?e pour enregistrer des ggplots. Cependant, lorsque l?on travaille avec cowplot, la fonction save_plot() [dans le package cowplot] est pr?f?r?e. Il est une alternative ? ggsave avec un meilleur support pour les graphiques multi-figures.
save_plot("mpg.pdf", plot.mpg,
base_aspect_ratio = 1.3 #Laisser de la place pour la l?gende
)
Combiner plusieurs graphes en utilisant cowplot
# Nuage de points
sp <- ggplot(mpg, aes(x = cty, y = hwy, colour = factor(cyl)))+
geom_point(size=2.5)
sp
# Bar plot
bp <- ggplot(diamonds, aes(clarity, fill = cut)) +
geom_bar() +
theme(axis.text.x = element_text(angle=70, vjust=0.5))
bp
Combiner deux graphiques (nuage de points et bar plot):
plot_grid(sp, bp, labels=c("A", "B"), ncol = 2, nrow = 1)
La fonction draw_plot() peut ?tre utilis?e pour placer des graphiques dans des sites sp?cifiques avec une taille particuli?re. Le format de la fonction est la suivante:
draw_plot(plot, x = 0, y = 0, width = 1, height = 1)
- plot: Le graphique ? placer (ggplot2 ou un gtable)
- x: L?abscisse x du coin inf?rieur gauche du graphique
- y: L?ordonn?e y du coin inf?rieur gauche du graphique
- width, height: la largeur et la hauteur du graphique
La fonction ggdraw() est utilis?e pour initialiser le graphique.
plot.iris <- ggplot(iris, aes(Sepal.Length, Sepal.Width)) +
geom_point() + facet_grid(. ~ Species) +
stat_smooth(method = "lm") +
background_grid(major = 'y', minor = "none") + # grilles horiz.
panel_border() # Bordure autour de chaque panel
ggdraw() +
draw_plot(plot.iris, 0, .5, 1, .5) +
draw_plot(sp, 0, 0, .5, .5) +
draw_plot(bp, .5, 0, .5, .5) +
draw_plot_label(c("A", "B", "C"), c(0, 0, 0.5), c(1, 0.5, 0.5), size = 15)
grid.arrange: Cr?er et organiser plusieurs graphiques
Le code R ci-dessous, cr?e un box plot, un dot plot, un violin plot et un stripchart (jitter plot) :
library(ggplot2)
# Cr?er un box plot
bp <- ggplot(df, aes(x=dose, y=len, color=dose)) +
geom_boxplot() +
theme(legend.position = "none")
# Cr?er un dot plot
# Ajouter la moyenne et l'?cart type
dp <- ggplot(df, aes(x=dose, y=len, fill=dose)) +
geom_dotplot(binaxis='y', stackdir='center')+
stat_summary(fun.data=mean_sdl, fun.args = list(mult=1),
geom="pointrange", color="red")+
theme(legend.position = "none")
# Cr?er un violin plot
vp <- ggplot(df, aes(x=dose, y=len)) +
geom_violin()+
geom_boxplot(width=0.1)
# Cr?er un stripchart
sc <- ggplot(df, aes(x=dose, y=len, color=dose, shape=dose)) +
geom_jitter(position=position_jitter(0.2))+
theme(legend.position = "none") +
theme_gray()
Combiner les graphiques en utilisant la fonction grid.arrange() [dans gridExtra] :
library(gridExtra)
grid.arrange(bp, dp, vp, sc, ncol=2, nrow = 2)
Ajouter une l?gende commune pour plusieurs graphiques ggplot2
Ceci peut ?tre r?alis? en quatre ?tapes:
- Cr?er les graphiques : p1, p2, ?.
- Enregistrer la l?gende du graphique p1 comme un ?l?ment graphique externe (appel? ?grob? dans la terminologie Grid)
- Retirer les l?gendes de tous les graphiques
- Dessiner l?ensemble des graphiques avec seulement une l?gende dans le panel de droite
Pour enregistrer la l?gende d?un ggplot, la fonction d?aide ci-dessous peut ?tre utilis?e:
library(gridExtra)
get_legend<-function(myggplot){
tmp <- ggplot_gtable(ggplot_build(myggplot))
leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
legend <- tmp$grobs[[leg]]
return(legend)
}
(La fonction ci-dessus est d?riv?e de ce forum. )
# 1. Cr?er les graphiques
#++++++++++++++++++++++++++++++++++
# Cr?er un box plot
bp <- ggplot(df, aes(x=dose, y=len, color=dose)) +
geom_boxplot()
# Cr?er un violin plot
vp <- ggplot(df, aes(x=dose, y=len, color=dose)) +
geom_violin()+
geom_boxplot(width=0.1)+
theme(legend.position="none")
# 2. Enregistrer la l?gende
#+++++++++++++++++++++++
legend <- get_legend(bp)
# 3. Supprimer la l?gende du box plot
#+++++++++++++++++++++++
bp <- bp + theme(legend.position="none")
# 4. Combiner les graphiques avec des tailles sp?cifiques
grid.arrange(bp, vp, legend, ncol=3, widths=c(2.3, 2.3, 0.8))
Nuage de point avec courbe de distribution marginale
Step 1/3. Cr?er des donn?es:
set.seed(1234)
x <- c(rnorm(500, mean = -1), rnorm(500, mean = 1.5))
y <- c(rnorm(500, mean = 1), rnorm(500, mean = 1.7))
group <- as.factor(rep(c(1,2), each=500))
df2 <- data.frame(x, y, group)
head(df2)
## x y group
## 1 -2.20706575 -0.2053334 1
## 2 -0.72257076 1.3014667 1
## 3 0.08444118 -0.5391452 1
## 4 -3.34569770 1.6353707 1
## 5 -0.57087531 1.7029518 1
## 6 -0.49394411 -0.9058829 1
Step 2/3. Cr?er des graphiques:
# Nuage de points color?s par groupes
scatterPlot <- ggplot(df2,aes(x, y, color=group)) +
geom_point() +
scale_color_manual(values = c('#999999','#E69F00')) +
theme(legend.position=c(0,1), legend.justification=c(0,1))
# Courbe de densit? marginale de x (panel du haut)
xdensity <- ggplot(df2, aes(x, fill=group)) +
geom_density(alpha=.5) +
scale_fill_manual(values = c('#999999','#E69F00')) +
theme(legend.position = "none")
# Courbe de densit? marginale de y (panel de droite)
ydensity <- ggplot(df2, aes(y, fill=group)) +
geom_density(alpha=.5) +
scale_fill_manual(values = c('#999999','#E69F00')) +
theme(legend.position = "none")
Cr?er un emplacement vide:
blankPlot <- ggplot()+geom_blank(aes(1,1))+
theme(
plot.background = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.border = element_blank(),
panel.background = element_blank(),
axis.title.x = element_blank(),
axis.title.y = element_blank(),
axis.text.x = element_blank(),
axis.text.y = element_blank(),
axis.ticks = element_blank(),
axis.line = element_blank()
)
Step 3/3. Regrouper les graphiques:
Organiser le graphique avec des largeurs et des hauteurs adapt?es pour chaque ligne et chaque colonne:
library("gridExtra")
grid.arrange(xdensity, blankPlot, scatterPlot, ydensity,
ncol=2, nrow=2, widths=c(4, 1.4), heights=c(1.4, 4))
Cr?er une mise en page complexe en utilisant la fonction viewport()
Les diff?rentes ?tapes sont:
- Cr?er les graphiques: p1, p2, p3, ?.
- Partir ? la page suivante sur le dispositif grid en utilisant la fonction grid.newpage()
- Cr?er une mise en page 2X2 - nombre de colonne = 2; nombre de ligne = 2
- D?finir une zone de vue (?grid viewport? : une r?gion rectangulaire sur le dispositif graphique)
- Afficher le graphique dans le viewport
require(grid)
# Nouvelle page
grid.newpage()
# Cr?er la mise en page : nrow = 2, ncol = 2
pushViewport(viewport(layout = grid.layout(2, 2)))
# Une fonction pour definir une region dans la mise en page
define_region <- function(row, col){
viewport(layout.pos.row = row, layout.pos.col = col)
}
# Arranger les graphiques
print(scatterPlot, vp=define_region(1, 1:2))
print(xdensity, vp = define_region(2, 1))
print(ydensity, vp = define_region(2, 2))
Ins?rez un ?l?ment graphique externe dans un ggplot
La fonction annotation_custom() [dans ggplot2] peut ?tre utilis?e pour ajouter des tables, des graphiques ou d?autres ?l?ments du syst?me graphique ?grid?. Le format simplifi? est:
annotation_custom(grob, xmin, xmax, ymin, ymax)
- grob: L??l?ment externe graphique ? afficher
- xmin, xmax : location x exprim?e dans les coordonn?es de donn?es (location horizontale)
- ymin, ymax : location x exprim?e dans les coordonn?es de donn?es (location verticale)
Les diff?rentes ?tapes sont:
- Cr?er un nuage de points de y = f(x)
- Ajouter, par exemple, le box plot de x et de y ? l?int?rieur du nuage de points en utilisant la fonction annotation_custom()
Comme le box plot int?rieur chevauche avec certains points, un fond transparent est utilis? pour les box plots.
# Cr?er un th?me transparent
transparent_theme <- theme(
axis.title.x = element_blank(),
axis.title.y = element_blank(),
axis.text.x = element_blank(),
axis.text.y = element_blank(),
axis.ticks = element_blank(),
panel.grid = element_blank(),
axis.line = element_blank(),
panel.background = element_rect(fill = "transparent",colour = NA),
plot.background = element_rect(fill = "transparent",colour = NA))
Cr?er les graphes:
p1 <- scatterPlot # voir sections pr?c?dentes
# Box plot pour la variable x
p2 <- ggplot(df2, aes(factor(1), x))+
geom_boxplot(width=0.3)+coord_flip()+
transparent_theme
# Box plot pour la variable y
p3 <- ggplot(df2, aes(factor(1), y))+
geom_boxplot(width=0.3)+
transparent_theme
# Cr?er les ?l?ments graphiques externes
# ("grob" en termininology grid)
p2_grob = ggplotGrob(p2)
p3_grob = ggplotGrob(p3)
# Inserer p2_grob ? l'int?rieur du nuage de points
xmin <- min(x); xmax <- max(x)
ymin <- min(y); ymax <- max(y)
p1 + annotation_custom(grob = p2_grob, xmin = xmin, xmax = xmax,
ymin = ymin-1.5, ymax = ymin+1.5)
# Inserer p3_grob ? l'int?rieur du nuage de points
p1 + annotation_custom(grob = p3_grob,
xmin = xmin-1.5, xmax = xmin+1.5,
ymin = ymin, ymax = ymax)
Si vous avez une solution pour ins?rer, en m?me temps, ? la fois p2_grob et p3_grob ? l?int?rieur du nuage de points, s?il vous pla?t laissez-moi un commentaire. J?ai eu quelques erreurs en essayant de le faire ?
Combiner table, texte et graphique ggplot2
Les fonctions ci-dessous sont n?cessaires:
- tableGrob() [dans le package gridExtra] : pour ajouter un tableau de donn?es ? un dispositif graphique
- splitTextGrob() [dans le package RGraphics] : pour ajouter un texte ? un graphique
Assurez vous que le package RGraphics est install?.
library(RGraphics)
library(gridExtra)
# Tableau
p1 <- tableGrob(head(ToothGrowth))
# Texte
text <- "ToothGrowth data describes the effect of Vitamin C on tooth growth in Guinea pigs. Three dose levels of Vitamin C (0.5, 1, and 2 mg) with each of two delivery methods [orange juice (OJ) or ascorbic acid (VC)] are used."
p2 <- splitTextGrob(text)
# Box plot
p3 <- ggplot(df, aes(x=dose, y=len)) + geom_boxplot()
# Combiner les graphiques sur la m?me page
grid.arrange(p1, p2, p3, ncol=1)
Infos
Cette analyse a ?t? faite en utilisant le logiciel R (ver. 3.2.4) et le package ggplot2 (ver. 2.1.0)
Show me some love with the like buttons below... Thank you and please don't forget to share and comment below!!
Montrez-moi un peu d'amour avec les like ci-dessous ... Merci et n'oubliez pas, s'il vous plaît, de partager et de commenter ci-dessous!