1. 前言

本文主要介绍一下自己利用业余时间开发的分子结构3D可视化R包 {r3dmol}
{r3dmol} 基于一个老牌的 JavaScript 的3D分子结构可视化库 3Dmol.js{htmlwidgets} 开发而成。 3Dmol.js 有 Python 版本的接口,可以在 Jupyter Notebook 中使用,但是却没有 R 语言能用的版本,也就无法很方便地在 Rmarkdown 和 Shiny 中使用。 虽然也不是不能通过直接调用 JavaScript 来进行实现,但对于一般专注科研的学者来说,似乎也没有必要花额外的精力去研究一大堆 JavaScript 的写法来达到目的。
因此,我利用 3Dmol.js{htmlwidgets} 开发了 {r3dmol} 这个 R 包,以方便日常用 R 进行分析的科研人员实现在分析文档中对分子、蛋白质结构进行可视化,免去了打开 PyMOL 等软件对结构进行绘制后在通过导出图片复制粘贴到文档中的繁琐操作。

2. 适用场景

诚然,{r3dmol} 只是一个较为轻量的处于初级开发阶段的可视化包,并没有PyMOL 等专业软件这么丰富的功能,而且 3Dmol.js 本身开发时间时间较早,受其所限导致绘制的结构看起来精致度有所欠缺。 但如果你有下列需求的话,我想 {r3dmol} 应该是一个不错的选择。

  1. 使用 R 语言进行分子、蛋白质的分析(如{bio3d}),需要在结果报告中展示3D结构(来显得报告更专业);
  2. 需要在 {rmarkdown}{shiny} 或者 {blogdown} 等 R 语言生态环境中进行结构可视化;
  3. 各类生物信息课程中的教学需求;

如果是需要导出最终发表文章那类高质量结构图的话,可能用业界老朋友 PyMOL,或者干脆上 blender会显得更为专业。 不过众所周知,这二者也是有一定的学习门槛,制作上也需要花费不少时间,因此也和 {r3dmol} 定位完全没有重叠,按需使用就好。

3. 安装方法

CRAN_Status_Badge 可以直接安装 CRAN 上的版本:

install.packages("r3dmol")

由于 CRAN 上的版本更新手续较为繁琐,也不能频繁更新,因此如果你想体验最新开发版本(可能包括一些 Bug 修复等),也可以通过 Github 安装开发版:

# install.packages("devtools")
devtools::install_github("swsoyee/r3dmol")

4. 使用方法

4.1 显示结构

如果对 {ggplot2} 或者 {dplyr} 等常用包的写法不陌生的话,你会发现上手起来非常简单。 一个简单的例子,让我们先来对包中自带的 6ZSL 蛋白进行可视化:

library(r3dmol)
r3dmol() %>%
  m_add_model(data = pdb_6zsl, format = "pdb") %>%
  m_zoom_to() %>%
  m_set_style(style = m_style_cartoon(color = 'spectrum'))
  • r3dmol():初始化可视化的框架;
  • m_add_model():添加模型;
  • m_zoom_to():将模型完全缩放到正中间;
  • m_set_style():将样式设置为 Cartoon 并且颜色为 spectrum.

仅仅数行就能将一个结构显示到文档中了。

再来看一个官方文档中提供的复杂一点设置的例子:

# 设定窗口样式
r3dmol(
  viewer_spec = m_viewer_spec(
    cartoonQuality = 10, # 图形质量
    lowerZoomLimit = 50, # 缩放下限
    upperZoomLimit = 350 # 缩放上限
  )
) %>%
  # 添加模型
  m_add_model(data = pdb_6zsl, format = "pdb") %>%  
  # 模型缩放到整体
  m_zoom_to() %>%
  # 设置 Cartoon 样式,并且颜色为绿色
  m_set_style(style = m_style_cartoon(color = '#00cc96')) %>% 
  # 设置 beta-折叠为蓝紫色
  m_set_style(sel = m_sel(ss = 's'),                 
              style = m_style_cartoon(color = '#636efa', arrows = TRUE)) %>% 
  # 设置 alpha-螺旋为橙色
  m_set_style(sel = m_sel(ss = 'h'),
              style = m_style_cartoon(color = '#ff7f0e')) %>%
  # 初始角度按Y轴旋转90度
  m_rotate(angle = 90, axis = 'y') %>%
  # 旋转动画
  m_spin() 

4.2 化学分子

对于化学分子也可以使用 {r3dmol} 进行可视化。m_add_model() 对于模型只需要提供纯文本的结构文件和指定文件格式即可添加模型。 这里我们使用苯环作为示范:

benz <- "
     RDKit          3D

  6  6  0  0  0  0  0  0  0  0999 V2000
   -0.9517    0.7811   -0.6622 C   0  0  0  0  0  0  0  0  0  0  0  0
    0.2847    1.3329   -0.3121 C   0  0  0  0  0  0  0  0  0  0  0  0
    1.2365    0.5518    0.3512 C   0  0  0  0  0  0  0  0  0  0  0  0
    0.9517   -0.7811    0.6644 C   0  0  0  0  0  0  0  0  0  0  0  0
   -0.2847   -1.3329    0.3144 C   0  0  0  0  0  0  0  0  0  0  0  0
   -1.2365   -0.5518   -0.3489 C   0  0  0  0  0  0  0  0  0  0  0  0
  1  2  2  0
  2  3  1  0
  3  4  2  0
  4  5  1  0
  5  6  2  0
  6  1  1  0
