Files
PlantAI-dev/scripts/draw_ppi_network.R
T
2026-08-03 18:42:47 +08:00

212 lines
7.0 KiB
R
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env Rscript
#============================================================================
# PPI Network Visualization
# 蛋白互作网络可视化
#============================================================================
# Parse arguments using commandArgs (no external dependencies)
args <- commandArgs(trailingOnly = TRUE)
network_file <- NULL
output_file <- NULL
prefix <- "ppi"
# Parse arguments
i <- 1
while (i <= length(args)) {
if (args[i] == "--network" && i < length(args)) {
network_file <- args[i + 1]
i <- i + 2
} else if (args[i] == "--output" && i < length(args)) {
output_file <- args[i + 1]
i <- i + 2
} else if (args[i] == "--prefix" && i < length(args)) {
prefix <- args[i + 1]
i <- i + 2
} else {
i <- i + 1
}
}
# Validate arguments
if (is.null(network_file) || is.null(output_file)) {
cat("Usage: Rscript draw_ppi_network.R --network <file> --output <file> [--prefix <name>]\n")
quit(status = 1)
}
cat("=" ,rep("=", 60), "\n", sep="")
cat("PPI Network Visualization\n")
cat("=" ,rep("=", 60), "\n\n")
has_igraph <- requireNamespace("igraph", quietly = TRUE)
has_ggraph <- requireNamespace("ggraph", quietly = TRUE)
has_ggplot2 <- requireNamespace("ggplot2", quietly = TRUE)
if (has_igraph) {
library(igraph)
}
if (has_ggraph && has_ggplot2) {
library(ggraph)
library(ggplot2)
}
#============================================================================
# Step 1: Read network data
#============================================================================
cat("Step 1: Reading network data...\n")
if (!file.exists(network_file)) {
stop(paste("Network file not found:", network_file))
}
edges <- read.table(network_file, header = TRUE, sep = "\t", stringsAsFactors = FALSE)
cat(" Edges:", nrow(edges), "\n")
cat(" Columns:", paste(colnames(edges), collapse = ", "), "\n\n")
score_col <- if ("combined_score" %in% colnames(edges)) "combined_score" else "score"
if (!score_col %in% colnames(edges)) {
stop("Network file must contain score or combined_score column")
}
edge_scores <- as.numeric(edges[[score_col]])
edge_weights <- ifelse(edge_scores > 1, edge_scores / 1000, edge_scores)
if (!has_igraph) {
cat("igraph not installed; using base R fallback plot\n")
nodes <- sort(unique(c(edges$protein1, edges$protein2)))
n <- length(nodes)
angle <- seq(0, 2 * pi, length.out = n + 1)[1:n]
coords <- data.frame(name = nodes, x = cos(angle), y = sin(angle))
rownames(coords) <- coords$name
pdf(output_file, width = 12, height = 10)
plot(coords$x, coords$y, type = "n", axes = FALSE, xlab = "", ylab = "",
main = paste(prefix, "PPI Network\n", n, "proteins,", nrow(edges), "interactions"))
for (idx in seq_len(nrow(edges))) {
a <- coords[edges$protein1[idx], ]
b <- coords[edges$protein2[idx], ]
col <- ifelse(edge_weights[idx] >= 0.7, "red",
ifelse(edge_weights[idx] >= 0.4, "orange", "gray"))
segments(a$x, a$y, b$x, b$y, col = col, lwd = 1 + edge_weights[idx] * 3)
}
points(coords$x, coords$y, pch = 21, bg = "lightblue", cex = 2)
text(coords$x, coords$y, labels = coords$name, pos = 3, cex = 0.7)
legend("bottomright",
legend = c("High (>=0.7)", "Medium (0.4-0.7)", "Low (<0.4)"),
col = c("red", "orange", "gray"), lty = 1, lwd = 2,
title = "Confidence", cex = 0.8)
dev.off()
cat("Base R network plot generated:", output_file, "\n")
quit(status = 0)
}
#============================================================================
# Step 2: Create graph
#============================================================================
cat("Step 2: Creating graph...\n")
# 创建边列表
edge_list <- as.matrix(edges[, c("protein1", "protein2")])
# 创建图
g <- graph_from_edgelist(edge_list, directed = FALSE)
# 添加边权重(score)
E(g)$weight <- edge_weights
E(g)$confidence <- cut(edge_weights,
breaks = c(0, 0.4, 0.7, 1.0),
labels = c("Low", "Medium", "High"))
cat(" Nodes:", vcount(g), "\n")
cat(" Edges:", ecount(g), "\n\n")
#============================================================================
# Step 3: Calculate network metrics
#============================================================================
cat("Step 3: Calculating network metrics...\n")
# 度中心性
V(g)$degree <- degree(g)
# 介数中心性
V(g)$betweenness <- betweenness(g)
# 聚类系数
V(g)$clustering <- transitivity(g, type = "local")
V(g)$clustering[is.na(V(g)$clustering)] <- 0 # 处理NA值
cat(" Average degree:", mean(V(g)$degree), "\n")
cat(" Network density:", edge_density(g), "\n")
cat(" Clustering coefficient:", transitivity(g), "\n\n")
#============================================================================
# Step 4: Create visualization
#============================================================================
cat("Step 4: Creating visualization...\n")
# 设置节点大小(基于度中心性)
V(g)$size <- sqrt(V(g)$degree) * 3 + 2
# 设置节点颜色(基于聚类系数)
node_colors <- colorRampPalette(c("lightblue", "darkblue"))(100)
color_indices <- cut(V(g)$clustering, breaks = 100, labels = FALSE)
color_indices[is.na(color_indices)] <- 1 # 处理NA值
V(g)$color <- node_colors[color_indices]
# 创建PDF
pdf(output_file, width = 12, height = 10)
# 布局算法(使用Fruchterman-Reingold)
set.seed(42)
layout <- layout_with_fr(g, niter = 1000)
# 绘制网络
plot(g,
layout = layout,
vertex.size = V(g)$size,
vertex.color = V(g)$color,
vertex.label = V(g)$name,
vertex.label.cex = 0.6,
vertex.label.color = "black",
edge.width = E(g)$weight * 2,
edge.color = ifelse(E(g)$weight >= 0.7, "red",
ifelse(E(g)$weight >= 0.4, "orange", "gray")),
main = paste(prefix, "PPI Network\n",
vcount(g), "proteins,", ecount(g), "interactions"),
sub = "Edge color: Red (high confidence ≥0.7), Orange (medium 0.4-0.7), Gray (low <0.4)"
)
# 添加图例
legend("bottomright",
legend = c("High (≥0.7)", "Medium (0.4-0.7)", "Low (<0.4)"),
col = c("red", "orange", "gray"),
lty = 1,
lwd = 2,
title = "Confidence",
cex = 0.8
)
# 使用ggraph绘制更美观的版本(如果包可用)
if (has_ggraph && has_ggplot2) tryCatch({
p <- ggraph(g, layout = "fr") +
geom_edge_link(aes(edge_width = weight, edge_color = confidence), alpha = 0.6) +
geom_node_point(aes(size = degree, color = clustering)) +
geom_node_text(aes(label = name), repel = TRUE, size = 2) +
scale_edge_width(range = c(0.5, 3)) +
scale_color_gradient(low = "lightblue", high = "darkblue") +
theme_graph() +
labs(title = paste(prefix, "PPI Network"),
subtitle = paste(vcount(g), "proteins,", ecount(g), "interactions"))
print(p)
}, error = function(e) {
cat(" ggraph plot skipped:", e$message, "\n")
})
dev.off()
cat("\n" ,rep("=", 60), "\n", sep="")
cat("Completed!\n")
cat("Output file:", output_file, "\n")
cat("=" ,rep("=", 60), "\n", sep="")
quit(status = 0)