Search code examples
rggplot2ggraph

color mapping in geom_conn_bundle not showing correctly


I am trying to plot an edge bundling graph in R with ggraph using geom_conn_bundle and I'm having a hard time trying to figure out why the color mappings aren't working properly.

I have a data frame with 152 rows and 3 columns: from, to, and color. Each row represents a connection between two people.

I used this tutorial to build my main plotting function:

Here is the code:

data_df <- read.csv('Final Natarajan - CGMRP_CCSG-Pubs_Fig-1-2.csv')
data_df_color_mapping <- data_df$color

data_df_color_mapping <- data_df_color_mapping[!(duplicated(data_df))]

data_df <- data_df[!(duplicated(data_df)),]
row.names(data_df) <- NULL
colnames(data_df) <- c('from', 'to')

hierarchy <- data.frame('from' = rep('origin', 71), 'to' = unique(c(as.character(data_df$from), 
as.character(data_df$to))))

vertices <- data.frame(name = unique(c(as.character(hierarchy$from), as.character(hierarchy$to))) ) 

mygraph <- graph_from_data_frame( hierarchy, vertices=vertices )

# The connection object must refer to the ids of the leaves:
from <- match( data_df$from, vertices$name)
to <- match( data_df$to, vertices$name)

vertices$id <- NA
myleaves <- which(is.na( match(vertices$name, hierarchy$from) ))
nleaves <- length(myleaves)
vertices$id[ myleaves ] <- seq(1:leaves)
vertices$angle <- 110 - 360 * vertices$id / leaves

# calculate the alignment of labels: right or left
# If I am on the left part of the plot, my labels have currently an angle < -90
vertices$hjust <- ifelse( vertices$angle < -90, 1, 0)

# flip angle BY to make them readable
vertices$angle <- ifelse(vertices$angle < -90, vertices$angle+180, vertices$angle)

png(file="edge_bundle.png",width=360*10,height=335*10)

ggraph(mygraph, layout = 'dendrogram', circular = TRUE) + 
  geom_conn_bundle(data = get_con(from = from, to = to), color=data_df_color_mapping, 
alpha=.3, width=2) +
  geom_node_text(aes(x = x*1.12, y=y*1.12, filter = leaf, label=name, angle=vertices$angle), size=16, 
alpha=1) +
  theme_void() +
  theme(
    legend.position="none",
    plot.margin=unit(c(0,0,0,0),"cm"),
  ) +
  expand_limits(x = c(-1.2, 1.2), y = c(-1.2, 1.2))

dev.off()

I have an issue with

geom_conn_bundle(data = get_con(from = from, to = to), color=data_df_color_mapping, alpha=.3, width=2)

I get the following error:

Error: Aesthetics must be either length 1 or the same as the data (15200): edge_colour

I fix it with color=rep(data_df_color_mapping, each=100) but the mapping is off. I can't figure out the pattern. I naturally assumed that I have to repeat each color 100 times since I have 152 rows but it doesn't work like that.

I also have a problem with putting color inside aes(), in that case I get the following error

Error: Aesthetics must be either length 1 or the same as the data (456): edge_colour

Now it's 3 times more data points than I have in my data frame.

Can anyone please help me understand how the get_con() function works or help me figure out how to pass the edge color data.

Thanks!

EDIT: The .csv file

The image it generates when I fix it with color=rep(data_df_color_mapping, each=100)enter image description here


Solution

  • I figured it out randomly. So when I reordered the data, I forgot to change the color mapping and I realized that it produced the same plot. So what happens is that it orders the graph according to the vertex index of "from". When I order my graph beforehand, it produces the desired result.