基于 aardio + R 的环形热图绘图工具
本文将介绍如何利用 aardio 开发图形界面,调用 R 语言强大的 circlize 包,构建一个专属的环形热图绘图工具。

一、 为什么选择环形热图?
在转录组测序分析中,我们经常需要展示几十个样本、数百个差异表达基因的表达模式。
传统热图的局限性在于:
版面限制:基因数量过多时,热图会变得极度细长,难以在标准纸张中排版。
信息割裂:样本的临床信息(如分组、表型)往往只能通过底部的注释条展示,不够直观。
环形热图的优势在于:
紧凑美观:将长条形的矩阵“卷”成圆环,极大节省了版面空间。
信息集成:外圈可以方便地添加多层数据追踪,如染色体位置、基因分类、样本分组等信息,一目了然。
二、 技术架构:aardio + R
要实现一个“一键绘图”的小工具,我们结合两者的优势:
R 语言 (
circlize包):负责核心的数据处理与绘图逻辑。circlize包是 R 语言中绘制 Circos 图的神器,专门为基因组数据可视化设计,提供了circos.heatmap函数,能够快速将矩阵映射为扇形热图。aardio:负责 Windows 桌面应用程序的开发。它体积小巧、免安装,能够方便地绘制 GUI 界面(按钮、文件选择框、参数输入框),并调用后台的 R 脚本执行绘图任务。
工作流程如下:
用户在 aardio 界面选择输入文件(CSV/TSV 格的表达矩阵)。
用户设置绘图参数(如颜色主题、聚类方式)。
aardio 生成临时 R 脚本并调用 Rscript 执行。
R 读取数据,绘制环形热图并输出图片。
三、 核心代码实现
1. R 端绘图逻辑
首先,我们需要在 R 中编写绘图函数。假设输入数据为标准化的表达矩阵(行是基因,列是样本)。
# 加载所需的包
suppressPackageStartupMessages(library(circlize))
suppressPackageStartupMessages(library(RColorBrewer))
suppressPackageStartupMessages(library(ComplexHeatmap))
suppressPackageStartupMessages(library(dendextend))
# 获取命令行参数
args <- commandArgs(trailingOnly = TRUE)
# 检查参数数量
if (length(args) != 2) {
stop("请提供两个参数:输入CSV文件路径和输出PDF文件路径。", call. = FALSE)
}
# 获取输入CSV文件路径和输出PDF文件路径
input_csv <- args[1]
output_pdf <- args[2]
# 检查输入文件是否存在
if (!file.exists(input_csv)) {
stop("输入文件不存在。请检查文件路径。", call. = FALSE)
}
# 函数加载和预处理数据
load_and_preprocess_data <- function(file_path) {
data <- read.table(file = file_path, header = TRUE, row.names = 1, sep = ',')
data_matrix <- as.matrix(data)
normalized_data <- t(scale(t(data_matrix)))
normalized_data[is.na(normalized_data)] <- 0
return(normalized_data)
}
# 加载和预处理数据
cir1 <- load_and_preprocess_data(input_csv)
# 打印数据维度和头部
print(dim(cir1))
print(head(cir1))
# 定义颜色梯度
mycol <- colorRamp2(c(-2.5, 0.3, 3.1), c("blue", "white", "red"))
# 打开PDF设备,设置宽度和高度相等
pdf(output_pdf, width = 8, height = 8)
# 设置绘图参数
circos.par(gap.after = c(30))
# 绘制调整后的圆形热图
circos.heatmap(cir1,
col = mycol,
dend.side = "inside",
rownames.side = "outside",
rownames.col = "black",
rownames.cex = 1.3,
track.height = 0.35, # 增加轨道高度
cluster = TRUE,
dend.track.height = 0.18,
dend.callback = function(dend, m, si) {
color_branches(dend, k = 15, col = 1:15)
})
# 添加列名
circos.track(track.index = get.current.track.index(), panel.fun = function(x, y) {
if (CELL_META$sector.numeric.index == 1) {
cn <- colnames(cir1)
n <- length(cn)
circos.text(rep(CELL_META$cell.xlim[2], n) + convert_x(0.5, "mm"),
1:n + 2.5,
cn, cex = 0.6, adj = c(0, 0.5), facing = "inside")
}
}, bg.border = NA)
# 添加图例
lg <- Legend(title = "Exp", col_fun = mycol, direction = "vertical")
grid.draw(lg)
# 清除圆形图
circos.clear()
# 关闭PDF设备
dev.off()
message("热图已成功保存至: ", output_pdf)获取命令行参数并执行(方便 aardio 调用)
args <- commandArgs(trailingOnly = TRUE)
draw_circular_heatmap(args[1], args[2])2. aardio 端界面与调用
在 aardio 中,我们设计一个简单的界面,包含“选择文件”和“开始绘图”两个核心功能。
import win.ui;
/*DSG{{*/
mainForm = win.form(text="CircosHeatmap-aardio";right=800;bottom=600)
mainForm.add(
btnRun={cls="plus";text="运行";left=740;top=10;right=791;bottom=41;activebgcolor=19354;bgcolor=-5197169;font=LOGFONT(h=-16);hoverbgcolor=23477;textcolor=16777215;z=4};
btnSelectFile={cls="plus";text="选择输入文件";left=608;top=10;right=732;bottom=41;activebgcolor=19354;bgcolor=-5197169;font=LOGFONT(h=-16);hoverbgcolor=23477;textcolor=16777215;z=3};
editConsole={cls="edit";left=10;top=467;right=791;bottom=591;bgcolor=16777215;db=1;dl=1;dr=1;edge=1;hscroll=1;multiline=1;textcolor=0;vscroll=1;z=1};
editRScript={cls="edit";left=10;top=48;right=791;bottom=451;bgcolor=16777215;db=1;dl=1;dr=1;dt=1;edge=1;hscroll=1;multiline=1;textcolor=0;vscroll=1;z=5};
inputFile={cls="edit";left=10;top=10;right=600;bottom=40;bgcolor=16777215;edge=1;textcolor=0;z=2}
)
/*}}*/
btskin = {
background={
active=0xFFD3E0BC;
default=0xFF8FB2B0;
hover=0xFF928BB3
}
}
mainForm.btnRun.skin(btskin);
mainForm.btnSelectFile.skin(btskin);
import console;
import process.r;
import fsys.dlg;
mainForm.editRScript.print($"\res\heatmap_script.R");
// 选择文件按钮点击事件
mainForm.btnSelectFile.oncommand = function(id, event) {
var filePath = fsys.dlg.open("CSV 文件|*.csv||",, "选择输入文件");
if (filePath) {
mainForm.inputFile.text = filePath; // 将选择的文件路径显示在输入框中
}
}
// 运行按钮点击事件
mainForm.btnRun.oncommand = function(id, event) {
var inputFilePath = mainForm.inputFile.text;
if (!inputFilePath) {
console.log("请先选择输入文件!");
return;
}
// 弹出保存文件对话框,选择PDF保存路径
var outputFilePath = fsys.dlg.save("PDF 文件|*.pdf||",, "选择保存路径");
if (!outputFilePath) {
console.log("请选择PDF文件的保存路径!");
return;
}
// 执行 R 脚本
var out = process.r.exec(mainForm.editRScript.text, inputFilePath, outputFilePath);
mainForm.editConsole.print(out);
}
// 显示主窗口
mainForm.show();
return win.loopMessage();四、 结果展示
运行该工具后,我们将得到一张紧凑的环形热图:

五、 总结
通过结合 aardio 的便捷开发与 R 语言的统计绘图能力,我们可以快速构建出功能强大的可视化小工具。
如果你也想尝试制作自己的 Circos 热图,不妨下载 R 的 circlize 包试一试,或者在这个基础上添加更多的自定义功能(如调整色板、添加图例等)。
参考链接: