041 Kegg 环状图(美化用)

一、代码的作用

这个代码就是相对于常规的气泡图来说,这个图可能是更好看一些的,气泡图太常规了,而且我觉得气泡图看不出来和什么基因集有关。

二、具体的代码



# 具体的自定义方法可以先自己探索,或者等过段时间,我会写一篇文章详细讲讲怎么用。
# 我的公众号:好想吃帝王蟹
# 我的小红书:LeunHo


# 加载所需要的包
library(clusterProfiler)
library(org.Hs.eg.db)
library(ggplot2)
library(dplyr)
···
# 使用方法:从第10行开始的每一个代码块都是在定义函数,先运行完这几个代码块
# 然后运行setwd('你的文件路径'),再运行create_kegg_circular_plot("你的文件路径/你的文件名.txt")
# 生成的png会保存在这个路径下
···
# 读取输入文件
read_input_file <- function(file_path) {
  lines <- readLines(file_path)
  header <- strsplit(lines[1], "\t")[[1]]
  data <- read.table(file_path, sep="\t", skip=1, header=FALSE, col.names=header)
  return(data)
}

# 将基因symbol转换为Entrez ID
convert_to_entrez <- function(gene_symbols) {
  gene_map <- mapIds(org.Hs.eg.db, keys = gene_symbols, column = "ENTREZID", keytype = "SYMBOL", multiVals = "first")
  return(gene_map)
}

# 将Entrez ID转换为基因symbol
convert_entrez_to_symbols <- function(entrez_ids) {
  symbol_map <- mapIds(org.Hs.eg.db, keys = entrez_ids, column = "SYMBOL", keytype = "ENTREZID", multiVals = "first")
  return(symbol_map)
}

# 进行KEGG富集分析
perform_kegg_enrichment <- function(gene_list) {
  entrez_ids <- convert_to_entrez(gene_list)
  entrez_ids <- entrez_ids[!is.na(entrez_ids)]
  
  kegg_enrichment <- enrichKEGG(gene = entrez_ids, organism = 'hsa', pvalueCutoff = 0.05, qvalueCutoff = 0.2)
  
  return(kegg_enrichment)
}

# 生成KEGG环形图
create_kegg_circular_plot <- function(input_file) {
  input_data <- read_input_file(input_file)
  
  kegg_result <- perform_kegg_enrichment(input_data$gene)
  
  kegg_df <- as.data.frame(kegg_result)
  kegg_df <- kegg_df[1:min(5, nrow(kegg_df)),]
  
  color_palette <- c("#8BA6A9", "#A9B7C0", "#C0A9B7", "#B7C0A9", "#A9C0B7")
  
  png("kegg_circular_plot.png", width = 1400, height = 1400, res = 300)
  par(mar = c(1, 1, 1, 1))
  plot.new()
  plot.window(xlim = c(-1, 1), ylim = c(-1, 1))
  
  quadraticBezier <- function(x0, y0, x1, y1, x2, y2, n = 100) {
    t <- seq(0, 1, length.out = n)
    x <- (1 - t)^2 * x0 + 2 * (1 - t) * t * x1 + t^2 * x2
    y <- (1 - t)^2 * y0 + 2 * (1 - t) * t * y1 + t^2 * y2
    return(list(x = x, y = y))
  }
  
  pathway_radius <- 0.42
  gene_radius <- 0.85
  n_paths <- nrow(kegg_df)
  
  for (i in 1:n_paths) {
    angle <- (i - 0.5) * (2 * pi / n_paths)
    x_center <- pathway_radius * cos(angle)
    y_center <- pathway_radius * sin(angle)
    
    gene_count <- length(strsplit(kegg_df$geneID[i], "/")[[1]])
    pathway_circle_radius <- 0.07 + 0.005 * gene_count
    
    symbols(x_center, y_center, circles = pathway_circle_radius, add = TRUE, inches = FALSE, fg = color_palette[i], bg = adjustcolor(color_palette[i], alpha.f = 0.35))
    
    pathway_name <- kegg_df$Description[i]
    wrapped_name <- paste(strwrap(pathway_name, width = 28), collapse = "\n")
    text(x_center, y_center, labels = wrapped_name, cex = 0.58, col = color_palette[i], font = 2)
    
    pathway_entrez_ids <- strsplit(kegg_df$geneID[i], "/")[[1]]
    pathway_genes <- convert_entrez_to_symbols(pathway_entrez_ids)
    
    for (j in 1:length(pathway_genes)) {
      gene_angle <- angle + (j - (length(pathway_genes) + 1) / 2) * (0.5 * pi / length(pathway_genes))
      gene_x <- gene_radius * cos(gene_angle)
      gene_y <- gene_radius * sin(gene_angle)
      
      gene_circle_radius <- 0.015 + 0.01 * (-log10(kegg_df$p.adjust[i]))
      symbols(gene_x, gene_y, circles = gene_circle_radius, add = TRUE, inches = FALSE, fg = color_palette[i], bg = adjustcolor(color_palette[i], alpha.f = 0.5))
      
      angle_gene <- atan2(gene_y, gene_x) * 180 / pi
      if (abs(angle_gene) > 90 && abs(angle_gene) < 270) {
        text_srt <- angle_gene + 180
        text_adj <- 1
      } else {
        text_srt <- angle_gene
        text_adj <- 0
      }
      
      text(gene_x * (1 + 0.02 + gene_circle_radius), gene_y * (1 + 0.02 + gene_circle_radius), labels = pathway_genes[j], cex = 0.4, col = color_palette[i], srt = text_srt, adj = c(text_adj, 0.5))
      
      control_angle <- (angle + gene_angle) / 2  
      control_radius <- (pathway_radius + gene_radius) / 2  
      control_x <- control_radius * cos(control_angle)
      control_y <- control_radius * sin(control_angle)
      
      curve_points <- quadraticBezier(x0 = x_center, y0 = y_center, x1 = control_x, y1 = control_y, x2 = gene_x, y2 = gene_y)
      
      lines(curve_points$x, curve_points$y, col = color_palette[i], lwd = 0.6, lty = 1)
    }
  }
  dev.off()
}

setwd('F:/生信代码复现/kegg_circularplot') #生成的png会保存在这个路径下
create_kegg_circular_plot("F:/生信代码复现/kegg_circularplot/input.txt") #定义完函数后运行这一行代码



复现出来的图片

kegg_circular_plot.png