99 votes

Comment ajouter un sous-titre ggplot2 de taille et de couleur différentes ?

J'utilise ggplot2 pour améliorer les diagrammes à barres des précipitations.

Voici un exemple reproductible de ce que je veux réaliser :

library(ggplot2)
library(gridExtra)
secu <- seq(1, 16, by=2)
melt.d <- data.frame(y=secu, x=LETTERS[1:8])
m <- ggplot(melt.d, aes(x=x, y=y)) +
  geom_bar(fill="darkblue") + 
  labs(x="Weather    stations", y="Accumulated Rainfall [mm]") +
  opts(axis.text.x=theme_text(angle=-45, hjust=0, vjust=1),
       title=expression("Rainfall"), plot.margin = unit(c(1.5, 1, 1, 1), "cm"),
       plot.title = theme_text(size = 25, face = "bold", colour = "black", vjust = 5))
z <- arrangeGrob(m, sub = textGrob("Location", x = 0, hjust = -3.5, vjust = -33, gp = gpar(fontsize = 18, col = "gray40"))) #Or guessing x and y with just option
z

Je ne sais pas comment éviter d'utiliser des nombres devinables sur hjust et vjust sur ggplot2 ? Existe-t-il un meilleur moyen de mettre un sous-titre (pas seulement en utilisant \n mais un sous-titre avec une couleur et une taille de texte différentes) ?

J'ai besoin de pouvoir l'utiliser avec ggsave pour avoir un fichier pdf.

Voici deux questions connexes :

Ajouter une citation en note de bas de page en dehors de la zone d'intrigue dans R ?

Comment puis-je ajouter un sous-titre et modifier la taille de la police des graphiques ggplot dans R ?

Merci pour toute aide.

120voto

hrbrmstr Points 53822

