superponer - Guardar la trama con una relación de aspecto dada
superponer graficas en r ggplot (5)
Basándome en la respuesta de Baptiste, eliminé su código para devolver la relación de aspecto sugerida por la geotoría. Esto fue mucho más conveniente para mí, porque quería un ancho o una altura fijos y también pasé todo a través de una función de envoltura existente que también agrega fuentes a mi pdf.
Ah, y si usaste facetas necesitas tenerlas en cuenta manualmente. Divide por filas y multiplica por columnas. No estoy seguro de si hay una mejor manera .....
ggGetAr <- function(p, default.ar=-1){
gb <- ggplot_build(p)
# first check if theme sets an aspect ratio
ar <- gb$plot$coordinates$ratio
# second possibility: aspect ratio is set by the coordinates, which results in
# the use of ''null'' units for the gtable layout. let''s find out
g <- ggplot_gtable(gb)
nullw <- sapply(g$widths, attr, "unit")
nullh <- sapply(g$heights, attr, "unit")
# ugly hack to extract the aspect ratio from these weird units
if(any(nullw == "null"))
ar <- unlist(g$widths[nullw == "null"]) / unlist(g$heights[nullh == "null"])
if(is.null(ar)) # if the aspect ratio wasn''t specified by the plot
ar <- default.ar
ar[1]
}
Estoy trabajando con la biblioteca realmente impresionante ggplot2. Descubrí cómo establecer la relación de aspecto de un gráfico utilizando coord_fixed
. Ahora, me gustaría guardar el gráfico en un PDF con un ancho específico (por ejemplo, 10 cm) y dejar que se calcule la altura requerida. No me di cuenta de cómo lograr esto. ¿Es esto posible?
No estoy seguro, pero es algo como esto lo que buscas?
ggplot(data.frame(x = seq(10), y = seq(10)), aes(x = x, y = y)) +
geom_point() +
coord_equal() +
theme(aspect.ratio = 1)
Esto me parece bien:
ggsave("test.pdf", width = 4, height = 4)
Demasiado espacio en blanco, pero el gráfico en sí tiene una relación de aspecto 1:
ggsave("test2.pdf", width = 4)
Mensaje: Guardando 4 x 6.93 en imagen
Puede usar las funciones de cuadrícula para calcular el tamaño completo del ggplot grob, pero hay ( edite: al menos) dos advertencias:
Se abrirá una ventana de dispositivo adicional, para hacer la conversión de la unidad.
el tamaño del panel de trazado será 0 de manera predeterminada, ya que está destinado a calcularse sobre la marcha de acuerdo con el dispositivo (ventana gráfica) en el que vive, no a la inversa.
Dicho esto, la siguiente función intenta abrir un dispositivo que se ajuste exactamente al ggplot,
library(ggplot2)
library(grid)
sizeit <- function(p, panel.size = 2, default.ar=1){
gb <- ggplot_build(p)
# first check if theme sets an aspect ratio
ar <- gb$plot$coordinates$ratio
# second possibility: aspect ratio is set by the coordinates, which results in
# the use of ''null'' units for the gtable layout. let''s find out
g <- ggplot_gtable(gb)
nullw <- sapply(g$widths, attr, "unit")
nullh <- sapply(g$heights, attr, "unit")
# ugly hack to extract the aspect ratio from these weird units
if(any(nullw == "null"))
ar <- unlist(g$widths[nullw == "null"]) / unlist(g$heights[nullh == "null"])
if(is.null(ar)) # if the aspect ratio wasn''t specified by the plot
ar <- default.ar
# ensure that panel.size is always the larger dimension
if(ar <= 1 ) panel.size <- panel.size / ar
g$fullwidth <- convertWidth(sum(g$widths), "in", valueOnly=TRUE) +
panel.size
g$fullheight <- convertHeight(sum(g$heights), "in", valueOnly=TRUE) +
panel.size / ar
class(g) <- c("sizedgrob", class(g))
g
}
print.sizedgrob <- function(x){
# note: dev.new doesn''t seem to respect those parameters
# when called from Rstudio; in this case it
# may be replaced by x11 or quartz or ...
dev.new(width=x$fullwidth, height=x$fullheight)
grid.draw(x)
}
p1 <- ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point() + coord_fixed() +
theme(plot.background = element_rect(colour = "red"))
p2 <- p1 + aes(x = mpg, y = wt)
# need for an explicit dummy device open, otherwise it''s a bit off
# for no apparent reason that I can understand
dev.new()
sizeit(p1, 0.1)
sizeit(p2, 2)
Si usa ggsave
, simplemente puede especificar el ancho y la altura del dispositivo de gráficos. Si especifica la relación de aspecto de la gráfica en sí, también es bueno tener esta relación de aspecto (aproximadamente) en su dispositivo gráfico. La unidad de height
y width
al guardar pdf
es pulgadas:
ggplot(...) # make a plot here
ggsave("plot.pdf", width = 10)
Ahora solo hay que transformar los 10 cm en pulgadas. Además, la height
no está forzada a una determinada relación de aspecto si no la especifica. Si desea una relación de aspecto de 16: 9, puede calcular fácilmente la altura en función del ancho:
ggplot(...) # make plot
width = 10
height = (9/16) * width
ggsave("plot.pdf", width = width, height = height)
Podría envolver esto en una función si realmente quiere.
editar: el punto crucial es sincronizar la relación de aspecto del gráfico (a través de coord_fixed()
) y la relación de aspecto del dispositivo gráfico. Por ejemplo
library(ggplot2)
ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point() + coord_fixed()
ggsave("plt.png", width = 7, height = 7)
conduce a un montón de espacio en blanco. Si bien la siguiente llamada ggsave
, que tiene un ajuste mucho mejor en la relación de aspecto, no tiene esta cantidad de espacio en blanco (perdón por la imagen grande, no se pudo establecer el tamaño máximo :)):
ggsave("plt.png", width = 2, height = 7)
Una solución más simplista sería guardar la gráfica con los márgenes predeterminados y recortar el png resultante con ImageMagick .
require(ggplot2)
require(dplyr)
ggplot(iris, aes(Sepal.Length, Sepal.Width)) + geom_point() + coord_fixed(0.3)
ggsave("untrimmed.png")
system("convert untrimmed.png -trim -bordercolor white -border 20 reframed.png")
Para asegurarse de que el recorte será diferente dependiendo del dispositivo de salida utilizado. Por ejemplo, en el caso de pdf, puede utilizar pdfcrop como se describe here .