varias tutorial los leyendas graficos graficas espaƱol escala ejes como cambiar r visualization ggplot2

tutorial - leyendas en r



Parcelas lado a lado con ggplot2 (12)

Me gustaría colocar dos parcelas lado a lado usando el paquete ggplot2 , es decir, hacer el equivalente de par(mfrow=c(1,2)) .

Por ejemplo, me gustaría que los siguientes dos gráficos se muestren lado a lado con la misma escala.

x <- rnorm(100) eps <- rnorm(100,0,.2) qplot(x,3*x+eps) qplot(x,2*x+eps)

¿Necesito ponerlos en el mismo data.frame?

qplot(displ, hwy, data=mpg, facets = . ~ year) + geom_smooth()


Cualquier ggplot lado a lado (o n parcelas en una cuadrícula)

La función grid.arrange() en el paquete gridExtra combinará múltiples gráficos; Así es como se ponen dos al lado del otro.

require(gridExtra) plot1 <- qplot(1) plot2 <- qplot(1) grid.arrange(plot1, plot2, ncol=2)

Esto es útil cuando los dos gráficos no se basan en los mismos datos, por ejemplo, si desea trazar diferentes variables sin utilizar remodelar ().

Esto trazará la salida como un efecto secundario. Para imprimir el efecto secundario en un archivo, especifique un controlador de dispositivo (como pdf , png , etc.), por ejemplo

pdf("foo.pdf") grid.arrange(plot1, plot2) dev.off()

o, use arrangeGrob() en combinación con ggsave() ,

ggsave("foo.pdf", arrangeGrob(plot1, plot2))

Esto es equivalente a hacer dos gráficos distintos usando par(mfrow = c(1,2)) . Esto no solo ahorra tiempo en la organización de los datos, sino que también es necesario cuando se desean dos gráficos diferentes.

Apéndice: Uso de las facetas

Las facetas son útiles para hacer parcelas similares para diferentes grupos. Esto se indica a continuación en muchas respuestas a continuación, pero quiero resaltar este enfoque con ejemplos equivalentes a los gráficos anteriores.

mydata <- data.frame(myGroup = c(''a'', ''b''), myX = c(1,1)) qplot(data = mydata, x = myX, facets = ~myGroup) ggplot(data = mydata) + geom_bar(aes(myX)) + facet_wrap(~myGroup)

Actualizar

La función plot_grid en el cowplot merece una grid.arrange como alternativa a grid.arrange . Vea la answer de @ claus-wilke a continuación y answer para un enfoque equivalente; pero la función permite controles más finos en la ubicación y el tamaño de la parcela, según answer .


El paquete cowplot le brinda una buena manera de hacerlo, de una manera que se adapte a la publicación.

x <- rnorm(100) eps <- rnorm(100,0,.2) A = qplot(x,3*x+eps, geom = c("point", "smooth"))+theme_gray() B = qplot(x,2*x+eps, geom = c("point", "smooth"))+theme_gray() cowplot::plot_grid(A, B, labels = c("A", "B"), align = "v")


Es posible que las soluciones anteriores no sean eficientes si desea trazar múltiples gráficos ggplot usando un bucle (por ejemplo, como se solicita aquí: Crear múltiples gráficos en ggplot con diferentes valores del eje Y usando un bucle ), que es un paso deseado para analizar lo desconocido ( o grande) conjuntos de datos (por ejemplo, cuando desea trazar los conteos de todas las variables en un conjunto de datos).

El siguiente código muestra cómo hacerlo utilizando el mencionado ''multiplot ()'', cuya fuente se encuentra aquí: http://www.cookbook-r.com/Graphs/Multiple_graphs_on_one_page_(ggplot2) :

plotAllCounts <- function (dt){ plots <- list(); for(i in 1:ncol(dt)) { strX = names(dt)[i] print(sprintf("%i: strX = %s", i, strX)) plots[[i]] <- ggplot(dt) + xlab(strX) + geom_point(aes_string(strX),stat="count") } columnsToPlot <- floor(sqrt(ncol(dt))) multiplot(plotlist = plots, cols = columnsToPlot) }

Ahora ejecute la función: para obtener los recuentos de todas las variables impresas con ggplot en una página

dt = ggplot2::diamonds plotAllCounts(dt)

Una cosa a tener en cuenta es que:
el uso de aes(get(strX)) , que normalmente usaría en bucles al trabajar con ggplot , en el código anterior en lugar de aes_string(strX) NO dibujará los gráficos deseados. En cambio, trazará la última trama muchas veces. No he descubierto por qué: puede que tenga que hacer que aes y aes_string se llaman en ggplot .

De lo contrario, espero que encuentre la función útil.


Puede usar la siguiente función de multiplicar del libro de cocina R de Winston Chang

multiplot(plot1, plot2, cols=2)

