复现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 中,欢迎下载使用。

相关推荐
IT_陈寒20 分钟前
Python 3.12性能优化实战:5个让你的代码提速30%的新特性
前端·人工智能·后端
赛博切图仔21 分钟前
「从零到一」我用 Node BFF 手撸一个 Vue3 SSR 项目(附源码)
前端·javascript·vue.js
爱写程序的小高21 分钟前
npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree
前端·npm·node.js
loonggg21 分钟前
竖屏,其实是程序员的一个集体误解
前端·后端·程序员
程序员爱钓鱼31 分钟前
Node.js 编程实战:测试与调试 - 单元测试与集成测试
前端·后端·node.js
码界奇点38 分钟前
基于Vue.js与Element UI的后台管理系统设计与实现
前端·vue.js·ui·毕业设计·源代码管理
时光少年44 分钟前
Android KeyEvent传递与焦点拦截
前端
踢球的打工仔1 小时前
typescript-引用和const常量
前端·javascript·typescript
OEC小胖胖1 小时前
03|从 `ensureRootIsScheduled` 到 `commitRoot`:React 工作循环(WorkLoop)全景
前端·react.js·前端框架
时光少年1 小时前
ExoPlayer MediaCodec视频解码Buffer模式GPU渲染加速
前端