如何在R中制作不同半径、可区分类别的弧图?
Absolutely! You can absolutely create arc diagrams where different connection categories are represented by arcs of varying radii—this is totally achievable in R, even if packages like ggraph or arcdiagram don’t support it out of the box. Let’s walk through two reliable approaches:
Approach 1: Layered Arcs with ggraph
The trick here is to split your edges by category and draw each group with a custom radius using geom_edge_arc. Here’s a complete example:
Step 1: Prepare Data
library(tidyverse) library(ggraph) library(igraph) # Create edge data with category labels edges <- tibble( from = c("A", "A", "B", "B", "C", "C"), to = c("D", "D", "E", "E", "F", "F"), category = c("Primary", "Secondary", "Primary", "Secondary", "Primary", "Secondary") ) # Convert to an igraph object graph <- graph_from_data_frame(edges, directed = FALSE)
Step 2: Assign Radii to Categories
Map each category to a unique radius value (adjust these numbers based on how spread out you want the arcs):
radius_mapping <- tibble( category = c("Primary", "Secondary"), radius = c(0.25, 0.5) ) # Merge radius values into edge data edges_with_radius <- edges %>% left_join(radius_mapping, by = "category")
Step 3: Plot Layered Arcs
Draw each category’s arcs separately with their assigned radius:
ggraph(graph, layout = "linear") + # Draw nodes geom_node_point(size = 6, color = "#2c3e50") + geom_node_text(aes(label = name), vjust = -1.2, size = 4) + # Draw arcs for each category geom_edge_arc( data = function(x) filter(x, category == "Primary"), aes(color = category), radius = 0.25, linewidth = 1.8 ) + geom_edge_arc( data = function(x) filter(x, category == "Secondary"), aes(color = category), radius = 0.5, linewidth = 1.8 ) + # Customize colors and theme scale_color_manual(values = c("Primary" = "#e74c3c", "Secondary" = "#3498db")) + theme_void()
This will give you arcs with distinct radii for each category, no overlapping!
Approach 2: Manual Arc Drawing with ggforce
For even more control, use ggforce::geom_arc to calculate and draw arcs from scratch. This is great if you need precise control over arc positioning:
Step 1: Get Node Positions
First, generate linear layout positions for your nodes:
library(ggforce) # Create linear layout and extract node positions layout <- create_layout(graph, layout = "linear") node_pos <- layout %>% select(name, x)
Step 2: Calculate Arc Parameters
Compute the center, radius, and angles for each arc based on its category:
arc_params <- edges_with_radius %>% left_join(node_pos, by = c("from" = "name")) %>% rename(x_start = x) %>% left_join(node_pos, by = c("to" = "name")) %>% rename(x_end = x) %>% mutate( x_center = (x_start + x_end) / 2, # Midpoint between nodes # Set arc direction (upwards) start_angle = ifelse(x_start < x_end, pi, 0), end_angle = ifelse(x_start < x_end, 0, pi) )
Step 3: Plot Custom Arcs
Use geom_arc to draw each arc with its calculated parameters:
ggplot() + # Draw nodes geom_point(data = node_pos, aes(x = x, y = 0), size = 6, color = "#2c3e50") + geom_text(data = node_pos, aes(x = x, y = 0.6, label = name), size = 4) + # Draw custom arcs geom_arc( data = arc_params, aes( x0 = x_center, y0 = 0, r = radius, start = start_angle, end = end_angle, color = category ), linewidth = 1.8 ) + # Customize plot scale_color_manual(values = c("Primary" = "#e74c3c", "Secondary" = "#3498db")) + coord_fixed() + theme_void()
Key Notes
- Adjust the
radiusvalues to control how high each arc curves—larger values mean taller arcs. - For directed graphs, you can tweak the
start_angleandend_angleparameters to make arcs curve in different directions (e.g., upwards for forward connections, downwards for reverse). - Both methods ensure arcs from different categories don’t overlap, making your diagram much easier to interpret.
内容的提问来源于stack exchange,提问作者santoku

