#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)