首页 文章

可以创建插图吗?

提问于
浏览
16

我知道当你使用 par( fig=c( ... ), new=T ) 时,你可以创建插图 . 但是,我想知道是否可以使用ggplot2库来创建'inset'图 .

更新1:我尝试使用 par() 与ggplot2,但它不起作用 .

更新2:我在ggplot2 GoogleGroups使用 grid::viewport() 找到了一个有效的解决方案 .

4 回答

  • 23

    the book的第8.4节解释了如何执行此操作 . 诀窍是使用 grid 包的 viewport .

    #Any old plot
    a_plot <- ggplot(cars, aes(speed, dist)) + geom_line()
    
    #A viewport taking up a fraction of the plot area
    vp <- viewport(width = 0.4, height = 0.4, x = 0.8, y = 0.2)
    
    #Just draw the plot twice
    png("test.png")
    print(a_plot)
    print(a_plot, vp = vp)
    dev.off()
    
  • 2

    使用 ggplot2egg 的更简单的解决方案 . 最重要的是,此解决方案适用于 ggsave .

    library(tidyverse)
    library(egg)
    plotx <- ggplot(mpg, aes(displ, hwy)) + geom_point()
    plotx + 
      annotation_custom(
        ggplotGrob(plotx), 
        xmin = 5, xmax = 7, ymin = 30, ymax = 44
      )
    ggsave(filename = "inset-plot.png")
    
  • 2

    我更喜欢使用ggsave的解决方案 . 经过大量的谷歌搜索后,我最终得到了这个(这是一个通用的公式,用于定位和调整你插入的图 .

    library(tidyverse)
    
    plot1 = qplot(1.00*mpg, 1.00*wt, data=mtcars)  # Make sure x and y values are floating values in plot 1
    plot2 = qplot(hp, cyl, data=mtcars)
    plot(plot1)
    
    # Specify position of plot2 (in percentages of plot1)
    # This is in the top left and 25% width and 25% height
    xleft   = 0.05
    xright  = 0.30
    ybottom = 0.70
    ytop    = 0.95 
    
    # Calculate position in plot1 coordinates
    # Extract x and y values from plot1
    l1 = ggplot_build(plot1)
    x1 = l1$layout$panel_ranges[[1]]$x.range[1]
    x2 = l1$layout$panel_ranges[[1]]$x.range[2]
    y1 = l1$layout$panel_ranges[[1]]$y.range[1]
    y2 = l1$layout$panel_ranges[[1]]$y.range[2]
    xdif = x2-x1
    ydif = y2-y1
    xmin  = x1 + (xleft*xdif)
    xmax  = x1 + (xright*xdif)
    ymin  = y1 + (ybottom*ydif)
    ymax  = y1 + (ytop*ydif) 
    
    # Get plot2 and make grob
    g2 = ggplotGrob(plot2)
    plot3 = plot1 + annotation_custom(grob = g2, xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax)
    plot(plot3)
    
    ggsave(filename = "test.png", plot = plot3)
    
    # Try and make a weird combination of plots
    g1 <- ggplotGrob(plot1)
    g2 <- ggplotGrob(plot2)
    g3 <- ggplotGrob(plot3)
    
    library(gridExtra)
    library(grid)
    
    t1 = arrangeGrob(g1,ncol=1, left = textGrob("A", y = 1, vjust=1, gp=gpar(fontsize=20)))
    t2 = arrangeGrob(g2,ncol=1, left = textGrob("B", y = 1, vjust=1, gp=gpar(fontsize=20)))
    t3 = arrangeGrob(g3,ncol=1, left = textGrob("C", y = 1, vjust=1, gp=gpar(fontsize=20)))
    
    final = arrangeGrob(t1,t2,t3, layout_matrix = cbind(c(1,2), c(3,3)))
    grid.arrange(final)
    
    ggsave(filename = "test2.png", plot = final)
    

    Image showing inset and relatively complex layout

  • 12

    或者,可以使用Claus O. Wilke的cowplot R包( cowplotggplot2 的强大扩展) . 作者有一个关于在this intro vignette中绘制较大图形内插图的示例 . 这是一些改编的代码:

    library(cowplot)
    
    main.plot <- 
      ggplot(data = mpg, aes(x = cty, y = hwy, colour = factor(cyl))) + 
      geom_point(size = 2.5)
    
    inset.plot <- main.plot + theme(legend.position = "none")
    
    plot.with.inset <-
      ggdraw() +
      draw_plot(main.plot) +
      draw_plot(inset.plot, x = 0.07, y = .7, width = .3, height = .3)
    
    # Can save the plot with ggsave()
    ggsave(filename = "plot.with.inset.png", 
           plot = plot.with.inset,
           width = 17, 
           height = 12,
           units = "cm",
           dpi = 300)
    

    enter image description here

相关问题