how to fit the plot over a background image in R and ggplot2

帅比萌擦擦* 提交于 2019-12-03 15:32:58

You can set width and height arguments in rasterGrob both equal to 1 "npc", which will force the image to fill the plot area. Then specify the height and width of the image when you save it to get the aspect ratio you desire. Theme and scale_y_reverse options can be used to control the appearance of the axes as demonstrated also below. note that we can also use the expand parameter to ensure that the axes do not extend further than the image or data.

g <- rasterGrob(img, width=unit(1,"npc"), height=unit(1,"npc"), interpolate = FALSE)

g_ct <- ggplot(data=df_ct) +
  annotation_custom(g, -Inf, Inf, -Inf, Inf) +
  geom_path(aes_string(x=df_ct$X1, y=df_ct$X0), color='red', size=1) +
  scale_y_reverse("", 
                  labels = c(min(df_ct$X0), rep("", length(seq(min(df_ct$X0), max(df_ct$X0), 5))-2),max(df_ct$X0)), 
                  breaks = seq(min(df_ct$X0), max(df_ct$X0), 5),
                  expand = c(0,0)) +
  theme(plot.margin = unit(c(5,5,5,5), "mm"),
        axis.line.x = element_blank(),
        axis.ticks.x = element_blank(),
        axis.text.x = element_blank(),
        axis.line.y = element_blank(),
        axis.ticks.y = element_line(size = 1),
        axis.ticks.length = unit(5,'mm')) +
  scale_x_continuous("")
g_ct

ggsave('test.png', height=5, width = 2, units = 'in')

Some data:

df_ct <- data.frame(X0 = 0:100)
df_ct$X1 = sin(df_ct$X0) +rnorm(101)

and a background image:

https://i.stack.imgur.com/aEG7I.jpg

Addition to the answer by @dww.
If you need to overlay (or rather 'under'lay) the image exactly over data points then instead of annotation_custom(g, -Inf, Inf, -Inf, Inf)
use
annotation_custom(g, minX, maxX, minY, maxY)
with minX..maxY being the bottom left to top right corner of where the image corners lay on your data.

You can then also freely zoom your data with xlim(), ylim() without loosing the image-data position relationship.

example (download of image per this SO question)

download.file("https://upload.wikimedia.org/wikipedia/commons/b/b9/Sinusoidal_projection_SW.jpg",
              destfile="tmp.jpg", mode="wb")
world_image <- jpeg::readJPEG("tmp.jpg")
ggplot(FileWellsUsed, aes(y=Decimal.Latitude))   +
     annotation_custom(rasterGrob(world_image, 
                                  width = unit(1,"npc"), 
                                  height = unit(1,"npc")), 
                       -180, 180, -90, 90)+
       ggtitle("Sinusoidal projection") + 
       xlim(c(-180,180)) +ylim(c(-60,75))+
       coord_fixed() +
       ...yourdata.....

Also see this question, which uses rasterGrid instead of rasterGrob.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!