Examples pulled from Network Visualization with R, Polnet 2016 by Katya Ognyanova.

suppressPackageStartupMessages({
  library(RColorBrewer)
  library(readr)
  library(dplyr)
  library(igraph)
})
data_dir <- file.path("inst", "doc", "shiny_logic")
data_dir <- "../extdata"

For igraph plotting parameters, node options start with vertex. and edge options start with edge.. Get options with

?igraph.plotting

Set node & edge options in two ways:

  1. specify them in plot() function
  2. add them to the igraph object

Basic igraph with Dataset 1

nodes <- 
   read_csv(file.path(data_dir,
                      "qtl2shinyNode.csv"))
links <- 
   read_csv(file.path(data_dir, 
                      "qtl2shinyEdge.csv"))

Convert dataset 1 to an igraph object. The graph_from_data_frame() function takes two data frames, d (edges of the network) and vertices (nodes). d has (at least) two columns with source and target node IDs for each network tie. vertices has (at least) a column of node IDs. Additional columns in either data frame are interpreted as attributes.

(net <- graph_from_data_frame(d=links, vertices=nodes, directed=T)) 

Access nodes, edges, and attributes:

E(net)
V(net)

Find specific nodes and edges by attribute

V(net)[type=="shiny"]
V(net)[logic=="reactive"]

Extract an edge list or matrix from igraph networks.

tibble::as_tibble(as_edgelist(net, names=T))
as_adjacency_matrix(net)

Look at network matrix directly:

net[1,]
net[5,7]

Plot graph, removing loops and labels, and reducing arrow size.

net <- simplify(net, remove.multiple = F, remove.loops = T) 
plot(net, 
     edge.arrow.size = 0.4,
     vertex.label = NA)

Annotating a graph

Using options to plot

Plot with curved edges (edge.curved=.1) and reduce arrow size. Using curved edges reveals multiple links between two nodes (e.g. links going in either direction, or multiplex links).

plot(net, edge.arrow.size=.4, edge.curved=.1)

Set node color to orange and the border color to hex #555555. Replace the vertex label with the node names stored in media.

plot(net, edge.arrow.size=.4, edge.curved=0,
     vertex.color="orange", vertex.frame.color="#555555",
     vertex.label=V(net)$media, vertex.label.color="black",
     vertex.label.cex=.7) 

Semantic network with only node labels.

plot(net, vertex.shape="none", vertex.label=V(net)$name, 
     vertex.label.font=2, vertex.label.color="gray40",
     vertex.label.cex=0.7, edge.color="gray90")

Using graph attributes

# Generate colors based on media type:
colrs <- c("skyblue", "tomato", "lightgrey", "gold","lightgreen")
V(net)$color <- colrs[factor(V(net)$type)]

# Compute node degree (#links) and use it to set node size:
deg <- degree(net, mode="all")
V(net)$size <- sqrt(deg)*5
#V(net)$size <- V(net)$audience.size*0.6

# The labels are currently node IDs.
# Setting them to NA will render no labels:
V(net)$label.color <- "black"
V(net)$label <- NA

# Set edge width based on weight:
#E(net)$width <- E(net)$weight/6

#change arrow size and edge color:
E(net)$arrow.size <- .2
E(net)$edge.color <- "gray80"

plot(net) 

Override attributes explicitly in the plot

plot(net, edge.color="orange", vertex.color="gray50") 

Legend

Add legend explaining color meaning.

plot(net) 
legend(x = -1.1, y = -1.1,
       c("list","module", "output", "shiny","table"), 
       pch = 21,
       col = "#777777", pt.bg = colrs, 
       pt.cex = 2.5, 
       bty = "n", ncol = 1)
netModule <-
  delete_vertices(
    delete_edges(
      net,
      E(net)[assign == "output"]),
    unclass(V(net)[shiny != "module"]))
plot(netModule)
plot(netModule, vertex.shape="none", vertex.label=V(netModule)$name, 
     vertex.label.font=2, vertex.label.color="gray40",
     vertex.label.cex=0.5, edge.color="gray50")
jpeg("net.jpg", width = 700, height = 700)
plot(netModule, vertex.shape="none", vertex.label=V(netModule)$name, 
     vertex.label.font=2, vertex.label.color="black",
     vertex.label.cex=0.75, edge.color="gray50",
     layout = layout_as_tree)
dev.off()

See https://stackoverflow.com/questions/7521381/draw-network-in-r-control-edge-thickness-plus-non-overlapping-edges about non-overlapping edges.

Try layout-on-grid https://www.reddit.com/r/rstats/comments/3idbde/igraph_help_vertex_spacing/

Highlight Graph Aspects

Color graph edges based on source node color. Here ends() gives us the start and end for each edge in es, and names controls whether ends() will return node names or IDs.

edge.start <- ends(net, es=E(net), names=F)[,1] # get the "from" node
edge.col <- V(net)$color[edge.start]
plot(net, edge.color = edge.col, edge.curved = .1)
knitr::knit_exit()

Keep only edges with weight higher than network mean using delete_edges(net, edges).

