可以创建插图吗?

Sam*_*Sam 21 graphics r ggplot2 insets

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

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

更新2:我发现了一个工作液在GGPLOT2 Google网上论坛使用grid::viewport().

Ric*_*ton 25

本书的第8.4节解释了如何执行此操作.诀窍是使用grid包的viewports.

#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()
Run Code Online (Sandbox Code Playgroud)

  • 值得指出的是,如果想要另一个情节作为插图,那么关键的一行就是`print(another_plot,vp = vp)`.我花了一段时间才弄明白.+1 (2认同)

pal*_*sen 13

我更喜欢使用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)
Run Code Online (Sandbox Code Playgroud)

图像显示插入和相对复杂的布局

  • 我认为他们已经更新了 ggplot 包,现在为了从 plot1 坐标中提取位置,格式应该是这样的:`l1$layout$panel_ranges[[1]]$x.range[1]`。注意`l1$layout$panel_ranges....` (2认同)

sta*_*tor 9

更简单的解决方案利用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")
Run Code Online (Sandbox Code Playgroud)

  • 嘿@stackinator.+1简洁示例并提到`egg`包.请注意,只使用`library(ggplot2)`绰绰有余(一个不需要额外的`tidyverse`或`egg`) (6认同)

and*_*har 8

2019年,patchwork包登场,您可以 使用以下函数轻松创建插图inset_element()

require(ggplot2)
require(patchwork)

gg1 = ggplot(iris, aes(Sepal.Length, Sepal.Width)) +
  geom_point()

gg2 = ggplot(iris, aes(Sepal.Length)) +
  geom_density()

gg1 +
  inset_element(gg2, left = 0.65, bottom = 0.75, right = 1, top = 1)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


Val*_*tin 7

或者,可以使用cowplotClaus O. Wilke 的R包(cowplot是的强大扩展ggplot2)。作者举了一个示例,该示例在此简介小插图中的较大图形内绘制插图。这是一些经过修改的代码:

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)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明


Ped*_*alo 7

'ggplot2' >= 3.0.0 使添加插图的新方法成为可能,因为现在tibble包含列表作为成员列的对象可以作为数据传递。列表列中的对象甚至可以是整个 ggplots...我的包 'ggpmisc' 的最新版本提供geom_plot(), geom_table()and geom_grob(), 以及使用npc单位而不是本机数据单位来定位插图的版本。这些 geoms 可以在每次调用时添加多个 insets 并遵守 faceting,但annotation_custom()事实并非如此。我从帮助页面复制了这个例子,它添加了一个插图,其中包含主图的放大细节作为插图。

图书馆(tibble)
图书馆(ggpmisc)
p<-
  ggplot(数据 = mtcars, 映射 = aes(wt, mpg)) +
  geom_point()

df <- tibble(x = 0.01, y = 0.01,
             情节 = 列表(p +
                         coord_cartesian(xlim = c(3, 4),
                                         ylim = c(13, 16)) +
                         实验室(x = NULL,y = NULL)+
                         主题_bw(10)))
p +
  expand_limits(x = 0, y = 0) +
  geom_plot_npc(data = df, aes(npcx = x, npcy = y, label = plot))

ggplot 与 ggplot 作为插图

或者从包装小插图中获取的作为插图的条形图。

图书馆(tibble)
图书馆(ggpmisc)
p <- ggplot(mpg, aes(factor(cyl), hwy, fill = factor(cyl))) +
  stat_summary(geom = "col", fun.y = mean, width = 2/3) +
  labs(x = "圆柱数", y = NULL, title = "Means") +
  scale_fill_discrete(guide = FALSE)

data.tb <- tibble(x = 7, y = 44, 
                  情节 = 列表(p +
                                theme_bw(8)))

ggplot(mpg, aes(displ, hwy, color = factor(cyl))) +
  geom_plot(data = data.tb, aes(x, y, label = plot)) +
  geom_point() +
  labs(x = "发动机排量 (l)", y = "燃油使用效率 (MPG)",
       color = "发动机气缸\n(数量)") +
  主题_bw()

在此处输入图片说明

下一个示例显示如何将不同的插图添加到分面图中的不同面板。下一个示例使用了根据世纪拆分后的相同示例数据。这个特定的数据集一旦分裂就会在其中一个插图中增加一个缺失水平的问题。由于这些图是自行构建的,因此我们需要使用手动比例尺来确保整个图的颜色和填充是一致的。对于其他数据集,这可能不需要。

library(tibble)
library(ggpmisc)
p <-
  ggplot(data = mtcars, mapping = aes(wt, mpg)) +
  geom_point()

df <- tibble(x = 0.01, y = 0.01,
             plot = list(p +
                         coord_cartesian(xlim = c(3, 4),
                                         ylim = c(13, 16)) +
                         labs(x = NULL, y = NULL) +
                         theme_bw(10)))
p +
  expand_limits(x = 0, y = 0) +
  geom_plot_npc(data = df, aes(npcx = x, npcy = y, label = plot))

在此处输入图片说明