multiplot <- function(..., plotlist=NULL, cols) { require(grid) # Make a list from the ... arguments and plotlist plots <- c(list(...), plotlist) numPlots = length(plots) # Make the panel plotCols = cols # Number of columns of plots plotRows = ceiling(numPlots/plotCols) # Number of rows needed, calculated from # of cols # Set up the page grid.newpage() pushViewport(viewport(layout = grid.layout(plotRows, plotCols))) vplayout <- function(x, y) viewport(layout.pos.row = x, layout.pos.col = y) # Make each plot, in the correct location for (i in 1:numPlots) { curRow = ceiling(i/plotCols) curCol = (i-1) %% plotCols + 1 print(plots[[i]], vp = vplayout(curRow, curCol )) } }


Sí, creo que necesitas organizar tus datos adecuadamente. Una forma sería esta:

X <- data.frame(x=rep(x,2), y=c(3*x+eps, 2*x+eps), case=rep(c("first","second"), each=100)) qplot(x, y, data=X, facets = . ~ case) + geom_smooth()

Estoy seguro de que hay mejores trucos en Plyr o remodelación. Todavía no estoy realmente al día con todos estos poderosos paquetes de Hadley.


También hay un paquete multipanfigure que vale la pena mencionar. Véase también esta answer .

library(ggplot2) theme_set(theme_bw()) q1 <- ggplot(mtcars) + geom_point(aes(mpg, disp)) q2 <- ggplot(mtcars) + geom_boxplot(aes(gear, disp, group = gear)) q3 <- ggplot(mtcars) + geom_smooth(aes(disp, qsec)) q4 <- ggplot(mtcars) + geom_bar(aes(carb)) library(magrittr) library(multipanelfigure) figure1 <- multi_panel_figure(columns = 2, rows = 2, panel_label_type = "none") # show the layout figure1

figure1 %<>% fill_panel(q1, column = 1, row = 1) %<>% fill_panel(q2, column = 2, row = 1) %<>% fill_panel(q3, column = 1, row = 2) %<>% fill_panel(q4, column = 2, row = 2) figure1

# complex layout figure2 <- multi_panel_figure(columns = 3, rows = 3, panel_label_type = "upper-roman") figure2

figure2 %<>% fill_panel(q1, column = 1:2, row = 1) %<>% fill_panel(q2, column = 3, row = 1) %<>% fill_panel(q3, column = 1, row = 2) %<>% fill_panel(q4, column = 2:3, row = 2:3) figure2

Creado en 2018-07-06 por el paquete reprex (v0.2.0.9000).


Una desventaja de las soluciones basadas en grid.arrange es que hacen que sea difícil etiquetar los gráficos con letras (A, B, etc.), como lo requieren la mayoría de las revistas.

Escribí el paquete cowplot para resolver este (y algunos otros) problemas, específicamente la función plot_grid() :

library(cowplot) iris1 <- ggplot(iris, aes(x = Species, y = Sepal.Length)) + geom_boxplot() + theme_bw() iris2 <- ggplot(iris, aes(x = Sepal.Length, fill = Species)) + geom_density(alpha = 0.7) + theme_bw() + theme(legend.position = c(0.8, 0.8)) plot_grid(iris1, iris2, labels = "AUTO")

El objeto que plot_grid() devuelve es otro objeto ggplot2, y puedes guardarlo con ggsave() como de costumbre:

p <- plot_grid(iris1, iris2, labels = "AUTO") ggsave("plot.pdf", p)

Alternativamente, puede usar la función save_plot() , que es una envoltura delgada alrededor de ggsave() que facilita obtener las dimensiones correctas para los gráficos combinados, por ejemplo:

p <- plot_grid(iris1, iris2, labels = "AUTO") save_plot("plot.pdf", p, ncol = 2)

(El argumento ncol = 2 le dice a save_plot() que hay dos gráficos uno al lado del otro, y save_plot() hace que la imagen guardada tenga el doble de ancho).

Para obtener una descripción más detallada de cómo organizar las parcelas en una cuadrícula, consulte esta viñeta. También hay una viñeta que explica cómo hacer gráficos con una leyenda compartida.

Un punto frecuente de confusión es que el paquete cowplot cambia el tema ggplot2 predeterminado. El paquete se comporta de esa manera porque originalmente fue escrito para usos internos de laboratorio, y nunca usamos el tema predeterminado. Si esto causa problemas, puede utilizar uno de los siguientes tres enfoques para solucionarlos:

1. Establecer el tema manualmente para cada trama. Creo que es una buena práctica especificar siempre un tema en particular para cada trama, como hice con + theme_bw() en el ejemplo anterior. Si especifica un tema en particular, el tema predeterminado no importa.

2. Revertir el tema predeterminado a ggplot2 predeterminado. Puedes hacer esto con una línea de código:

theme_set(theme_gray())

3. Llame a las funciones cowplot sin adjuntar el paquete. Tampoco puede llamar a la library(cowplot) o require(cowplot) y, en su lugar, llamar a las funciones de cowplot:: . Por ejemplo, el ejemplo anterior que usa el tema predeterminado ggplot2 se convertiría en:

## Commented out, we don''t call this # library(cowplot) iris1 <- ggplot(iris, aes(x = Species, y = Sepal.Length)) + geom_boxplot() iris2 <- ggplot(iris, aes(x = Sepal.Length, fill = Species)) + geom_density(alpha = 0.7) + theme(legend.position = c(0.8, 0.8)) cowplot::plot_grid(iris1, iris2, labels = "AUTO")

Actualización: a partir de ggplot2 3.0.0, los gráficos se pueden etiquetar directamente, ver, por ejemplo, here.


Usando el paquete de patchwork , simplemente puede usar el operador + :

# install.packages("devtools") devtools::install_github("thomasp85/patchwork") library(ggplot2) p1 <- ggplot(mtcars) + geom_point(aes(mpg, disp)) p2 <- ggplot(mtcars) + geom_boxplot(aes(gear, disp, group = gear)) library(patchwork) p1 + p2


Usando el paquete remodelado puedes hacer algo como esto.

library(ggplot2) wide <- data.frame(x = rnorm(100), eps = rnorm(100, 0, .2)) wide$first <- with(wide, 3 * x + eps) wide$second <- with(wide, 2 * x + eps) long <- melt(wide, id.vars = c("x", "eps")) ggplot(long, aes(x = x, y = value)) + geom_smooth() + geom_point() + facet_grid(.~ variable)


Utilizando tidyverse

x <- rnorm(100) eps <- rnorm(100,0,.2) df <- data.frame(x, eps) %>% mutate(p1 = 3*x+eps, p2 = 2*x+eps) %>% tidyr::gather("plot", "value", 3:4) %>% ggplot(aes(x = x , y = value))+ geom_point()+geom_smooth()+facet_wrap(~plot, ncol =2) df


ggplot2 se basa en gráficos de cuadrícula, que proporcionan un sistema diferente para organizar los trazados en una página. El comando par(mfrow...) no tiene un equivalente directo, ya que los objetos de cuadrícula (llamados grobs ) no necesariamente se dibujan de inmediato, pero se pueden almacenar y manipular como objetos R regulares antes de convertirse en una salida gráfica. Esto permite una mayor flexibilidad que el dibujo de este modelo de gráficos base ahora , pero la estrategia es necesariamente un poco diferente.

Escribí grid.arrange() para proporcionar una interfaz simple lo más cerca posible de par(mfrow) . En su forma más simple, el código se vería así:

library(ggplot2) x <- rnorm(100) eps <- rnorm(100,0,.2) p1 <- qplot(x,3*x+eps) p2 <- qplot(x,2*x+eps) library(gridExtra) grid.arrange(p1, p2, ncol = 2)

Más opciones se detallan en esta viñeta .

Una queja común es que las parcelas no están necesariamente alineadas, por ejemplo, cuando tienen etiquetas de eje de diferente tamaño, pero esto es por diseño: grid.arrange no intenta los objetos ggplot2 en casos especiales, y los trata por igual a otros grobs (diagramas de celosía , por ejemplo). Simplemente coloca grobs en un diseño rectangular.

Para el caso especial de los objetos ggplot2, escribí otra función, ggarrange , con una interfaz similar, que intenta alinear los paneles de la trama (incluidas las parcelas facetadas) e intenta respetar las relaciones de aspecto cuando el usuario las define.

library(egg) ggarrange(p1, p2, ncol = 2)

Ambas funciones son compatibles con ggsave() . Para obtener una descripción general de las diferentes opciones y un contexto histórico, esta viñeta ofrece información adicional .


Actualización: esta respuesta es muy antigua. gridExtra::grid.arrange() es ahora el enfoque recomendado. Dejo esto aquí en caso de que pueda ser útil.

Stephen Turner publicó la función de arrange() en el blog Getting Genetics Done (ver publicación para obtener instrucciones de la aplicación)

vp.layout <- function(x, y) viewport(layout.pos.row=x, layout.pos.col=y) arrange <- function(..., nrow=NULL, ncol=NULL, as.table=FALSE) { dots <- list(...) n <- length(dots) if(is.null(nrow) & is.null(ncol)) { nrow = floor(n/2) ; ncol = ceiling(n/nrow)} if(is.null(nrow)) { nrow = ceiling(n/ncol)} if(is.null(ncol)) { ncol = ceiling(n/nrow)} ## NOTE see n2mfrow in grDevices for possible alternative grid.newpage() pushViewport(viewport(layout=grid.layout(nrow,ncol) ) ) ii.p <- 1 for(ii.row in seq(1, nrow)){ ii.table.row <- ii.row if(as.table) {ii.table.row <- nrow - ii.table.row + 1} for(ii.col in seq(1, ncol)){ ii.table <- ii.p if(ii.p > n) break print(dots[[ii.table]], vp=vp.layout(ii.table.row, ii.col)) ii.p <- ii.p + 1 } } }