复现sci顶刊中的画中画(局部细节放大)

简介

小编在撰写学术论文时,为了突出所提模型的优越性,你可以通过放大图形中的局部位置来进行比较。尽管从全局来看,各个方法的拟合效果都还不错,但通过放大图中的特定区域,可以更清楚地展示所提模型相对于其他模型的优势。

例如,你可以选择在图中放大一个具有显著差异的区域,或者突出显示所提模型在某个关键阶段的表现。通过这种方式,读者能够更加直观地观察所提模型的预测趋势,并对其在特定情况下的优越性有更深刻的理解(如上图)。这样的展示方式将有助于更全面地展示所提模型的独特优势,提高论文的可读性和说服力。

这种图在工业工程方向的顶级期刊中经常看到。本文小编将给出几种 R 中绘制局部细节放大图的方法。

注意:小编搜到过 matlab 和 Origin 绘制局部细节放大图的文章。但是很少看到有人写 R 相关的教程。

初级版本

这章节给出利用 ggplot 包绘制模拟数据的线性图。下一章节将会介绍两种细节放大方法。

模拟数据产生

这里以一个模拟数据作为例子,读者可以根据自身数据情况进行替换。

r 复制代码
# 生成模拟数据
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 轴。绘制出不同方法的拟合/预测对比图。

r 复制代码
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 包中的 facet_zoom() 可以通过一行代码实现局部细节放大的效果。官网给出了各个参数的细节以及示例。

这里假设我们想对 xlim = c(18, 24),ylim = c(40, 43) 范围内的数据进行放大。只需要使用以下代码即可,其中 zoom.size = 0.4表示放大后的图形大小占比整个图的比例。

r 复制代码
library(ggforce) 
p + facet_zoom(xlim = c(18, 24),ylim = c(40, 43), zoom.size = 0.4)

注意:当然还有其他几个参数可以调整,这里不做过多介绍。

如果你觉得这个图已经满足要求,并且美观程度还不错的话。那你就随意使用吧~但对于小编而言,这里的灰色框太奇怪了(不会改😭),而且整个构造也很突兀。

所以小编打算直接基于 ggplot 包的思想自己添加内容,并通过 patchwork 包对图进行合并,复现出类似图一的效果。

patchwork 包

基于 ggplot 包,我们再绘制一幅需要局部放大的图,只需在 xlim()ylim() 上做文章,并去除标签和图例。

r 复制代码
ppp = p + xlim(5,10) + ylim(10,20) + theme(legend.position = 'none') +
  xlab("") + ylab("")

之后将该图放到原图的合适位置即可,可以使用 patchwork 包中的 inset_element() 实现该功能。

注意 :也可以使用cowplot包进行图形合并。相关推文见:合并多幅图形利用 cowplot 包快速对齐图片

r 复制代码
library(patchwork)
p + inset_element(ppp, 0.01, 0.6, 0.6, 0.95, on_top = TRUE)

此时,基本完成了我们的要求,接下来进行一些细节处理:添加选择放大位置的框,添加指向箭头,修改图例位置等(注释在代码后)。

r 复制代码
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 中,欢迎下载使用。

相关推荐
diygwcom7 分钟前
electron-updater实现electron全量版本更新
前端·javascript·electron
Hello-Mr.Wang23 分钟前
vue3中开发引导页的方法
开发语言·前端·javascript
程序员凡尘1 小时前
完美解决 Array 方法 (map/filter/reduce) 不按预期工作 的正确解决方法,亲测有效!!!
前端·javascript·vue.js
编程零零七4 小时前
Python数据分析工具(三):pymssql的用法
开发语言·前端·数据库·python·oracle·数据分析·pymssql
(⊙o⊙)~哦6 小时前
JavaScript substring() 方法
前端
无心使然云中漫步7 小时前
GIS OGC之WMTS地图服务,通过Capabilities XML描述文档,获取matrixIds,origin,计算resolutions
前端·javascript
Bug缔造者7 小时前
Element-ui el-table 全局表格排序
前端·javascript·vue.js
xnian_7 小时前
解决ruoyi-vue-pro-master框架引入报错,启动报错问题
前端·javascript·vue.js
麒麟而非淇淋8 小时前
AJAX 入门 day1
前端·javascript·ajax
2401_858120538 小时前
深入理解MATLAB中的事件处理机制
前端·javascript·matlab