Skip to content

Instantly share code, notes, and snippets.

@kateto
Last active November 22, 2021 20:13
Show Gist options
  • Save kateto/11092938 to your computer and use it in GitHub Desktop.
Save kateto/11092938 to your computer and use it in GitHub Desktop.
#==========================================================#
# 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)
#==========================================================##
@MohanBunny
Copy link

Correct the FBImages directory names in loop

@brianpenghe
Copy link

brianpenghe commented Oct 25, 2017

got this error:

Copy and paste into Site URL on Facebook App Settings: http://localhost:1410/
When done, press any key to continue...
Waiting for authentication in browser...
Press Esc/Ctrl + C to abort
Authentication complete.
Error in oauth2.0_access_token(endpoint, app, code = code, user_params = user_params, :
Bad Request (HTTP 400). Failed to get an access token.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment