I'm trying to plot igraph network with ggplot2. I use geom_point()
for the vertex and geom_line()
for the edges. The point size and line width in ggplot2 are both specified by size. When I specified them separately, I hope to get two separate legends but they turned out to be merged. Below is an example.
# an example graph
df <- data.frame(from=letters[c(1, 1, 2:4, 4)], to=letters[c(2, 3, 5:7, 1)])
g <- graph.data.frame(df, directed=FALSE)
Vname <- V(g)$name
set.seed(100)
V(g)$varVsize <- rnorm(length(Vname))
E(g)$varEwidth <- rnorm(nrow(df))
E(g)$varEcol <- rnorm(nrow(df), 1, 1)
Vcord <- layout.fruchterman.reingold(g) # get coordinates for the Vertex
rownames(Vcord) <- V(g)$name
# 2-column edge list
el <- get.edgelist(g)
el_df <- data.frame(as.data.frame(el), Ewidth=E(g)$varEwidth, Ecol=E(g)$varEcol)
# assigning edge id so that it can be used as group
el_df$id <- 1:nrow(el_df)
## now g_df have each node in the edgelist as a row: first nodesFrom (id=1:145), then nodesTo (id=146:290, i.e.)
el_dfm <- melt(el_df, id=3:5)
xy_s <- data.frame(value = rownames(Vcord),
Vsize=V(g)$varVsize, # add Vetex attribues here: affects size and color
x = Vcord[, 1],
y = Vcord[, 2])
g_df2 <- merge(el_dfm, xy_s, by = "value")
# fig 1
ggplot(g_df2, aes(x, y)) +
geom_point(data=g_df2, aes(x, y, size=Vsize), alpha=0.4) +
geom_line(aes(color=Ecol, group = id)) +
geom_text(size = 4, aes(label = value), colour='blue')
# fig 2: Vsize and Ewidth legend are merged: transparency in geom_line is used so it will not overlap geom_point
ggplot(g_df2, aes(x, y)) +
geom_point(data=g_df2, aes(x, y, size=Vsize), alpha=0.4) +
geom_line(aes(color=Ecol, group = id, size=Ewidth), alpha=0.3) +
geom_text(size = 4, aes(label = value), colour='blue')