Reputation: 87
I am trying to make a graph with ggplot2 and ggnetwork. I have a two dimensional lattice grid, an adjacency matrix, and I want to illustrate certain values by colour coding.
Unfortunately i can either get the network going, or the accurate colour coding, but not both at the same time.
Here is my code and sample data to reproduce my problem:
library(network)
library(ggnetwork)
library(ggplot2)
#SAMPLE DATA
adj_matrix <- matrix(c(0, 1, 0, 1, 1, 0, 0, 0, 0,
1, 0, 1, 1, 1, 1, 0, 0, 0,
0, 1, 0, 0, 1, 1, 0, 0, 0,
1, 1, 0, 0, 1, 0, 1, 1, 0,
1, 1, 1, 1, 0, 1, 1, 1, 1,
0, 1, 1, 0, 1, 0, 0, 1, 1,
0, 0, 0, 1, 1, 0, 0, 1, 0,
0, 0, 0, 1, 1, 1, 1, 0, 1,
0, 0, 0, 0, 1, 1, 0, 1, 0), nrow = 9, ncol = 9, byrow = TRUE)
grid_coords <- matrix(NA, nrow=3 * 3, ncol=2)
cell_size <- 1
origin_x <- 1
origin_y <- 1
k <- 1
for (i in 1:3) {
for (j in 1:3) {
x <- (j-1) * cell_size + origin_x
y <- (i-1) * cell_size + origin_y
grid_coords[k,] <- c(x, y)
k <- k + 1
}
}
R <- c(1.0000000, 0.5723928, 0.1447857, 1.4276072, 1.0000000, 0.5723928, 1.8552143, 1.4276072, 1.0000000)
#GENERATING GRAPH
gra <- network.initialize(nrow(grid_coords), directed=F)
gra <- network.adjacency(adj_matrix, gra)
n <- ggnetwork(gra, layout=grid_coords, arrow.gap=0)
r_i <- data.frame(R=R, X=n$x[1:nrow(grid_coords)], Y=n$y[1:nrow(grid_coords)], xend=rep(0, nrow(grid_coords)), yend=rep(0, nrow(grid_coords)))
ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) +
geom_edges(color = "grey80") +
geom_point(size=5, col="grey80") +
geom_point(size=3.5, col="white") +
geom_point(dat=r_i, aes(x=X, y=Y, color = R), size=3.5) +
scale_colour_gradient(low="steelblue3", high='firebrick3', name=expression(bold(R)[ix]), limit=c(min(R),max(R)), na.value = "white") +
theme(panel.background = element_blank(),
axis.title = element_blank(),
axis.text = element_blank(),
axis.ticks = element_blank())
The code above will create the network, but won't apply the correct colouring to the nodes.
However, by hashing out one line the colouring issue can be solved, but the network connecting the nodes is not generated.
gra <- network.initialize(nrow(grid_coords), directed=F)
#gra <- network.adjacency(adj_matrix, gra)
n <- ggnetwork(gra, layout=grid_coords, arrow.gap=0)
r_i <- data.frame(R=R, X=n$x[1:nrow(grid_coords)], Y=n$y[1:nrow(grid_coords)], xend=rep(0, nrow(grid_coords)), yend=rep(0, nrow(grid_coords)))
ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) +
geom_edges(color = "grey80") +
geom_point(size=5, col="grey80") +
geom_point(size=3.5, col="white") +
geom_point(dat=r_i, aes(x=X, y=Y, color = R), size=3.5) +
scale_colour_gradient(low="steelblue3", high='firebrick3', name=expression(bold(R)[ix]), limit=c(min(R),max(R)), na.value = "white") +
theme(panel.background = element_blank(),
axis.title = element_blank(),
axis.text = element_blank(),
axis.ticks = element_blank())
Here is the figure with the correct colouring:
I think it might have to do with something about the synchronisation of the nodes, but havent been able to crack it so far.
Thanks for considering this problem :)
EDIT: After Allan's solution to my original question i am wondering if there is a way to create a function which synchs up all possible node networks. Heres the sample data for a triangle: Thanks again:)
#SAMPLE DATA OF NOT SYMMETRICAL LATTICE
adj_matrix2 <- matrix(c( 0, 1, 0, 0, 0, 0, 0, 0, 1, 0,
1, 0, 1, 0, 0, 0, 0, 1, 1, 1,
0, 1, 0, 1, 1, 1, 0, 0, 0, 1,
0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
0, 0, 1, 1, 0, 1, 0, 0, 0, 1,
0, 0, 1, 0, 1, 0, 1, 1, 0, 1,
0, 0, 0, 0, 0, 1, 0, 1, 0, 1,
0, 1, 0, 0, 0, 1, 1, 0, 1, 1,
1, 1, 0, 0, 0, 0, 0, 1, 0, 1,
0, 1, 1, 0, 1, 1, 1, 1, 1, 0), nrow = 10, ncol = 10, byrow = TRUE)
Xchords <- c(1,2,3,4,4,4,4,3,2,3)
Ychords <- c(1,2,3,4,3,2,1,1,1,2)
grid_coords2 <- (cbind(Xchords, Ychords))
R2 <- c(2.057551, 2.057551, 2.057551, 2.057551, 2.057551, 2.057551, 2.057551, 2.057551, 2.057551, 10.517957 )
And here is the image with incorrect colouring:
Upvotes: 2
Views: 88
Reputation: 173793
The problem is nothing to do with your plotting code - you simply haven't defined the node data frame correctly (examine the x and y co-ordinates of r_i
).
If you do:
r_i <- data.frame(R = R,
X = rep(sort(unique(n$x)), 3),
Y = rep(sort(unique(n$y)), each = 3))
And plot with
ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) +
geom_edges(color = "grey80") +
geom_point(size = 5, color = "grey80") +
geom_point(aes(x = X, y = Y, color = R), data = r_i,
size = 3.5, inherit.aes = FALSE) +
scale_colour_gradient(low = "steelblue3", high = 'firebrick3',
name = expression(bold(R)[ix])) +
theme(panel.background = element_blank(),
axis.title = element_blank(),
axis.text = element_blank(),
axis.ticks = element_blank())
You get this:
Upvotes: 1