Today, we are working in Markdown so you can see your work as you
proceed. We will be using igraph exclusively. But all the
lessons that you learn will work for any network or network
visualization software.
In the end, you just want to be effective.
So, start by initiating loading the igraph library and loading the data for today.
To create a code chunk:
library(igraph)
##
## Attaching package: 'igraph'
## The following objects are masked from 'package:stats':
##
## decompose, spectrum
## The following object is masked from 'package:base':
##
## union
# Load networks
load("data/allege.rda")
load("data/negative.rda")
load("data/positive.rda")
load("data/secrets.rda")
load("data/sentiment.rda")
# allege <- graph_from_adjacency_matrix(as.matrix(allege))
Note to self: Look iup “markdown cheat sheets” for R Studio to learn
more.
At this point, you should have five networks in R’s memory: allege, negative, positive, secrets, and sentiment.
Now, you are ready to start.
Use visualization to illustrate analysis or develop your initial opinions.
Here is a first look at the two networks. To keep it interesting, let’s put them together in one row (and two columns).
We should also set some options now so that we don’t have to keep adding arguments to each plot.
In this case, the code chunk below is telling igraph to use the Kamada Kawaii algorithm for each visualization it draws. It will also decrease the size of the arrowheads to 0.2 (the default is 1).
igraph_options(plot.layout=layout_with_kk,
edge.arrow.size=0.2,
vertex.label.cex=0.5)
#global options
Now, plot the networks.
par(mfrow=c(2,2), mar=c(0.5,0,2,0))
# make a two row, two column table of plots. margins (bottom, left, top, right) (default is 1 1 2 1)
plot(positive, main="Positive Sentiment")
plot(negative, main="Negative Sentiment")
plot(allege, main="Made Allegations About")
plot(secrets, main="Knows a Secret About")
par(mfrow=c(1,1))
#make the plot window plot just one graph at a time
This doesn’t mean that you can be arbitrary about which layout to
select. Rather, the relative position of the nodes should not be taken
as a demonstration that two nodes are necessarily similar or different.
You are looking at what happens when we try to fit a multidimensional
object into two dimensions.
#### There is no one “best” plotting solution.
Try out a range of options for plotting the networks. Each plotting algorithm is meant to work with a different type of network situation. For a list of the potential graphing algorithms in igraph, try:
?layout_
…or you can also try out some other options, such as manipulating the
plot yourself with tkplot() or using 3-D with
rglplot(). But those options are fairly rudimentary
compared with some of the newer options that you have these days.
For more on that, check out visNetwork(). That will
start you down a rabbit hole.
In this case, we are going to learn how to take and reuse coordinates from one plot in others.
First, take the x and y coordinates of each node using this code:
coords <- layout_with_kk(positive)
Now, let’s plot that again…
par(mfrow=c(2,2), mar=c(0.5,0,2,0))
# make a two row, two column table of plots. margins (bottom, left, top, right) (default is 1 1 2 1)
plot(positive, main="Positive Sentiment", layout=coords)
plot(negative, main="Negative Sentiment", layout=coords)
plot(allege, main="Made Allegations About", layout=coords)
plot(secrets, main="Knows a Secret About", layout=coords)
par(mfrow=c(1,1))
#make the plot window plot just one graph at a time
Now, if you like that, then you can add the coordinates to each network. We add the coordinates as an x and y attribute of the vertices. coors [rows, columns]
V(positive)$x <- coords[ ,1]
V(positive)$y <- coords[ ,2]
V(negative)$x <- coords[ ,1]
V(negative)$y <- coords[ ,2]
V(allege)$x <- coords[ ,1]
V(allege)$y <- coords[ ,2]
V(secrets)$x <- coords[ ,1]
V(secrets)$y <- coords[ ,2]
Next, remove isolates and name the new networks something unique so you don’t overwrite the original networks. They will plot according to their coordinates, unless you tell them to do something else.
The priorities are always communication and clarity.
A simpler approach is generally more powerful.
Depict no more than 2 or 3 properties at a time.
Attributes can add a lot of information to a visualization.
atts <- read.csv("data/character_attributes.csv", header=TRUE)
Before you try to add attributes, make sure that the nodes in the network appear in the same order as the nodes in the attribute sheet.
cbind(V(positive)$name, atts[ ,1])#bind the two into columns so we can compare them
Then, add the attributes to each network.
V(positive)$family <- atts[ ,2]
V(positive)$employed <- atts[ ,3]
V(positive)$sex <- atts[ ,4]
V(negative)$family <- atts[ ,2]
V(negative)$employed <- atts[ ,3]
V(negative)$sex <- atts[ ,4]
V(allege)$family <- atts[ ,2]
V(allege)$employed <- atts[ ,3]
V(allege)$sex <- atts[ ,4]
V(secrets)$family <- atts[ ,2]
V(secrets)$employed <- atts[ ,3]
V(secrets)$sex <- atts[ ,4]
Finally, save your work.
save(positive, file="data/positive.rda")
save(negative, file="data/negative.rda")
save(allege, file="data/allege.rda")
save(secrets, file="data/secrets.rda")
Node
Categorical
Color
Shape
Label size
Layout
Continuous
Size
Color
Layout
Label (Color or Size)
Tie
Categorical
Color
Label
Line type (solid, dotted, dashed, curved)
Continuous
Size
Arrow size
Label (value, size, color)
Emphasize and compare
Removing or hiding
Removing certain nodes
Minimize all but a few labels
Compare networks
Save coordinates
Larger and denser networks will be more difficult to visualize
If you go to the trouble to create good work. Then spend some effort at saving it in high quality format.
Screenshots are garbage and should be treated as such. Instead, save your work as a high quality jpeg, png, pdf, or similar. It is worth the extra effort.
jpeg("plot_name.jpg", # Name the plot
width=5, height=5, # Set the size of the plot area
units="in", res=400) # Here, we are using inches. You can switch
# to "cm" if you prefer. "res" is resolution
# 400 is ok... prob higher res
plot.igraph(network, # add your network here
vertex.label.cex=0.5)
dev.off() # Don't forget this part.
# It ends the process and saves your work.
For example, see below:
jpeg("The Trial Plot.jpg",
width=7, height=7,
units="in", res=400)
par(mfrow=c(2,2), mar=c(0.5,0,2,0))
# make a two row, two column table of plots. margins (bottom, left, top, right) (default is 1 1 2 1)
plot(positive, main="Positive Sentiment", layout=coords)
plot(negative, main="Negative Sentiment", layout=coords)
plot(allege, main="Made Allegations About", layout=coords)
plot(secrets, main="Knows a Secret About", layout=coords)
par(mfrow=c(1,1))
#make the plot window plot just one graph at a time
dev.off()
## quartz_off_screen
## 2