学习SCI论文绘制技巧(A)

本文详细介绍了如何使用R语言中的ggplot2、cowplot等包,通过导入图片、设置自定义主题、添加文字与箭头,实现了一幅包含照片和解释性元素的科学出版图。通过一步步代码解析,读者可以学习到关键技巧如并排展示图形、统一主题和几何元素的运用。
摘要由CSDN通过智能技术生成

简介

在查阅文献的过程中,看到了几幅非常不错的出版图,今天就跟着小编一起学习下,他们是怎么使用 R 绘制出来的。

今天主要介绍第一幅图(A),初步观察来看,改图是由两张照片合并而成,并且在上面加上了箭头、圆圈,来说明作者想表达的问题。

后面几幅图会一一介绍,读者在学习过程中,可以将内部学到的知识点应用到自己的图形绘制中。

那我们来看看,他是怎么实现这个功能的吧,对应代码可在 [GitHub](GitHub - marco-meer/scifig_plot_examples_R: Scientific
publication figure plotting examples with R
) 可以找到。

主要知识点

  • 学会如何导入图形,并将其并排展示;
  • 学会设置自定义主题,简化代码,统一主题,方便绘制其他图形使用;
  • 学会使用 ggplot2 包内置参数添加文字已经其他其他修饰图标。

绘图

加载包

首先加载一些需要使用到的包。

library(ggplot2) # Grammar of graphics
library(cowplot) # Arranging multiple plots into a grid
library(png)     # Load JPEG, PNG and TIFF format 
library(scales)  # Generic plot scaling methods
library(viridis) # Default color maps from 'matplotlib'
library(grid)    # A rewrite of the graphics layout capabilities
library(magick)  # graphics and image processing
library(rsvg)    # Render svg image into a high quality bitmap
library(ggforce) # Collection of additional ggplot stats + geoms

设置主题

接下来,为了方便起见,作者在绘图前设置好了主题,并将该函数命名为 my_theme

这个主题并没有在第一幅图中使用,但是在后面几幅图中都会使用,这里先将其展示下。使用方式会在下一篇推文中进行介绍。

手动修改大部分面板,具体可以参考本篇文章。或者观看我在 B 站发布的《R 语言可视化教程》,里面也有一些简单主题设置介绍。

# 全局字体大小
base_size = 12 

# 手动修改大部分面板
# documentation: https://ggplot2.tidyverse.org/reference/theme.html
my_theme <-  function() {
  theme(
    aspect.ratio = 1,
    axis.line =element_line(colour = "black"),  
    
    # shift axis text closer to axis bc ticks are facing inwards
    axis.text.x = element_text(size = base_size*0.8, color = "black", 
                               lineheight = 0.9,
                               margin=unit(c(0.3,0.3,0.3,0.3), "cm")), 
    axis.text.y = element_text(size = base_size*0.8, color = "black", 
                               lineheight = 0.9,
                               margin=unit(c(0.3,0.3,0.3,0.3), "cm")),  
    
    axis.ticks = element_line(color = "black", size  =  0.2),  
    axis.title.x = element_text(size = base_size, 
                                color = "black", 
                                margin = margin(t = -5)), 
    # t (top), r (right), b (bottom), l (left)
    axis.title.y = element_text(size = base_size, 
                                color = "black", angle = 90,
                                margin = margin(r = -5)),  
    axis.ticks.length = unit(-0.3, "lines"),  
    legend.background = element_rect(color = NA, 
                                     fill = NA), 
    legend.key = element_rect(color = "black",  
                              fill = "white"),  
    legend.key.size = unit(0.5, "lines"),  
    legend.key.height = NULL,  
    legend.key.width = NULL,      
    legend.text = element_text(size = 0.6*base_size, 
                               color = "black"),  
    legend.title = element_text(size = 0.6*base_size, 
                                face = "bold", 
                                hjust = 0, 
                                color = "black"),  
    legend.text.align = NULL,  
    legend.title.align = NULL,  
    legend.direction = "vertical",  
    legend.box = NULL, 
    panel.background = element_rect(fill = "white", 
                                    color  =  NA),  
    panel.grid.major = element_blank(),
    panel.grid.minor = element_blank(),
    plot.title = element_text(size = base_size, 
                              color = "black"), 
  ) 
}

绘图步骤详解