Les dernières versions de ggplot2 (c'est-à-dire 2.1.0.9000 ou plus récent) ont des sous-titres et des légendes sous le graphe comme fonctionnalité intégrée. Cela signifie que vous pouvez faire ceci :

library(ggplot2) # 2.1.0.9000+ 

secu <- seq(1, 16, by=2)
melt.d <- data.frame(y=secu, x=LETTERS[1:8])

m <-  ggplot(melt.d, aes(x=x, y=y))
m <- m + geom_bar(fill="darkblue", stat="identity")
m <- m + labs(x="Weather    stations", 
              y="Accumulated Rainfall [mm]",
              title="Rainfall",
              subtitle="Location")
m <- m + theme(axis.text.x=element_text(angle=-45, hjust=0, vjust=1)) 
m <- m + theme(plot.title=element_text(size=25, hjust=0.5, face="bold", colour="maroon", vjust=-1))
m <- m + theme(plot.subtitle=element_text(size=18, hjust=0.5, face="italic", color="black"))
m

77voto

Sandy Muspratt Points 5682

Ignorer cette réponse ggplot2 La version 2.2.0 dispose de la fonctionnalité de titre et de sous-titre. Voir la réponse de @hrbrmstr en dessous de .


Vous pourriez utiliser des éléments imbriqués atop à l'intérieur d'un expression pour obtenir des tailles différentes.

EDITAR Code mis à jour pour ggplot2 0.9.3

m <-  ggplot(melt.d, aes(x=x, y=y)) + 
     geom_bar(fill="darkblue", stat = "identity") + 
     labs(x="Weather    stations", y="Accumulated Rainfall [mm]") + 
     ggtitle(expression(atop("Rainfall", atop(italic("Location"), "")))) +
     theme(axis.text.x = element_text(angle=-45, hjust=0, vjust=1), 
     #plot.margin = unit(c(1.5, 1, 1, 1), "cm"), 
     plot.title = element_text(size = 25, face = "bold", colour = "black", vjust = -1))

enter image description here

11voto

baptiste Points 19677

Il n'est pas trop difficile d'ajouter des grobs au gtable et de créer un titre fantaisiste de cette façon,

library(ggplot2)
library(grid)
library(gridExtra)
library(magrittr)
library(gtable)

p <- ggplot() + 
  theme(plot.margin = unit(c(0.5, 1, 1, 1), "cm"))

lg <- list(textGrob("Rainfall", x=0, hjust=0, 
                    gp = gpar(fontsize=24, fontfamily="Skia", face=2, col="turquoise4")),
               textGrob("location", x=0, hjust=0, 
                        gp = gpar(fontsize=14, fontfamily="Zapfino", fontface=3, col="violetred1")),
           pointsGrob(pch=21, gp=gpar(col=NA, cex=0.5,fill="steelblue")))

margin <- unit(0.2, "line")
tg <- arrangeGrob(grobs=lg, layout_matrix=matrix(c(1,2,3,3), ncol=2),
                  widths = unit.c(grobWidth(lg[[1]]), unit(1,"null")),
                  heights = do.call(unit.c, lapply(lg[c(1,2)], grobHeight)) + margin)

grid.newpage()
ggplotGrob(p) %>%
  gtable_add_rows(sum(tg$heights), 0) %>%
  gtable_add_grob(grobs=tg, t = 1, l = 4)  %>%
  grid.draw()

enter image description here

10voto

Aren Cambre Points 815

Il semble que opts est déprécié depuis la version 0.9.1 de ggplot 2 et n'est plus fonctionnel. Cela a fonctionné pour moi avec les dernières versions à ce jour : + ggtitle(expression(atop("Top line", atop(italic("2nd line"), "")))) .

8voto

Sandy Muspratt Points 5682

Cette version utilise un gtable fonction. Elle autorise deux lignes de texte dans le titre. Le texte, la taille, la couleur et la police de chaque ligne peuvent être définis indépendamment de l'autre. Cependant, la fonction ne modifiera qu'un tracé avec un seul panneau de tracé.

Modification mineure : mise à jour vers ggplot2 v2.0.0

# The original plot
library(ggplot2)

secu <- seq(1, 16, by = 2)
melt.d <- data.frame(y = secu, x = LETTERS[1:8])

m <- ggplot(melt.d, aes(x = x, y = y)) + 
     geom_bar(fill="darkblue", stat = "identity") + 
     labs(x = "Weather    stations", y = "Accumulated Rainfall [mm]") + 
     theme(axis.text.x = element_text(angle = -45, hjust = 0, vjust = 1))

# The function to set text, size, colour, and face
plot.title = function(plot = NULL, text.1 = NULL, text.2 = NULL, 
   size.1 = 12,  size.2 = 12,
   col.1 = "black", col.2 = "black", 
   face.1 = "plain",  face.2 = "plain") {

library(gtable)
library(grid)

gt = ggplotGrob(plot)

text.grob1 = textGrob(text.1, y = unit(.45, "npc"), 
   gp = gpar(fontsize = size.1, col = col.1, fontface = face.1))
text.grob2 = textGrob(text.2,  y = unit(.65, "npc"), 
   gp = gpar(fontsize = size.2, col = col.2, fontface = face.2))

text = matrix(list(text.grob1, text.grob2), nrow = 2)
text = gtable_matrix(name = "title", grobs = text, 
   widths = unit(1, "null"), 
   heights = unit.c(unit(1.1, "grobheight", text.grob1) + unit(0.5, "lines"), unit(1.1,  "grobheight", text.grob2) + unit(0.5, "lines")))

gt = gtable_add_grob(gt, text, t = 2, l = 4)
gt$heights[2] = sum(text$heights)

class(gt) =  c("Title", class(gt))

gt
}

# A print method for the plot
print.Title <- function(x) {
   grid.newpage()   
   grid.draw(x)
}

# Try it out - modify the original plot
p = plot.title(m, "Rainfall", "Location", 
   size.1 = 20, size.2 = 15, 
   col.1 = "red", col.2 = "blue", 
   face.2 = "italic")

p

enter image description here

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X