Data Visualization

Download R source file
            
              #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)