読者です 読者をやめる 読者になる 読者になる

ggsave をいじって viewport で layout したファイルを保存してみよう

R ggplot2

論文風な Kaplan-Meier plot を書いてみよう で試してみましたが、grid package の viewport を使うと、柔軟な感じにレイアウトを決めることができました。
普通に png や pdf でファイルを保存することもできますが、ggplot2 pacakge の ggsave が便利なので、流用できればなぁと思って試してみました。

df <- data.frame(x=rnorm(10), y=rnorm(10))
plot1 <- ggplot(data=df, aes(x=x, y=y)) + geom_point()
grid.newpage()
pushViewport(viewport(layout = grid.layout(2, 2)))
print(plot1, vp=viewport(layout.pos.row=1, layout.pos.col=1))
print(plot1, vp=viewport(layout.pos.row=1, layout.pos.col=2))
print(plot1, vp=viewport(layout.pos.row=2, layout.pos.col=1))
print(plot1, vp=viewport(layout.pos.row=2, layout.pos.col=2))
grid.gedit("text", gp=gpar(fontfamily="serif"))
kmg2.plot0 <- recordPlot()
kmg2.ggsave("save.png", plot = kmg2.plot0)
`kmg2.ggsave` <- function (filename = default_name(plot), plot = last_plot(), 
    device = default_device(filename), path = NULL, scale = 1, 
    width = par("din")[1], height = par("din")[2], dpi = 300, 
    keep = plot$options$keep, drop = plot$options$drop, ...) 
{
  # original
  # if (!inherits(plot, "ggplot"))
  #     stop("plot should be a ggplot2 plot")
    if (!inherits(plot, "recordedplot")) 
        stop("plot should be a recordedplot")
    eps <- ps <- function(..., width, height) grDevices::postscript(..., 
        width = width, height = height, onefile = FALSE, horizontal = FALSE, 
        paper = "special")
    tex <- function(..., width, height) grDevices::pictex(..., 
        width = width, height = height)
    pdf <- function(..., version = "1.4") grDevices::pdf(..., 
        version = version)
    svg <- function(...) grDevices::svg(...)
    wmf <- function(..., width, height) grDevices::win.metafile(..., 
        width = width, height = height)
    png <- function(..., width, height) grDevices::png(..., width = width, 
        height = height, res = dpi, units = "in")
    jpg <- jpeg <- function(..., width, height) grDevices::jpeg(..., 
        width = width, height = height, res = dpi, units = "in")
    bmp <- function(..., width, height) grDevices::bmp(..., width = width, 
        height = height, res = dpi, units = "in")
    tiff <- function(..., width, height) grDevices::tiff(..., 
        width = width, height = height, res = dpi, units = "in")
    default_name <- function(plot) {
        paste(digest.ggplot(plot), ".pdf", sep = "")
    }
    default_device <- function(filename) {
        pieces <- strsplit(filename, "\\.")[[1]]
        ext <- tolower(pieces[length(pieces)])
        match.fun(ext)
    }
    if (missing(width) || missing(height)) {
        message("Saving ", prettyNum(width * scale, digits = 3), 
            "\" x ", prettyNum(height * scale, digits = 3), "\" image")
    }
    width <- width * scale
    height <- height * scale
    if (!is.null(path)) {
        filename <- file.path(path, filename)
    }
    device(file = filename, width = width, height = height, ...)
    on.exit(capture.output(dev.off()))
    print(plot, keep = keep, drop = drop)
    invisible()
}