superponer - Mostrando texto debajo del gráfico generado por ggplot2
superponer graficas en r ggplot (4)
En realidad, la mejor respuesta y la solución más sencilla es usar el paquete cowplot.
La versión 0.5.0 del paquete cowplot (en CRAN) maneja los subtítulos ggplot2 usando la función add_sub.
Úselo así:
diamondsCubed <-ggplot(aes(carat, price), data = diamonds) +
geom_point() +
scale_x_continuous(trans = cuberoot_trans(), limits = c(0.2, 3),
breaks = c(0.2, 0.5, 1, 2, 3)) +
scale_y_continuous(trans = log10_trans(), limits = c(350, 15000),
breaks = c(350, 1000, 5000, 10000, 15000)) +
ggtitle(''Price log10 by Cube-Root of Carat'') +
theme_xkcd()
ggdraw(add_sub(diamondsCubed, "This is an annotation./nAnnotations can span multiple lines."))
Estoy tratando de mostrar cierta información sobre los datos debajo de la trama creada en ggplot2 . Me gustaría trazar la variable N usando la coordenada del eje X de la gráfica, pero la coordenada Y debe ser del 10% desde la parte inferior de la pantalla. De hecho, las coordenadas Y deseadas ya están en el marco de datos como la variable y_pos.
Puedo pensar en 3 enfoques usando ggplot2 :
1) Cree un diagrama vacío debajo del gráfico real, use la misma escala y luego use geom_text para trazar los datos sobre el gráfico en blanco. Este enfoque funciona, pero es extremadamente complicado.
2) Use geom_text
para trazar los datos, pero de alguna manera utilice la coordenada y como porcentaje de la pantalla (10%). Esto obligaría a los números a mostrarse debajo de la trama. No puedo descifrar la sintaxis adecuada.
3) Usa grid.text para mostrar el texto. Puedo configurarlo fácilmente en el 10% desde la parte inferior de la pantalla, pero no entiendo cómo establecer la coordinación X para que coincida con la trama. Traté de usar grconvert para capturar la posición X inicial pero no pude hacer eso también.
A continuación se muestra el gráfico básico con los datos ficticios:
graphics.off() # close graphics windows
library(car)
library(ggplot2) #load ggplot
library(gridExtra) #load Grid
library(RGraphics) # support of the "R graphics" book, on CRAN
#create dummy data
test= data.frame(
Group = c("A", "B", "A","B", "A", "B"),
x = c(1 ,1,2,2,3,3 ),
y = c(33,25,27,36,43,25),
n=c(71,55,65,58,65,58),
y_pos=c(9,6,9,6,9,6)
)
#create ggplot
p1 <- qplot(x, y, data=test, colour=Group) +
ylab("Mean change from baseline") +
geom_line()+
scale_x_continuous("Weeks", breaks=seq(-1,3, by = 1) ) +
opts(
legend.position=c(.1,0.9))
#display plot
p1
La gplot modificada a continuación muestra números de sujetos, sin embargo, se muestran DENTRO de la gráfica. Obligan a la escala Y a extenderse. Me gustaría mostrar estos números debajo de la trama.
p1 <- qplot(x, y, data=test, colour=Group) +
ylab("Mean change from baseline") +
geom_line()+
scale_x_continuous("Weeks", breaks=seq(-1,3, by = 1) ) +
opts( plot.margin = unit(c(0,2,2,1), "lines"),
legend.position=c(.1,0.9))+
geom_text(data = test,aes(x=x,y=y_pos,label=n))
p1
Un enfoque diferente de mostrar los números implica crear una gráfica ficticia debajo de la gráfica real. Aquí está el código:
graphics.off() # close graphics windows
library(car)
library(ggplot2) #load ggplot
library(gridExtra) #load Grid
library(RGraphics) # support of the "R graphics" book, on CRAN
#create dummy data
test= data.frame(
group = c("A", "B", "A","B", "A", "B"),
x = c(1 ,1,2,2,3,3 ),
y = c(33,25,27,36,43,25),
n=c(71,55,65,58,65,58),
y_pos=c(15,6,15,6,15,6)
)
p1 <- qplot(x, y, data=test, colour=group) +
ylab("Mean change from baseline") +
opts(plot.margin = unit(c(1,2,-1,1), "lines")) +
geom_line()+
scale_x_continuous("Weeks", breaks=seq(-1,3, by = 1) ) +
opts(legend.position="bottom",
legend.title=theme_blank(),
title.text="Line plot using GGPLOT")
p1
p2 <- qplot(x, y, data=test, geom="blank")+
ylab(" ")+
opts( plot.margin = unit(c(0,2,-2,1), "lines"),
axis.line = theme_blank(),
axis.ticks = theme_segment(colour = "white"),
axis.text.x=theme_text(angle=-90,colour="white"),
axis.text.y=theme_text(angle=-90,colour="white"),
panel.background = theme_rect(fill = "transparent",colour = NA),
panel.grid.minor = theme_blank(),
panel.grid.major = theme_blank()
)+
geom_text(data = test,aes(x=x,y=y_pos,label=n))
p2
grid.arrange(p1, p2, heights = c(8.5, 1.5), nrow=2 )
Sin embargo, eso es muy complicado y sería difícil modificarlo para diferentes datos. Idealmente, me gustaría poder pasar las coordenadas Y como porcentaje de la pantalla.
La versión actual (> 2.1) tiene a + labs(caption = "text")
, que muestra una anotación debajo de la gráfica. Esto es temible (propiedades de fuente, ... alineado a la izquierda / derecha). Consulte https://github.com/hadley/ggplot2/pull/1582 para ver ejemplos.
opts
editados ha quedado obsoleto, reemplazado por theme
; element_blank
ha reemplazado theme_blank
; y ggtitle()
se usa en lugar de opts(title = ...
Sandy, ¡muchas gracias! Esto hace exactamente lo que quiero. Ojalá pudiéramos controlar el recorte en geom.text o geom.annotate.
Arreglo el siguiente programa si alguien más está interesado.
rm(list = ls()) # clear objects
graphics.off() # close graphics windows
library(ggplot2)
library(gridExtra)
#create dummy data
test= data.frame(
group = c("Group 1", "Group 1", "Group 1","Group 2", "Group 2", "Group 2"),
x = c(1 ,2,3,1,2,3 ),
y = c(33,25,27,36,23,25),
n=c(71,55,65,58,65,58),
ypos=c(18,18,18,17,17,17)
)
p1 <- qplot(x=x, y=y, data=test, colour=group) +
ylab("Mean change from baseline") +
theme(plot.margin = unit(c(1,3,8,1), "lines")) +
geom_line()+
scale_x_continuous("Visits", breaks=seq(-1,3) ) +
theme(legend.position="bottom",
legend.title=element_blank())+
ggtitle("Line plot")
# Create the textGrobs
for (ii in 1:nrow(test))
{
#display numbers at each visit
p1=p1+ annotation_custom(grob = textGrob(test$n[ii]),
xmin = test$x[ii],
xmax = test$x[ii],
ymin = test$ypos[ii],
ymax = test$ypos[ii])
#display group text
if (ii %in% c(1,4)) #there is probably a better way
{
p1=p1+ annotation_custom(grob = textGrob(test$group[ii]),
xmin = 0.85,
xmax = 0.85,
ymin = test$ypos[ii],
ymax = test$ypos[ii])
}
}
# Code to override clipping
gt <- ggplot_gtable(ggplot_build(p1))
gt$layout$clip[gt$layout$name=="panel"] <- "off"
grid.draw(gt)
Las opts()
actualizadas opts()
se han reemplazado con el theme()
En el siguiente código, se dibuja un gráfico base, con un margen más ancho en la parte inferior del gráfico. El textoGrob se crea, luego se inserta en el diagrama usando annotation_custom (). Excepto que el texto no está visible porque está fuera del panel de trazado: la salida está recortada en el panel. Pero usando el código de Baptiste desde aquí , el recorte puede ser anulado. La posición está en términos de unidades de datos, y ambas etiquetas de texto están centradas.
library(ggplot2)
library(grid)
# Base plot
df = data.frame(x=seq(1:10), y = seq(1:10))
p = ggplot(data = df, aes(x = x, y = y)) + geom_point() + ylim(0,10) +
theme(plot.margin = unit(c(1,1,3,1), "cm"))
p
# Create the textGrobs
Text1 = textGrob(paste("Largest x-value is", round(max(df$x), 2), sep = " "))
Text2 = textGrob(paste("Mean = ", mean(df$x), sep = ""))
p1 = p + annotation_custom(grob = Text1, xmin = 4, xmax = 4, ymin = -3, ymax = -3) +
annotation_custom(grob = Text2, xmin = 8, xmax = 8, ymin = -3, ymax = -3)
p1
# Code to override clipping
gt <- ggplotGrob(p1)
gt$layout$clip[gt$layout$name=="panel"] <- "off"
grid.draw(gt)
O, usando funciones de grid
para crear y posicionar la etiqueta.
p
grid.text((paste("Largest x-value is", max(df$x), sep = " ")),
x = unit(.2, "npc"), y = unit(.1, "npc"), just = c("left", "bottom"),
gp = gpar(fontface = "bold", fontsize = 18, col = "blue"))
Editar O, agregar texto grob usando funciones gtable.
library(ggplot2)
library(grid)
library(gtable)
# Base plot
df = data.frame(x=seq(1:10), y = seq(1:10))
p = ggplot(data = df, aes(x = x, y = y)) + geom_point() + ylim(0,10)
# Construct the text grob
lab = textGrob((paste("Largest x-value is", max(df$x), sep = " ")),
x = unit(.1, "npc"), just = c("left"),
gp = gpar(fontface = "bold", fontsize = 18, col = "blue"))
gp = ggplotGrob(p)
# Add a row below the 2nd from the bottom
gp = gtable_add_rows(gp, unit(2, "grobheight", lab), -2)
# Add ''lab'' grob to that row, under the plot panel
gp = gtable_add_grob(gp, lab, t = -2, l = gp$layout[gp$layout$name == "panel",]$l)
grid.newpage()
grid.draw(gp)