由于代码复杂,知识点较多,为了读者更好理解代码逻辑和含义,小编将其分布讲解。最后再将完整代码放到本节末。

导入图片

首先使用 magick 包中的 image_read() 导入两幅图,并通过image_flip()进行转化。

img1 <- magick::image_flip(magick::image_read("./image1.jpg"))
img2 <-  magick::image_flip(magick::image_read("./image2.png"))

接下来,将两幅图并行合并,放置到一幅图中。这里的代码,小编也是第一次见。通过 grid 包中的 grid.raster() 设置光栅(raster)对象,并使用 annotation_custom()设置摆放位置。这时候得到的结果是

ggplot() +
  annotation_custom(rasterGrob(image =  img1, 
                               x=0.27,
                               y=0.49,
                               width = unit(0.45,"npc"),
                               height = unit(0.87,"npc")), 
                    -Inf, Inf, -Inf, Inf) +
  annotation_custom(rasterGrob(image = img2, 
                               x=0.73,
                               y=0.49,
                               width = unit(0.45,"npc"),
                               height = unit(0.87,"npc")), 
                    -Inf, Inf, -Inf, Inf) 

其他修饰图标

加入修饰图标,来说明问题。主要使用 geom_ellipse() 构建椭圆形,geom_segment() 增加线段(箭头设置,在内部参数 arrow 中)。

geom_ellipse(aes(x0 = 0.25, 
                 y0 = 0.3,
                 a = 0.1, 
                 b = 0.04, 
                 angle = 0),
              color="yellow",
              size=1) +
  scale_x_continuous(limits = c(0,1))+ # 设置 x 轴坐标范围
  scale_y_continuous(limits=c(0,1)) +
  geom_segment(aes(x=0.15,
                   xend=0.2,
                   y=0.75,
                   yend=0.7),
               arrow = arrow(length=unit(0.30,"cm"),
                             ends="last", 
                             type = "closed"),
               size = 1,
               color="white") +
  geom_segment(aes(x=0.3,
                   xend=0.9,
                   y=0.7,
                   yend=0.7),
               arrow = arrow(length=unit(0.30,"cm"),
                             ends="both", 
                             type = "closed"),
               size = 1,
               color="red") 

添加文字

使用 annotate() 添加文字("text"),使用 geom_segment() 添加线段(右下角白色的线段),这里没有设置箭头。

annotate("text", x = 0.25, y = 0.5, label = "PNG",color="white") +
  annotate("text", x = 0.75, y = 0.5, label = "JPEG",color="white") +
  annotate("text", x = 0.25, y = 1, label = "image 1",color="black") +
  annotate("text", x = 0.75, y = 1, label = "image 2",color="black") +
  annotate("text", x = 0.39, y = 0.07, label = "20~mu*m",color="white",parse=T) +
  annotate("text", x = 0.89, y = 0.07, label = "20~mu*m",color="white",parse=T) +
  geom_segment(aes(x=0.33,xend=0.45,y=0.03,yend=0.03), size = 2,color="white") +
  geom_segment(aes(x=0.83,xend=0.95,y=0.03,yend=0.03),size = 2,color="white") 

这时候得到的结果为:

微调主题

去除主题,并修改图形边界。

  theme_void() +# blank plot w/o axes etc.
  theme(plot.margin = unit(c(-0,0,1,0), "cm"),
        aspect.ratio = 1)

完整代码

library(ggplot2) # Grammar of graphics
library(cowplot) # Arranging multiple plots into a grid
library(png)     # Load JPEG, PNG and TIFF format 
library(scales)  # Generic plot scaling methods
library(viridis) # Default color maps from 'matplotlib'
library(grid)    # A rewrite of the graphics layout capabilities
library(magick)  # graphics and image processing
library(rsvg)    # Render svg image into a high quality bitmap
library(ggforce) # Collection of additional ggplot stats + geoms

# global font size
base_size = 12 

