-
-
Save zhiboz/9c4fd5a5b4f350d4ac43cc4057db55db to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#==========================================================# | |
# Visualizing Facebook networks with friend photos # | |
# Katya Ognyanova, www.kateto.net, @ognyanova # | |
#==========================================================# | |
# Find more details at http://bit.ly/fbgephi | |
#==========================================================# | |
#### Collect the data using the RFacebook package #### | |
install.packages("Rfacebook") | |
library(Rfacebook) | |
# To get authenticated, first register as a developer here: | |
# https://developers.facebook.com/apps and create a new app. | |
# Then replace "123456789" below with the actual info | |
# you'll find in the "Settings" panel of your app. | |
# You also need to set Settings -> Website -> Site URL | |
# there to be http://localhost:1410/ | |
oauth <- fbOAuth(app_id = "123456789", | |
app_secret = "123456789", | |
extended_permissions = T) | |
save(oauth, file="fb_oauth") | |
# load(file="fb_oauth") | |
# Get friend info: | |
my.friends <- getFriends(oauth, simplify=F) | |
head(my.friends) | |
colnames(my.friends) | |
# Get friend network in two formats, matrix and edgelist: | |
fb.net.mat <- getNetwork(oauth, format = "adj.matrix")+0 # boolean, +0 to get numeric | |
fb.net.el <- as.data.frame(getNetwork(oauth, format = "edgelist")) | |
#==========================================================# | |
#### Download friend profile photos from Fb #### | |
setwd("C:/Research/R") | |
dir.create("FbImages") | |
# Image file name and local path stored here: | |
my.friends$picture.dld <- NA | |
# Download the images: | |
for (i in 1:dim(my.friends)[1]) { | |
# Fb images appear to be mostly JPEGs, except for people | |
# with no profile pics - for those we seem to get a default GIF | |
pic.ext <- ".jpg" | |
if(grepl(".gif$", my.friends$picture[i])) pic.ext <- ".gif" | |
# We'll name files using people's full names plus file extension. | |
my.friends$picture.dld[i] <- paste0("FBImages/", sub(" ", "_", my.friends$name[i]), pic.ext) | |
# Some users have UTF-8 encoded names that don't work well as file names: | |
if (Encoding(my.friends$name[i])=="UTF-8") { | |
my.friends$picture.dld[i] <- paste0("FBImages/", "FbID_", my.friends$id[i], pic.ext) } | |
download.file(my.friends$picture[i], my.friends$picture.dld[i], mode = 'wb') | |
} | |
#==========================================================# | |
#### Save the data for import into Gephi #### | |
# Two files: an edgelist csv containing Source and Target columns, | |
# and a node attributes csv, containing IDs that match those in the | |
# Source/Target columns. To use the Gephi Image preview plugin, | |
# we also need a column called "image" and containing | |
# the file name of each picture. | |
colnames(fb.net.el) <- c("Source", "Target") | |
my.friends$ID <- my.friends$name | |
my.friends$image <- gsub("FBImages/(*.)", "\\1", my.friends$picture.dld) | |
write.csv(fb.net.el, file="Facebook-friend-EDGES.csv", row.names=F) | |
write.csv(my.friends, file="Facebook-friend-NODES.csv" row.names=F) | |
# Note that we could use other formats like gexf for the export/import, | |
# but in my experience for simple nets that just ends up being more work | |
# than going with the csv files. | |
#==========================================================# | |
#### Plot the network using the igraph package #### | |
require("png") | |
require("jpeg") | |
require("igraph") | |
fb.net <- graph.adjacency(fb.net.mat) | |
# Add node degree, node colors based on gender, and | |
# edge colors based on the color of the source node. | |
my.friends$degree <- degree(fb.net) | |
my.friends$color <- "gray45" | |
my.friends$color[my.friends$gender=="female"] <- "lightpink3" | |
my.friends$color[my.friends$gender=="male"] <- "lightblue" | |
fb.net.el$color <- my.friends$color[match(fb.net.el$Source, my.friends$name)] | |
l <- layout.fruchterman.reingold(fb.net, niter=10000,area=vcount(fb.net)^2.3, | |
repulserad=vcount(fb.net)^2.65) | |
png("Facebook-friends-net-IGRAPH.png", width = 2500, height = 2000) | |
plot(fb.net, vertex.size=my.friends$degree/20, vertex.label=NA, | |
vertex.color=my.friends$color, edge.color=fb.net.el$color, | |
edge.width=1, edge.arrow.size=0, edge.curved=0.3, layout=l) | |
dev.off() | |
# Now plot using images for the nodes: | |
# Rescale the layout so it goes from -1 to 1 | |
l <- layout.norm(l, -1, 1, -1, 1) | |
png("Facebook-friends-net-IGRAPH-Photos.png", width = 2500, height = 2000) | |
plot(fb.net, vertex.size=4, vertex.label=NA, edge.color=fb.net.el$color, | |
vertex.shape="square",vertex.color="white", vertex.frame.color="white", | |
edge.width=1, edge.arrow.size=0, edge.curved=0.2, layout=l) | |
img.sc <- 0.03 #Image scaling | |
for (i in 1:dim(l)[1]) { | |
img <- my.friends$picture.dld[i] | |
img <- if(grepl(".jpg", img)) readJPEG(img) else "gray20" | |
rasterImage(img, l[i,1]-img.sc, l[i,2]-img.sc, l[i,1]+img.sc, l[i,2]+img.sc) | |
} | |
dev.off() | |
detach(package:png) | |
detach(package:jpeg) | |
detach(package:igraph) | |
#==========================================================# | |
#### Plot the network using the qgraph package #### | |
require("png") | |
require("qgraph") | |
png("Facebook-friends-net-QGRAPH.png", width = 2500, height = 2000) | |
qgraph(fb.net.mat, images = my.friends$picture.dld, labels = F, | |
borders = F, esize=0.1, curve=0.2, curveAll=T, edge.color="gray55") | |
dev.off() | |
detach(package:png) | |
detach(package:qgraph) | |
#==========================================================## |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment