rggplot2igraphggnetwork

Plotting a network with edge line widths proportional to their weights using ggnetwork


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 and igraph object from that using:

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

Then I follow examples of R's ggnetwork to convert gr to a data.frame:

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:

ggplot2::ggplot(gr.df,ggplot2::aes(x=x,y=y,xend=xend,yend=yend))+
  ggnetwork::geom_edges(color="gray")+
  ggnetwork::geom_nodes(color="black")+
  ggnetwork::geom_nodelabel_repel(aes(label=vertex.names,color=vertex.names),fontface="bold",box.padding=unit(1,"lines"))+
  ggplot2::theme_minimal()+ggplot2::theme(axis.text=ggplot2::element_blank(),axis.title=ggplot2::element_blank(),legend.position="none")

Which gives: enter image description here

My question is how to get the widths of the edge lines in this plot to be proportional to the edge weights in gr (igraph::E(gr)$weight)?

Looking at gr.df:

> head(gr.df)
          x         y  na.x vertex.names      xend      yend na.y weight
1 0.3637960 0.8873783 FALSE            A 0.3637960 0.8873783   NA     NA
2 0.7480217 0.4129375 FALSE            B 0.7480217 0.4129375   NA     NA
3 0.1306538 0.0000000 FALSE            C 0.1306538 0.0000000   NA     NA
4 0.4828271 0.6498561 FALSE            D 0.4828271 0.6498561   NA     NA
5 0.2243358 0.4484766 FALSE            E 0.2243358 0.4484766   NA     NA
6 1.0000000 0.6396669 FALSE            F 1.0000000 0.6396669   NA     NA

I see that the edges are not transferred from gr to gr.df.


Solution

  • You can specify the size aesthetic in the geom_edges call. E.g. aes(size=weight)

    ggplot2::ggplot(gr.df,ggplot2::aes(x=x,y=y,xend=xend,yend=yend))+
      ggnetwork::geom_edges(color="gray",size=aes(size=weight))+
      ggnetwork::geom_nodes(color="black")+
      ggnetwork::geom_nodelabel_repel(aes(label=vertex.names,color=vertex.names),fontface="bold",box.padding=unit(1,"lines"))+
      ggplot2::theme_minimal()+ggplot2::theme(axis.text=ggplot2::element_blank(),axis.title=ggplot2::element_blank(),legend.position="none")
    

    As a note, the dataframe created does contain the vertices, and the edges and relevant weights. The vertices are listed first and the edges come next. In this case, if you look at the whole dataframe (or just tail), you'll see that the weight values are there for the edges.