复现sci顶刊中的画中画(局部细节放大)
点击下方公众号,回复资料分享,收获惊喜
简介
小编在撰写学术论文时,出现以下问题:图形重叠导致看不清细节。此时,可以通过放大图形中的局部位置。
这种图在工业工程方向的顶级期刊中经常看到。本文小编将给出几种 R 中绘制局部细节放大图的方法。
注意:小编搜到过 matlab 和 Origin 绘制局部细节放大图的文章。但是很少看到有人写 R 相关的教程。
初级版本
这章节给出利用 ggplot[1] 包绘制模拟数据的线性图。下一章节将会介绍两种细节放大方法。
模拟数据产生
这里以一个模拟数据作为例子,读者可以根据自身数据情况进行替换。
# 生成模拟数据
com_battery = data.frame("Time" = 1:30,"True" = cumsum(abs(rnorm(30,2,0.4))),
"Proposed" = cumsum(abs(rnorm(30,2,0.5))),
"Linear" = cumsum(abs(rnorm(30,2,0.4))),
"Power" = cumsum(abs(rnorm(30,2,0.1))),
"Exp" = cumsum(abs(rnorm(30,2,0.3))))
基础绘图
以时间作为 x 轴,各个模型拟合/预测值作为 y 轴。绘制出不同方法的拟合/预测对比图。
library(ggplot2)
library(tidyverse)
# 基础绘图
cols <- c("black","#85BA8F", "#A3C8DC","#349839","#EA5D2D","#EABB77","#F09594")
p = com_battery %>% pivot_longer(cols = !Time, names_to = "Model", values_to = "Value") %>%
mutate(Model = factor(Model, levels = c("True", "Proposed", "Linear","Power","Exp"))) %>%
ggplot(aes(Time,Value,col = Model,shape = Model)) +
geom_line() + geom_point(size=1.5,alpha=0.8) +
scale_color_manual(values = cols) +
theme_bw() + theme(panel.grid = element_blank()) + #,legend.title=element_text(size=12), legend.text=element_text(size=11) +
xlab("Time") + ylab("Rate(%)")
可以看到,各个方法的拟合/预测结果非常接近。此时,可以通过放大局部细节来突出某个模型的优越性。
ggforce 包
ggforce[2] 包中的 facet_zoom()
可以通过一行代码实现局部细节放大的效果。官网[3]给出了各个参数的细节以及示例。
这里假设我们想对 xlim = c(18, 24),ylim = c(40, 43)
范围内的数据进行放大。只需要使用以下代码即可,其中 zoom.size = 0.4
表示放大后的图形大小占比整个图的比例。
library(ggforce)
p + facet_zoom(xlim = c(18, 24),ylim = c(40, 43), zoom.size = 0.4)
注意:当然还有其他几个参数可以调整,这里不做过多介绍。
如果你觉得这个图已经满足要求,并且美观程度还不错的话。那你就随意使用吧~但对于小编而言,这里的灰色框太奇怪了(不会改😭),而且整个构造也很突兀。
所以小编打算直接基于 ggplot 包的思想自己添加内容,并通过 patchwork[4] 包对图进行合并,复现出类似图一的效果。
patchwork 包
基于 ggplot 包,我们再绘制一幅需要局部放大的图,只需在 xlim()
和 ylim()
上做文章,并去除标签和图例。
ppp = p + xlim(5,10) + ylim(10,20) + theme(legend.position = 'none') +
xlab("") + ylab("")
之后将该图放到原图的合适位置即可,可以使用 patchwork 包中的 inset_element()
实现该功能。
注意:也可以使用cowplot[5]包进行图形合并。相关推文见:合并多幅图形、利用 cowplot 包快速对齐图片。
library(patchwork)
p + inset_element(ppp, 0.01, 0.6, 0.6, 0.95, on_top = TRUE)
此时,基本完成了我们的要求,接下来进行一些细节处理:添加选择放大位置的框,添加指向箭头,修改图例位置等(注释在代码后)。
p +
geom_rect(aes(xmin = 5, xmax = 10, ymin = 10, ymax = 20),
fill = "transparent", color = "black", alpha = 0,
linetype = "dashed", linewidth =0.2) + #添加选择放大位置的框
theme(legend.position = c(0.9,.2),legend.background = element_rect(fill = 'white', colour = 'black')) + #修改图例位置
geom_segment(aes(x = 7, xend = 10, y = 20, yend = 38.3),
col = "gray60", linewidth =0.2,linetype = "dashed",
arrow = arrow(length = unit(0.2, "cm"), type = "closed")) + # 添加指向箭头
inset_element(ppp, 0.01, 0.6, 0.6, 0.95, on_top = TRUE)
小编有话说
模拟数据绘制出的效果可能不是很好,本文主要是给出 2 种绘制局部细节的方法供大家参考。这是小编平常科研中出现的一种画图需求,防止后续还会使用类似图形,所以在这做个记录也分享给大家。
小编使用过 matlab 进行绘制这种图形,发现 matlab 可以互动式选择放大位置以及展示位置,非常方便。不知道这种功能是否可以借鉴到 R 中?
如果有更好的方法欢迎读者们评论留言。也欢迎大家一键三连~
注意:本文所有代码已经上传至 Github[6] 中,欢迎下载使用。
参考资料
ggplot: https://ggplot2.tidyverse.org/
[2]ggforce: https://ggforce.data-imaginist.com/
[3]官网: https://ggforce.data-imaginist.com/reference/facet_zoom.html
[4]patchwork: https://patchwork.data-imaginist.com/
[5]cowplot: https://cran.r-project.org/web/packages/cowplot/vignettes/introduction.html
[6]Github: https://github.com/liangliangzhuang/R_example
相关推文指南
cowplot包,ggplot2图形排版R包
使用 ggpubr 包制图
使用 ggcharts 高亮部分内容
使用 ggTimeSeries 包构建日历图
基于 ggdensity 包的等高线绘制
贝叶斯 RStan 包入门教程