rggplot2jitterggnetwork

Add jitterred points to a ggnetwork plot


I have a graph of vertices and edges which I'd like to plot using a fruchtermanreingold layout.

Here's the graph edges matrix:

edge.mat <- matrix(as.numeric(strsplit("3651,0,0,1,0,0,0,0,2,0,11,2,0,0,0,300,0,1,0,0,66,0,78,9,0,0,0,0,0,0,11690,0,1,0,0,0,0,0,0,0,0,493,1,1,0,4288,5,0,0,36,0,9,7,3,0,6,1,0,1,7,490,0,0,0,6,0,0,628,6,12,0,0,0,0,0,641,0,0,4,0,0,0,0,0,0,66,0,0,0,0,3165,0,281,0,0,0,0,0,0,0,0,45,1,0,0,35248,0,1698,2,0,1,0,2,99,0,0,6,29,286,0,31987,0,1,10,0,8,0,16,0,21,1,0,0,1718,0,51234,0,0,17,3,12,0,0,7,0,0,0,1,0,2,16736,0,0,0,3,0,0,4,630,0,0,0,9,0,0,29495,53,6,0,0,0,0,5,0,0,0,0,3,0,19,186,0,0,0,482,8,12,0,1,0,7,1,0,6,0,26338",
                              split = ",")[[1]]),
                   nrow = 14,
                   dimnames = list(LETTERS[1:14], LETTERS[1:14]))

I then create an igraph object from that using:

gr <- igraph::graph_from_adjacency_matrix(edge.mat, mode="undirected", weighted=T, diag=F)

And then use ggnetwork to convert gr to a data.frame, with specified vertex colors:

set.seed(1)
gr.df <- ggnetwork::ggnetwork(gr,
                              layout="fruchtermanreingold", 
                              weights="weight", 
                              niter=50000, 
                              arrow.gap=0)

And then I plot it using ggplot2 and ggnetwork:

vertex.colors <- strsplit("#00BE6B,#DC2D00,#F57962,#EE8044,#A6A400,#62B200,#FF6C91,#F77769,#EA8332,#DA8E00,#C59900,#00ACFC,#C49A00,#DC8D00",
                          split=",")[[1]]

library(ggplot2)
library(ggnetwork)

ggplot(gr.df, aes(x = x, y = y, xend = xend, yend = yend)) +
  geom_edges(color = "gray", aes(size = weight)) +
  geom_nodes(color = "black")+
  geom_nodelabel(aes(label = vertex.names),
                 color = vertex.colors, fontface = "bold")+
  theme_minimal() + 
  theme(axis.text=element_blank(), 
        axis.title=element_blank(),
        legend.position="none")

enter image description here

In my case each vertex actually represents many points, where each vertex has a different number of points. Adding that information to gr.df:

gr.df$n <- NA
gr.df$n[which(is.na(gr.df$weight))] <- as.integer(runif(length(which(is.na(gr.df$weight))), 100, 500))

What I'd like to do is add to the plot gr.df$n radially jittered points around each vertex (i.e., with its corresponding n), with the same vertex.colors coding. Any idea how to do that?


Solution

  • I think sampling and then plotting with geom_point is a reasonable strategy. (otherwise you could create your own geom).

    Here is some rough code, starting from the relevant bit of your question

    gr.df$n <- 1
    gr.df$n[which(is.na(gr.df$weight))] <- as.integer(runif(length(which(is.na(gr.df$weight))), 100, 500))
    
    # function to sample
    # https://stackoverflow.com/questions/5837572/generate-a-random-point-within-a-circle-uniformly
    circSamp <- function(x, y, R=0.1){
        n <- length(x)
        A <- a <- runif(n,0,1)
        b <- runif(n,0,1)
    
        ind <- b < a
        a[ind] <- b[ind]
        b[ind] <- A[ind]
    
        xn = x+b*R*cos(2*pi*a/b)
        yn = y+b*R*sin(2*pi*a/b)
        cbind(x=xn, y=yn)
     }
    
    
    # sample  
    d <- with(gr.df, data.frame(vertex.names=rep(vertex.names, n),
                                circSamp(rep(x,n), rep(y,n))))
    
    # p is your plot   
    p + geom_point(data=d, aes(x, y, color = vertex.names),
                   alpha=0.1, inherit.aes = FALSE) +
        scale_color_manual(values = vertex.colors)
    

    Giving

    enter image description here