# Manual theme for most panels
# documentation: https://ggplot2.tidyverse.org/reference/theme.html
my_theme <-  function() {
  theme(
    aspect.ratio = 1,
    axis.line =element_line(colour = "black"),  
    
    # shift axis text closer to axis bc ticks are facing inwards
    axis.text.x = element_text(size = base_size*0.8, color = "black", 
                               lineheight = 0.9,
                               margin=unit(c(0.3,0.3,0.3,0.3), "cm")), 
    axis.text.y = element_text(size = base_size*0.8, color = "black", 
                               lineheight = 0.9,
                               margin=unit(c(0.3,0.3,0.3,0.3), "cm")),  
    
    axis.ticks = element_line(color = "black", size  =  0.2),  
    axis.title.x = element_text(size = base_size, 
                                color = "black", 
                                margin = margin(t = -5)), 
    # t (top), r (right), b (bottom), l (left)
    axis.title.y = element_text(size = base_size, 
                                color = "black", angle = 90,
                                margin = margin(r = -5)),  
    axis.ticks.length = unit(-0.3, "lines"),  
    legend.background = element_rect(color = NA, 
                                     fill = NA), 
    legend.key = element_rect(color = "black",  
                              fill = "white"),  
    legend.key.size = unit(0.5, "lines"),  
    legend.key.height =NULL,  
    legend.key.width = NULL,      
    legend.text = element_text(size = 0.6*base_size, 
                               color = "black"),  
    legend.title = element_text(size = 0.6*base_size, 
                                face = "bold", 
                                hjust = 0, 
                                color = "black"),  
    legend.text.align = NULL,  
    legend.title.align = NULL,  
    legend.direction = "vertical",  
    legend.box = NULL, 
    panel.background = element_rect(fill = "white", 
                                    color  =  NA),  
    panel.grid.major = element_blank(),
    panel.grid.minor = element_blank(),
    plot.title = element_text(size = base_size, 
                              color = "black"), 
  ) 
  
  
}

# Panel A ----

img1 <- magick::image_flip(magick::image_read("./image1.jpg"))
img2 <-  magick::image_flip(magick::image_read("./image2.png"))

panel_A <- ggplot() +
  annotation_custom(rasterGrob(image =  img1, 
                               x=0.27,
                               y=0.49,
                               width = unit(0.45,"npc"),
                               height = unit(0.87,"npc")), 
                    -Inf, Inf, -Inf, Inf) +
  annotation_custom(rasterGrob(image = img2, 
                               x=0.73,
                               y=0.49,
                               width = unit(0.45,"npc"),
                               height = unit(0.87,"npc")), 
                    -Inf, Inf, -Inf, Inf) +
  
  geom_ellipse(aes(x0 = 0.25, 
                            y0 = 0.3,
                            a = 0.1, 
                            b = 0.04, 
                            angle = 0),
                        color="yellow",
                        size=1)+
  scale_x_continuous(limits = c(0,1))+
  scale_y_continuous(limits=c(0,1)) +
  geom_segment(aes(x=0.15,
                   xend=0.2,
                   y=0.75,
                   yend=0.7),
               arrow = arrow(length=unit(0.30,"cm"),
                             ends="last", 
                             type = "closed"),
               size = 1,
               color="white") +
  geom_segment(aes(x=0.3,
                   xend=0.9,
                   y=0.7,
                   yend=0.7),
               arrow = arrow(length=unit(0.30,"cm"),
                             ends="both", 
                             type = "closed"),
               size = 1,
               color="red") +

  annotate("text", x = 0.25, y = 0.5, label = "PNG",color="white") +
  annotate("text", x = 0.75, y = 0.5, label = "JPEG",color="white") +
  annotate("text", x = 0.25, y = 1, label = "image 1",color="black") +
  annotate("text", x = 0.75, y = 1, label = "image 2",color="black") +
  annotate("text", x = 0.39, y = 0.07, label = "20~mu*m",color="white",parse=T) +
  annotate("text", x = 0.89, y = 0.07, label = "20~mu*m",color="white",parse=T) +
  geom_segment(aes(x=0.33,xend=0.45,y=0.03,yend=0.03), size = 2,color="white") +
  geom_segment(aes(x=0.83,xend=0.95,y=0.03,yend=0.03),size = 2,color="white")  + 
  theme_void() +# blank plot w/o axes etc.
  theme(plot.margin = unit(c(-0,0,1,0), "cm"),
        aspect.ratio = 1)

panel_A

小编有话说

本文主要学到的知识点如下:

  1. 使用 magick 包中的 image_read() 导入两幅图,并通过image_flip()进行转化;

  2. 设置自定义主题 my_theme,方便绘制其他图形使用;

  3. 使用 annotate() 添加文字("text"),使用 geom_segment() 添加线段。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值