cut.off <- mean(links$weight) 
net.sp <- delete_edges(net, E(net)[weight<cut.off])
plot(net.sp) 

Plot two tie types (hyperlink and mention) separately.

E(net)$width <- 1.5
net.m <- net - E(net)[E(net)$type=="hyperlink"] # another way to delete edges:
net.h <- net - E(net)[E(net)$type=="mention"]   # using the minus operator
par(mfrow=c(1,2))
plot(net.h, vertex.color="orange", main="Tie: Hyperlink")
plot(net.m, vertex.color="lightsteelblue2", main="Tie: Mention")

Force nodes to stay in place for both plots.

l <- layout_with_fr(net)
par(mfrow=c(1,2))
plot(net.h, vertex.color="orange", layout=l, main="Tie: Hyperlink")
plot(net.m, vertex.color="lightsteelblue2", layout=l, main="Tie: Mention")

Show network communities.

par(mfrow=c(1,2))

# Community detection based on label propagation:
clp <- cluster_label_prop(net)
class(clp)

# Community detection returns an object of class "communities" 
# which igraph knows how to plot: 
plot(clp, net)

# We can also plot the communities without relying on their built-in plot:
V(net)$community <- clp$membership
colrs <- adjustcolor( c("gray50", "tomato", "gold", "yellowgreen"), alpha=.6)
plot(net, vertex.color=colrs[V(net)$community])

Highlight Distance to Node(s)

Focus on a particular node or group of nodes. In the example media network, examine spread of information from the NYT.

The distances() function returns a matrix of shortest paths from nodes listed in the v parameter to ones included in the to parameter.

(dist.from.NYT <- distances(net, v=V(net)[media=="NY Times"], 
                           to=V(net), weights=NA))

Set colors to plot the distances

oranges <- colorRampPalette(c("dark red", "gold"))
col <- oranges(max(dist.from.NYT) + 1)
col <- col[dist.from.NYT + 1]
plot(net, vertex.color = col,
     vertex.label = dist.from.NYT, 
     edge.arrow.size = .6, 
     vertex.label.color = "white")

Highlight a network path

(news.path <- shortest_paths(net, 
                            from = V(net)[media=="MSNBC"], 
                             to  = V(net)[media=="New York Post"],
                             output = "both")) # both path nodes and edges

Generate edge color and width and node color variables to plot path. Awkward, but it works.

ecol <- rep("gray80", ecount(net))
ecol[unlist(news.path$epath)] <- "orange"
ew <- rep(2, ecount(net))
ew[unlist(news.path$epath)] <- 4
vcol <- rep("gray40", vcount(net))
vcol[unlist(news.path$vpath)] <- "gold"
plot(net, 
     vertex.color = vcol, 
     edge.color = ecol, 
     edge.width = ew, 
     edge.arrow.mode = 0)

Highlight edges of a vertex, for instance the WSJ. For a single node, use incident(), for multiple nodes use incident_edges().

(inc.edges <- incident(net,  V(net)[media=="Wall Street Journal"], mode="all"))

Set colors to plot the selected edges.

ecol <- rep("gray80", ecount(net))
ecol[inc.edges] <- "orange"
vcol <- rep("grey40", vcount(net))
vcol[V(net)$media=="Wall Street Journal"] <- "gold"
plot(net, 
     vertex.color = vcol, 
     edge.color = ecol)

Highlight immediate neighbors of a vertex using neighbors() to find all nodes one step out from the focal actor. To find the neighbors for multiple nodes, use adjacent_vertices(). To find node neighborhoods going more than one step out, use function ego() with parameter order set to the number of steps out to go from the focal node(s).

(neigh.nodes <- neighbors(net, V(net)[media=="Wall Street Journal"], mode="out"))
vcol[neigh.nodes] <- "#ff9d00"
plot(net, vertex.color=vcol)

Highlight a group of nodes by marking them (recall network communities).

par(mfrow=c(1,2))
plot(net, 
     mark.groups = c(1,4,5,8), 
     mark.col = "#C5E5E7", 
     mark.border = NA)

# Mark multiple groups:
plot(net, 
     mark.groups = list(c(1,4,5,8), c(15:17)),
     mark.col = c("#C5E5E7","#ECD89A"), 
     mark.border = NA)

Other Views of Networks besides Hairballs

Heatmap of network matrix

netm <- as_adjacency_matrix(net, attr="weight", sparse=F)
colnames(netm) <- V(net)$media
rownames(netm) <- V(net)$media

palf <- colorRampPalette(c("gold", "dark orange")) 
heatmap(netm[,17:1], Rowv = NA, Colv = NA, col = palf(100), 
        scale="none", margins=c(10,10) )

Degree distribution for network.

deg.dist <- degree_distribution(net, cumulative=T, mode="all")
plot( x=0:max(deg), y=1-deg.dist, pch=19, cex=1.2, col="orange", 
      xlab="Degree", ylab="Cumulative Frequency")


byandell/qtl2shiny documentation built on June 11, 2025, 4:54 a.m.