#Example R-based network drawing tools #This is a compilation of code snipits pulled from Jaemin Lee's 2016 presentation, #the Polnet 2016 tutorial, and examples from the various package vingettes #Make sure you have the relevant packages, you likely do given the earlier modules, #but for completeness here are relevant packages, we wont' #go over all these today... install.packages("igraph") install.packages("network") install.packages("sna") install.packages("visNetwork") install.packages("ndtv", dependencies=T) install.packages("GGally") install.packages("ggraph") install.packages("ggnetwork") install.packages("networkD3") #clear everything to start rm(list = ls()) gc() #try some iGraph plotting functions library(igraph); #load the data #if you have not already doneso, download the #the network file from: #http://www.soc.duke.edu/~jmoody77/SNH/comm1.net #and save to a space you'll specify next g=read.graph('C:/jwm/grants/r25NetHealth/ProgramMaterials/workshopdata/comm1.net', format=c("pajek")); #transfor the data into parts, which will be needed later. #edgelist stuff ge=get.edgelist(g) ge=ge-1; #order from 0 ge=data.frame(ge) #nodelist stuff. iGraph starts vertext count at zero, so adjust that. #also add degree as a node-level variable we can use to plot with gn=data.frame(NodeID=as.numeric(V(g)-1),Nodesize=(degree(g))) #look at plotting options ??igraph.plot #help bits #basic default plot plot(g) #pretty ugly...arrows are too big and labes are #in the way. So let's specify those with the #igraph options remove those: plot(g, edge.arrow.size=.2,vertex.label=NA) #better, the layout is not optimal...lots of node #overlap and such. Let's see what else we can do... #Fruchterman Rheingold is a good default: plot(g, edge.arrow.size=.2,vertex.label=NA, layout=layout_with_fr) #you can see the basic clustering here some, let's highlight #that with a community detection clustering imc<-cluster_infomap(g) membership(imc) plot(g, edge.arrow.size=.2,vertex.label=NA, layout=layout_with_fr, vertex.color=imc$membership) #add in some size information... plot(g, edge.arrow.size=.2,vertex.label=NA, layout=layout_with_fr, vertex.color=imc$membership, vertex.size=degree(g,mode = "in")) #arcs are still hard to see...lets adjust a little more... plot(g, edge.arrow.size=.1,vertex.label=NA, layout=layout_with_fr, vertex.color=imc$membership, vertex.size=degree(g,mode = "in"), edge.curved=.2) #lets try a dif layout plot(g, edge.arrow.size=.1,vertex.label=NA, layout=layout_with_kk, vertex.color=imc$membership, vertex.size=degree(g,mode = "in"), edge.curved=.2) #default plot(g, edge.arrow.size=.1,vertex.label=NA, layout=layout_nicely, vertex.color=imc$membership, vertex.size=degree(g,mode = "in"), edge.curved=.2) #MDS plot(g, edge.arrow.size=.1,vertex.label=NA, layout=layout_with_mds, vertex.color=imc$membership, vertex.size=degree(g,mode = "in"), edge.curved=.2) #some rarely used/not so effective styles: #Circle - really only useful for very small networks plot(g, edge.arrow.size=.1,vertex.label=NA, layout=layout_in_circle, vertex.color=imc$membership, vertex.size=degree(g,mode = "in"), edge.curved=.2) #random -- no idea why you'd use this plot(g, edge.arrow.size=.1,vertex.label=NA, layout=layout_randomly, vertex.color=imc$membership, vertex.size=degree(g,mode = "in"), edge.curved=.2) #ditto plot(g, edge.arrow.size=.1,vertex.label=NA, layout=layout_on_sphere, vertex.color=imc$membership, vertex.size=degree(g,mode = "in"), edge.curved=.2) #cute way to get a list of them all...if you want #to try some...note they dont all apply to us, many #really only work well if the graph is a single connected #component (i.e. no isolates) layouts <- grep("^layout_", ls("package:igraph"), value=TRUE)[-1] layouts #another modification of the spring embedder plot(g, edge.arrow.size=.1,vertex.label=NA, layout=layout_with_graphopt, vertex.color=imc$membership, vertex.size=degree(g,mode = "in"), edge.curved=.2) #similar plot(g, edge.arrow.size=.1,vertex.label=NA, layout=layout_with_dh, vertex.color=imc$membership, vertex.size=degree(g,mode = "in"), edge.curved=.2) #these only work with fully only connected components, if your #graph is like that, give 'em a try #plot(g, edge.arrow.size=.2,vertex.label=NA, # layout=layout_with_drl, # vertex.color=imc$membership, # vertex.size=degree(g,mode = "in"), # edge.curved=.1) #plot(g, edge.arrow.size=.2,vertex.label=NA, # layout=layout_with_gem, # vertex.color=imc$membership, # vertex.size=degree(g,mode = "in"), # edge.curved=.1) detach("package:igraph", unload=TRUE) #an alternative is the GGPLoT network plotting tools #good choice if you already have the data in a statnet #style network object. library(GGally) library(sna) library(ggplot2) library(network) #need to coerce this into a network object #it assumes min value of 1 not zero, so adjust.. lm=ge+1; lm=as.matrix(lm) gnet=network(lm,matrix.type="edgelist",directed=TRUE) #lets add in our network attributes.. gnet %v% "cluster" <- imc$membership gnet %v% "degree" <- log(degree(gnet)) plot.network(gnet,vertex.col="cluster", vertex.cex="degree", arrowhead.cex = .5, jitter=T) ?plot.network #ggnet2 is another option #simplest default is, of course, but here are some others: ggnet2(gnet) ggnet2(gnet, node.size = "degree", node.color = "cluster", color.legend = "Cluster", edge.size = .5, arrow.size = 2, arrow.gap = 0.027)+ guides( size = FALSE) ?ggnet2 detach("package:GGally", unload=TRUE) #a nice way to implement contour plots -- thanks Jake! library(ggraph) library(ggnetwork) library(ggplot2) library(magrittr) ??ggnetwork #contour plot ggnetwork(gnet) %>% ggplot(aes(x = x, y = y, xend = xend, yend = yend)) + geom_edges(color = "lightgray") + geom_nodes(color = "blue") + theme_blank() + geom_density_2d() #interactve D3 layouts library(networkD3) #need edgelist & nodelist simpleNetwork(ge) ??networkD3 gn$group <- imc$membership forceNetwork(Links=ge, Nodes = gn, Source = "X1", Target = "X2", Group="group", Nodesize = "Nodesize", NodeID = "NodeID", opacity = 0.9, bounded=FALSE, opacityNoHover=.2) #if you want to pipe the image to a webpage, something like this #will work #forceNetwork(Links=ge, Nodes = gn, # Source = "X1", Target = "X2", Group="group", # Nodesize = "Nodesize", NodeID = "NodeID", # opacity = 0.9, bounded=FALSE, opacityNoHover=.2) %>% # saveNetwork(file = 'C:/jwm/Presentations/Viztalk/ah_comm1.htm') library('visNetwork') ??visNetwork #visNetwork needs a dataframe with "to" #and "from" columns, so change library(plyr) links <- rename(ge,c("X1" = "from", "X2" = "to")) nodes <- rename(gn,c('NodeID'="id")) #just a simple interactive plot .. really #almost exactly like the d3 plot above.. #note it might take a moment to run... visNetwork(nodes, links, width="100%", height="400px",main="Network!") #some alternative options...need to specify on the graph object nodes$shape <- "dot" nodes$shadow <- TRUE # Nodes will drop shadow nodes$size <- gn$Nodesize # Node size nodes$borderWidth <- .5 # Node border width nodes$color.background <- c("slategrey", "tomato", "gold", "red", "blue", "green","lightgray","lavender")[imc$membership] nodes$color.border <- "black" nodes$color.highlight.background <- "orange" nodes$color.highlight.border <- "darkred" visNetwork(nodes, links)