Code
library(igraph)
library(readr)
library(RColorBrewer)
This is a cheat sheet for the third homework. It works through each step in R.
First, you need the following packages.
library(igraph)
library(readr)
library(RColorBrewer)
First, we are going to construct the toy graph. We can make an edge list based on how the nodes are connected to one another.
And make a vector of node colors that correspond to each of the nodes.
<- c(1,2, 1,3, 1,6, 2,3, 2,5, 3,4, 3,5, 6,2)
edges
<- c("yellow", "red", "green", "yellow", "red", "green") colors
Now we can use the graph function in igraph to read the graph into an igraph object and assign the color in the function.
<- graph(edges, directed=T)
t.g
plot(t.g, vertex.color=colors, edge.arrow.size=.5)
You could also assign colors as vertex attribute in the igraph object. Then you don’t have to. assign colors inside the graph function.
V(t.g)$color <- colors
plot(t.g, edge.arrow.size=.5)
First we load the data from the Game of Thrones book and inspect.
<- read_csv("data/stormofswords.csv")
stormofswords
head(stormofswords)
# A tibble: 6 × 3
Source Target Weight
<chr> <chr> <dbl>
1 Aemon Grenn 5
2 Aemon Samwell 31
3 Aerys Jaime 18
4 Aerys Robert 6
5 Aerys Tyrion 5
6 Aerys Tywin 8
We can see that this is a weighted edgelist in a data frame. So, we can use graph_from_data_frame to make an igraph object. If we return the graph name, we can see the graph summary. We can also see an initial plot.
<- graph_from_data_frame(stormofswords)
thr.g
#Let's take a peek at the graph summary
thr.g
IGRAPH db58165 DN-- 107 352 --
+ attr: name (v/c), Weight (e/n)
+ edges from db58165 (vertex names):
[1] Aemon ->Grenn Aemon ->Samwell Aerys ->Jaime Aerys ->Robert
[5] Aerys ->Tyrion Aerys ->Tywin Alliser->Mance Amory ->Oberyn
[9] Arya ->Anguy Arya ->Beric Arya ->Bran Arya ->Brynden
[13] Arya ->Cersei Arya ->Gendry Arya ->Gregor Arya ->Jaime
[17] Arya ->Joffrey Arya ->Jon Arya ->Rickon Arya ->Robert
[21] Arya ->Roose Arya ->Sandor Arya ->Thoros Arya ->Tyrion
[25] Balon ->Loras Belwas ->Barristan Belwas ->Illyrio Beric ->Anguy
[29] Beric ->Gendry Beric ->Thoros Bran ->Hodor Bran ->Jojen
+ ... omitted several edges
#Initial plot
plot(thr.g)
The plot is a bit messy and it is hard to make much sense of it, so let’s add some additional information.
We can add the houses as attributes
load("~/Documents/GitHub/sna_course/week_3_visualization/week3_visualization/data/got_att.rda") #This point to where attribute file is located
#Inspect thing
head(got_att)
names degree house
1 Aemon 5 0
2 Aerys 4 0
3 Alliser 3 0
4 Amory 1 0
5 Arya 19 2
6 Balon 6 0
We can see there are names, degree, and the house (0=“Other”, 1=“Lannister”, 2=“Stark”, 3=“Tagaryen”, 4=“Baratheon”)
Let’s store those in the vertices
And plot with the setting vertex color by house and vertex size by degree, and edge width by weight
V(thr.g)$degree <- got_att$degree
V(thr.g)$house <- got_att$house
plot(thr.g, vertex.color=V(thr.g)$house+1, vertex.size=V(thr.g)$degree/2, edge.arrow.size=.1, edge.width=E(thr.g)$Weight/10,
layout=layout_with_kk)
It might be nice to include a legend. The Moody and Light 2020 tutorial describes how to accomplish that.
Start with the RColorBrewer Package and index the colors. Then connect the colors to the house attribute as a factor and plot.
library(RColorBrewer)
#Index the colors
<- brewer.pal(5, "Accent")
pal
#Connect the colors to the house attribte as a factor
<- (pal[as.numeric(as.factor(vertex_attr(thr.g, "house")))])
vertex.col
#plot...note I adjust the color by making more transparent (alpha=)
plot(thr.g, vertex.color=adjustcolor(vertex.col, alpha=.75), vertex.label=NA, vertex.size=V(thr.g)$degree/2, edge.arrow.size=.1,
edge.width=E(thr.g)$Weight/10, layout=layout_with_kk)
#Add legend (see https://www.rdocumentation.org/packages/graphics/versions/3.6.2/topics/legend)
legend("topleft", title="House", bty = "n", #set location, legend title, and box type
legend=c("Other","Lannister", "Stark", "Tagaryen", "Baratheon"), #legend words
fill=pal, border=NA) #fill of circles and we don't need a border