M  END
$$$$"

r3dmol(id = "demo_sdf", elementId = "demo_sdf") %>%
  m_add_model(data = benz, format = "sdf") %>%
  m_set_style(style = m_style_stick()) %>%
  m_set_style(sel = m_sel(model = 0), 
              style = m_style_stick(colorScheme = "cyanCarbon")) %>%
  m_zoom_to()

4.3 利用 JavaScript 函数进行高自由度可视化

如果对 JavaScript 有所了解的话,还可以自己定制一些函数进行特殊的高自由度的可视化。 下面的这个例子使用内置的 1J72 蛋白展示了如何将处于偶数位置的设置成白色,奇数位置设置为绿色:

r3dmol() %>%
  m_add_model(data = pdb_1j72) %>%
  m_set_style(style = m_style_cartoon(
      colorfunc = "
        function(atom) {
          return atom.resi % 2 == 0 ? 'white' : 'green';
        }"
    )
  ) %>%
  m_zoom_to()

4.4 分子选择

类似 PyMol{r3dmol} 也支持对个别成员(如残基名字、残基位置、肽链、模型、元素和原子等)进行选择,使用不同的样式或者是进行标记等操作。 详细可参考函数帮助或者在线文档

下面的例子展示了选择 A 链并将头 10 个残基设置为球棍模型的写法:

r3dmol() %>%
  m_add_model(data = pdb_6zsl) %>%
  m_set_style(style = m_style_cartoon()) %>%
  m_add_style(
    style = c(
      m_style_stick(),            # 棍样式
      m_style_sphere(scale = 0.5) # 球样式
    ),
    sel = m_sel(
      resi = 1:10,                # 头1到10个残基
      chain = "A",                # A链
    )
  ) %>%
  m_zoom_to(                      # 缩放到
    sel = m_sel(
      resi = 1:10,                # 头1到10个残基                
      chain = "A"                 # A链
    )
  )

在上面这个例子中,我们在选择 的时候指定了是在A链上的头10个残基。 但如果在用 m_sel() 进行选择的时候没有指定哪一条链时,将会自动选择所有链的头10个残基,并取他们的空间中点作为选择点。 比如下面的例子中,我们在添加标签时候没有指定链,因此将会在两条链的中心点出现标签。

r3dmol() %>%
  m_add_model(data = pdb_6zsl) %>%
  m_set_style(style = m_style_cartoon()) %>%
  m_add_style(
    sel = m_sel(resi = 1:10),
    style = c(
      m_style_stick(),
      m_style_sphere(scale = 0.5)
    )
  ) %>%
  m_add_line(
    start = m_sel(
      resi = 1:10,
      chain = "A"
    ),
    end = m_sel(
      resi = 1:10,
      chain = "B"
    ),
    dashed = TRUE
  ) %>%
  m_add_label(
    text = "所选范围的空间中心",
    sel = m_sel(
      resi = 1:10 # 这里只选择了残基位置而没有指定链
    ),
    style = m_style_label(
      borderColor = "green",
      borderThickness = 1,
      inFront = FALSE
    )
  ) %>%
  m_zoom_to()

4.5 读取结构

在上面的例子中,展示的都是使用包中包含的默认结构或者直接字符串形式进行传入的。 从 0.1.1 版本开始,对于蛋白质来说,可以使用 m_fetch_pdb() 直接从 PDB 获取,或者是用 m_bio3d() 来读取 {bio3d} 中的结构数据。

直接从 PDB 获取 1BNA

r3dmol() %>% 
  m_add_model(data = m_fetch_pdb("1bna", save.pdb = FALSE)) %>% 
  m_set_style(style = m_style_cartoon()) %>% 
  m_zoom_to()

读取 {bio3d} 中的结构数据:

# install.packages("bio3d")
library(bio3d)

pdb <- read.pdb("1bna")
##   Note: Accessing on-line PDB file
r3dmol() %>%
  m_add_model(data = m_bio3d(pdb)) %>%
  m_set_style(style = m_style_cartoon()) %>%
  m_zoom_to() %>%
  m_rotate(angle = "90", axis = "x") %>%
  m_spin(axis = "z")

5. 结语

虽然开发出了这个分子结构可视化的包,但由于本人对结构生物学一窍不通,也不再是生物科研人员,自然而然不是这个包的目标用户。 因此有这方面需求的读者可以尝试一下,提出宝贵的体验反馈和改进意见。 {r3dmol} 的源码放置在 Github, 无限欢迎提交 Issue 和 PR,或是分享你的 {r3dmol} 使用体验和所绘制的成果。 如果你觉得该包有帮助到你的日常科研生活,可在 Github 上点个 Star 表示对这项工作的支持哦 :)