# 渐变火山图绘制 - logFC已是log2转换值# 数据范围:-11.52 到 7.9library(ggplot2)library(ggrepel)library(tidyverse)setwd("D:/R/R_code/volcano")data = read.csv("volcano.csv")# ==================== 直接使用log2FC ====================data <- data %>% mutate( log2FC = logFC, # 您的logFC已是log2值,直接使用 negLog10P = -1 * log10(pvalue) )cat("log2FC范围:", round(min(data$log2FC), 2), "到", round(max(data$log2FC), 2), "\n")cat("对应倍数变化:", round(2^min(data$log2FC)), "倍下调 到 ", round(2^max(data$log2FC)), "倍上调\n")# ==================== 阈值设置 ====================# 建议用1(对应2倍变化)或0.585(对应1.5倍),根据您的数据范围调整FC_threshold_log2 = 1.0 # log2(2) = 1,即2倍变化阈值# 如果基因太多/太少,可以改为 0.585 (1.5倍) 或 1.585 (3倍)PValue_threshold = 0.05# 定义差异类型data <- data %>% mutate( change = case_when( log2FC > FC_threshold_log2 & pvalue < PValue_threshold ~ "Up", log2FC < -FC_threshold_log2 & pvalue < PValue_threshold ~ "Down", TRUE ~ "NotSig" ) )cat("\n差异基因统计(|log2FC| >", FC_threshold_log2, "且 p <", PValue_threshold, "):\n")print(table(data$change))# 查看下调基因分布down_stats <- data %>% filter(change == "Down") %>% summarise( n = n(), min_log2FC = min(log2FC), max_log2FC = max(log2FC), median_log2FC = median(log2FC) )cat("\n下调基因统计:\n")print(down_stats)# ==================== 筛选Top 5(排除NotSig)====================top5_up <- data %>% filter(change == "Up") %>% arrange(pvalue) %>% head(5) %>% pull(gene)top5_down <- data %>% filter(change == "Down") %>% arrange(pvalue) %>% head(5) %>% pull(gene)cat("\nTop 5 上调:", paste(top5_up, collapse = ", "), "\n")cat("Top 5 下调:", paste(top5_down, collapse = ", "), "\n")# 检查这些基因的值cat("\nTop 5 下调基因详细信息:\n")print(data %>% filter(gene %in% top5_down) %>% select(gene, log2FC, pvalue, negLog10P))# ==================== 图1:无标签 ====================data$label <- ""p1 <- ggplot(data, aes(x = log2FC, y = negLog10P)) + geom_point(aes(color = negLog10P, size = negLog10P), alpha = 0.6) + scale_color_gradientn(colors = c("#3288BD", "#66C2A5", "#ABDDA4", "#E6F598", "#FFFFBF", "#FEE08B", "#FDAE61", "#F46D43", "#D53E4F", "#9E0142")) + scale_radius(range = c(0.5, 4), guide = "none") + labs(title = "Volcano Plot", subtitle = paste0("Threshold: |log2FC| > ", FC_threshold_log2, " (", round(2^FC_threshold_log2, 1), "-fold), p < ", PValue_threshold), x = expression(log[2](Fold~Change)), y = expression(-log[10](PValue))) + geom_hline(yintercept = -log10(PValue_threshold), linetype = 2, color = "grey40") + geom_vline(xintercept = c(-FC_threshold_log2, FC_threshold_log2), linetype = 2, color = "grey40") + # X轴范围设置,确保两侧都显示清楚 scale_x_continuous(limits = c(min(data$log2FC)*1.1, max(data$log2FC)*1.1)) + theme_classic() + theme(plot.title = element_text(hjust = 0.5, size = 14, face = "bold"))ggsave("volcano_no_labels.pdf", p1, width = 9, height = 7, dpi = 300)print(p1)# ==================== 图2:Top 5标签(修正版)====================data$label <- ifelse(data$gene %in% c(top5_up, top5_down), as.character(data$gene), "")p2 <- ggplot(data, aes(x = log2FC, y = negLog10P)) + geom_point(aes(color = negLog10P, size = negLog10P), alpha = 0.6) + scale_color_gradientn(colors = c("#3288BD", "#66C2A5", "#ABDDA4", "#E6F598", "#FFFFBF", "#FEE08B", "#FDAE61", "#F46D43", "#D53E4F", "#9E0142")) + scale_radius(range = c(0.5, 4), guide = "none") + labs(title = "Volcano Plot (Top 5 Up & Down)", subtitle = paste0("Down-regulated: ", sum(data$change=="Down"), " | Up-regulated: ", sum(data$change=="Up")), x = expression(log[2](Fold~Change)), y = expression(-log[10](PValue))) + # ← 这里关闭了labs() geom_hline(yintercept = -log10(PValue_threshold), linetype = 2, color = "grey40") + geom_vline(xintercept = c(-FC_threshold_log2, FC_threshold_log2), linetype = 2, color = "grey40") + geom_text_repel(data = subset(data, label != ""), aes(label = label), max.overlaps = 10000, size = 3.5, fontface = "italic", box.padding = unit(0.5, "lines"), point.padding = unit(0.2, "lines"), segment.color = "black", min.segment.length = 0, nudge_x = ifelse(subset(data, label != "")$log2FC < 0, -0.5, 0.5), direction = "both", seed = 42) + scale_x_continuous(limits = c(min(data$log2FC)*1.15, max(data$log2FC)*1.15)) + theme_classic() + theme(plot.title = element_text(hjust = 0.5, size = 14, face = "bold"), plot.margin = margin(10, 30, 10, 30))ggsave("volcano_top5_labels.pdf", p2, width = 10, height = 7, dpi = 300)print(p2)