在ggplot中嵌入子图(ggsubplot)

9
我想用ggplot重新创建这个基础绘图,但我想使用比这里演示的更优雅的工作流程,因为它直接依赖于grid::viewport()
使用ggsubplot,我尝试了:
require(ggplot2)
require(ggsubplot)
d = data.frame(x = sort(rlnorm(300)), y = sort(rlnorm(300)), grp = 1)
ggplot(d, aes(x, y)) + geom_point() + theme_bw() +
  scale_x_continuous(limits=c(0, 10)) + scale_y_continuous(limits=c(0, 10)) +
  geom_subplot(data=d, aes(x=5, y=1, group = grp, subplot = geom_point(aes(x, y))), width=4, height=4)

这导致了以下令人失望的结果:

enter image description here

显然还需要一些工作,但是如果将轴、标签和网格添加到子图中,它就不会差太远。你有什么办法可以做到这些吗?我找不到任何关于此的例子,而ggsubplot默认会删除这些元素。提前感谢您的帮助。


وˆ‘هœ¨ن½؟用ggplotو—¶ç»“هگˆن؛†viewport,ç”ڑ至و²،وœ‰و„ڈ识هˆ°ggsubplotçڑ„ه­کهœ¨م€‚ - Ananta
尝试在?annotation_custom中运行最后一个示例。 - baptiste
可能是是否可以创建嵌入式图形?的重复问题。 - zx8754
相关帖子:https://dev59.com/2mQn5IYBdhLWcg3wLkgd - zx8754
3个回答

15

使用笛卡尔坐标系,我会使用annotation_custom

require(ggplot2)
d = data.frame(x = sort(rlnorm(300)), y = sort(rlnorm(300)), grp = 1)

main <- ggplot(d, aes(x, y)) + geom_point() + theme_bw() 

sub <- main + geom_rect(data=d[1,],xmin=0, ymin=0, xmax=5, ymax=5, 
                        fill="blue", alpha=0.5)
sub$layers <- rev(sub$layers) # draw rect below

main + annotation_custom(ggplotGrob(sub), xmin=2.5, xmax=5, ymin=0, ymax=2.5) +
  scale_x_continuous(limits=c(0, 5)) + scale_y_continuous(limits=c(0,4))

输入图片描述


2

你可能需要调整位置和颜色等,但似乎添加 reference 可以起作用。

ggplot(d, aes(x, y)) + geom_point() + theme_bw() +
  scale_x_continuous(limits=c(0, 10)) + scale_y_continuous(limits=c(0, 10)) +
  geom_subplot(data=d, aes(x=5, y=1, group = grp, subplot = geom_point(aes(x, y))), width=4, height=4,reference=ref_box(fill = "grey90", color = "black"))

工作


谢谢Ananta。这是最接近我所请求的,因此我感到有义务授予解决方案。但是,如果您想要更专业的子图,网格解决方案似乎更优雅(鉴于ggsubplot坚持最小化子图图表元素),我认为Josh是正确的。 - geotheory
1
请注意,截至2019年,geom_subplot和ggsubplot包已经停止开发,并且不再在CRAN上提供。现在的解决方案是使用annotation_custom(),如baptiste在另一个答案中所述。 - user2711915

2

这符合你的要求吗?

编辑: 添加了@geotheory的编辑以只绘制1个geom_rect(...)

您可以使用grid软件包中的viewports实现此操作。

require(ggplot2)
set.seed(123)
d   <- data.frame(x = sort(rlnorm(300)), y = sort(rlnorm(300)), grp = 1)
ggp <- ggplot(d, aes(x, y)) + 
  geom_point() + theme_bw() +
  scale_x_continuous(limits=c(0, 5)) + 
  scale_y_continuous(limits=c(0, 5)) 

sub <- ggplot(d)+geom_point(aes(x,y))+
  theme_bw()+
# assign single row data object so only one rectangle is drawn  
  geom_rect(data=d[1,],xmin=0,ymin=0,xmax=5,ymax=5,fill="blue",alpha=0.5)

library(grid)
grid.newpage()
print(ggp)
vp <- viewport(width = .6, height = .6, x=.37, y=.06,just=c("left","bottom"))
pushViewport(vp)
print(sub,vp=vp)

1
@Ananta - 是的,他确实这样做了,但是以链接的形式提供关键信息让读者必须要点击才能获取是相当糟糕的做法。最终导致jlhoward浪费了一些时间。(顺便说一下,对我来说,使用grid成熟、表达力强的工具集来完成这个任务似乎更加优雅。) - Josh O'Brien
@JoshO'Brien,是的,我也在OP的问题中为视窗添加了评论,并在回答之前点击了链接,他可能使用了“而不是视口”来节省我们的时间。 - Ananta
1
@Ananta -- 这也浪费了我一点时间。我只是编辑了问题,使得原帖作者的请求更加清晰明了。 - Josh O'Brien
@geotheory -- 抱歉如果我的话听起来太严厉了。链接很好,而我对你的问题所做的修改基本上展示了我更喜欢看到的内容。至于其他SO问题是如何处理的,我建议你保持比这里典型的提问者要高得多的标准(就像你已经做到的那样;)。干杯。 - Josh O'Brien
点已收到!感谢您的反馈。 - geotheory
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接