ggplot在两个不同比例的图中右上方添加图像

时间:2017-01-29 08:33:59

标签: r ggplot2

我想在右上方的两个ggplots中添加一个图像。我的问题是尺度不同,这就是我必须为每个情节单独指定xminxmax ...的原因:

library(ggplot2)
library(png)
library(grid)

# subsetting
am0 <- subset(mtcars, am == 0)
am1 <- subset(mtcars, am == 1)

# ggplot
plt <- function(dat){
    p <- ggplot(dat, aes(mpg,disp)) + 
      geom_point()

    return(p)
}

p0 <- plt(am0)
p1 <- plt(am1)

# reading image
img <- readPNG(system.file("img", "Rlogo.png", package = "png"))

# adding image
p0 + annotation_custom(rasterGrob(img), xmin = 20, xmax = 25, ymin = 400, ymax = 450)
p1 + annotation_custom(rasterGrob(img), xmin = 30, xmax = 35, ymin = 300, ymax = 350)

导致以下结果: enter image description here

我的问题是:有没有办法添加图像,使图像的大小和位置保持不变,而不依赖于图的比例? 看起来像这样: enter image description here

1 个答案:

答案 0 :(得分:2)

我们可以自动指定位置和比例的过程,这样您就不需要手动更改位置,如下例所示:

get.xy <- function(p) {
  g_data <- ggplot_build(p)
  data.frame(xmax = max(g_data$data[[1]]$x),
             ymax = max(g_data$data[[1]]$y),
             xmin = min(g_data$data[[1]]$x),
             ymin = min(g_data$data[[1]]$y))
}

# this returns the dataframe with required x, y params for annotation_custom,
# ensuring the size and position of the image constant
get.params.df <- function(p0, p1, width, height) {
  df0 <- cbind.data.frame(get.xy(p0), width=width, height=height)
  df1 <- cbind.data.frame(get.xy(p1))
  df1$width <- df0$width*(df1$xmax-df1$xmin)/(df0$xmax-df0$xmin)
  df1$height <- df0$height*(df1$ymax-df1$ymin)/(df0$ymax-df0$ymin)
  df <- rbind(df0, df1)
  return(data.frame(xmin=df$xmax-df$width, xmax=df$xmax+df$width, ymin=df$ymax-df$height, ymax=df$ymax+df$height))
}

p0 <- plt(am0)
p1 <- plt(am1)

df <- get.params.df(p0, p1, width=10, height=10)

# adding image
library(gridExtra)
grid.arrange(
  p0 + annotation_custom(rasterGrob(img), xmin=df[1,1],xmax=df[1,2], ymin=df[1,3], ymax=df[1,4]),
  p1 + annotation_custom(rasterGrob(img), xmin=df[2,1],xmax=df[2,2], ymin=df[2,3], ymax=df[2,4])  
)

enter image description here

如果你想要更大的图像只改变宽度高度参数,其他一切都保持不变。

df <- get.params.df(p0, p1, width=25, height=25)
library(gridExtra)
grid.arrange(
  p0 + annotation_custom(rasterGrob(img), xmin=df[1,1],xmax=df[1,2], ymin=df[1,3], ymax=df[1,4]),
  p1 + annotation_custom(rasterGrob(img), xmin=df[2,1],xmax=df[2,2], ymin=df[2,3], ymax=df[2,4])  
)

enter image description here