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:

  1. Cr?er les graphiques : p1, p2, ?.
  2. Enregistrer la l?gende du graphique p1 comme un ?l?ment graphique externe (appel? ?grob? dans la terminologie Grid)
  3. Retirer les l?gendes de tous les graphiques
  4. 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:

  1. Cr?er les graphiques: p1, p2, p3, ?.
  2. Partir ? la page suivante sur le dispositif grid en utilisant la fonction grid.newpage()
  3. Cr?er une mise en page 2X2 - nombre de colonne = 2; nombre de ligne = 2
  4. D?finir une zone de vue (?grid viewport? : une r?gion rectangulaire sur le dispositif graphique)
  5. 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:

  1. Cr?er un nuage de points de y = f(x)
  2. 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)


Enjoyed this article? I’d be very grateful if you’d help it spread by emailing it to a friend, or sharing it on Twitter, Facebook or Linked In.

Show me some love with the like buttons below... Thank you and please don't forget to share and comment below!!
Avez vous aimé cet article? Je vous serais très reconnaissant si vous aidiez à sa diffusion en l'envoyant par courriel à un ami ou en le partageant sur Twitter, Facebook ou Linked In.

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!





Cette page a été vue 32009 fois
Licence - Pas d?Utilisation Commerciale - Partage dans les M?mes Conditions
Licence Creative Commons