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

j'utilise la ggplot2 pour améliorer les nuages de précipitation.

voici un exemple reproductible de ce que je veux accomplir:

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 de devinettes sur hjust et vjust sur ggplot2? Y a-t-il une meilleure façon de mettre un sous-titre (pas seulement en utilisant n, mais un sous-titre avec une couleur et une taille de texte différente)?

je dois pouvoir utiliser avec ggsave pour avoir un fichier pdf.

Voici deux questions connexes:

ajouter une note de bas de page à l'extérieur de la zone de la parcelle dans R?

Comment puis-je ajouter un sous-titre et changer la taille de police de ggplot tracks en R?

Merci pour votre aide.

64
demandé sur Community 0000-00-00 00:00:00

7 réponses

les dernières versions de ggplot2 (c.-à-d. 2.1.0.9000 ou plus récentes) ont des sous-titres et des sous-titres de fonctionnalité intégrée. Cela signifie que vous pouvez le faire:

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
67
répondu hrbrmstr 2017-07-12 09:15:10

ignorez cette réponse ggplot2 la version 2.2.0 a la fonctionnalité titre et sous-titre. Voir la réponse de @hrbrmstr ci-dessous .


vous pouvez utiliser les fonctions imbriquées atop à l'intérieur d'un expression pour obtenir des tailles différentes.

MODIFIER 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

71
répondu Sandy Muspratt 2017-07-12 04:59:16

Il semble opts est obsolète depuis la ggplot 2 0.9.1 et n'est plus fonctionnelle. Cela a fonctionné pour moi avec les dernières versions d'aujourd'hui: + ggtitle(expression(atop("Top line", atop(italic("2nd line"), "")))) .

7
répondu Aren Cambre 2013-02-03 01:42:46

cette version utilise une fonction gtable . Il permet 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 modifiera une placette avec un seul panneau de placette.

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

6
répondu Sandy Muspratt 2016-08-01 03:11:19

il n'est pas trop difficile d'ajouter des grobs au gtable et de faire 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

5
répondu baptiste 2016-03-16 19:43:54

vous pouvez utiliser envelopper la parcelle dans la grille.organiser et passer un titre personnalisé basé sur la grille,

enter image description here

library(ggplot2)
library(gridExtra)

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

tg <- grobTree(textGrob("Rainfall", y=1, vjust=1, gp = gpar(fontsize=25, face=2, col="black")),
               textGrob("location", y=0, vjust=0, gp = gpar(fontsize=12, face=3, col="grey50")),
               cl="titlegrob")
heightDetails.titlegrob <- function(x) do.call(sum,lapply(x$children, grobHeight))

grid.arrange(p, top = tg)
2
répondu baptiste 2016-02-12 21:40:01

vous avez peut - être remarqué que le code de Sandy ne produit pas de titre en gras pour" pluie " - l'instruction de faire ce caractère en gras doit apparaître dans la fonction atop() plutôt que dans la fonction theme ().

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(bold("Rainfall"), atop(italic("Location"), "")))) +
 theme(axis.text.x = element_text(angle=-45, hjust=0, vjust=1),
 plot.title = element_text(size = 25, colour = "black", vjust = -1))

enter image description here

1
répondu Nathan 2015-09-21 01:49:31