This week I was impressed by this tweet where Daniel Pett, Digital Humanities Lead at the British Museum, presented a collage of Twitter profile pics of all his colleagues. He made this piece of art using R (for collecting the usernames) and Python. I’m a bit of an R fanatic (or a Python dummy…) so I decided to write a code in R only to make a collage of profile pics of Twitter #rstats users.
Note: if you’re interested in Daniel Pett’s code, the data gathering is here and the montage code is here.
Getting the users
Once again I’ll use rtweet
! In case you’ve been using twitteR
, note that twitteR
maintainer is currently passing the torch to rtweet
so you’d better switch packages.
library("rtweet")
library("dplyr")
library("magick")
library("httr")
library("stringr")
library("purrr")
users <- search_users(q= '#rstats',
n = 1000,
parse = TRUE)
users <- unique(users)
I think that doing this I got only profiles whose description includes “rstats” or “#rstats”. Moreover, although I got 1,000 results, many of them were duplicates, so in the end I had about 450 #rstats Twitter users.
Gathering profile pics
This is the part where I felt slightly creepy downloading pictures of so many people.
I first had to create the link to each person’s profile page.
users <- mutate(users,
where = paste0("https://twitter.com/",
screen_name))
Then I wrote a function for getting the profile pic for each user. I worked for everyone except 1) eggs and 2) a person whose profile pic had no extension, so I was quite satisfied with the result.
Update: Daniel Pett told me I could have used the column “profile_image_url” of the data.frame obtained from rtweet::search_users
… I had completely missed that column! Thanks a lot!
get_piclink <- function(df){
content <- httr::GET(df$where)
content <- httr::content(content, as = "text")
image <- str_extract(content,
"class=\"ProfileAvatar-image \" src=\"https://pbs.twimg.com/profile_images/.*\\..*\" alt")
image <- str_replace(image, "class=\"ProfileAvatar-image \" src=\"", "")
image <- str_replace(image, "..alt", "")
return(image)
}
users <- by_row(users, get_piclink,
.to = "piclink", .collate = "cols")
readr::write_csv(users, path = "users.csv")
After getting the links I could start saving the pictures, in a small 50px x 50px format. At that point I started using the magick
package, a real game changer for image manipulation in R!
save_image <- function(df){
image <- try(image_read(df$piclink), silent = TRUE)
if(class(image)[1] != "try-error"){
image %>%
image_scale("50x50") %>%
image_write(paste0("data/2017-03-19-facesofr_users_images/", df$screen_name,".jpg"))
}
}
users <- filter(users, !is.na(piclink))
users <- split(users, 1:nrow(users))
walk(users, save_image)
I got 448 images.
Preparing the collage itself
I want to take a minute thinking about myself in elementary school. I am left-handed and I had scissors for right-handed people that I used with my left hand because no one in my family or school knew any better. I was therefore very bad at collages because of the cutting part. Had I known that I’d do collages with a computer as a grown-up, I would have been less sad to have to skip the break to keep on slowly cutting pieces of paper! (Note: I actually had a very happy childhood.)
Back to R talk now! For doing the collage I had to know how many columns and rows I wanted. For this I factorized the number of pics I had. Note that I also re-sampled the images, because I didn’t want all the R-Ladies chapters and their beautiful purple logo to end up near each other in the collage.
files <- dir("data/2017-03-19-facesofr_users_images/", full.names = TRUE)
set.seed(1)
files <- sample(files, length(files))
gmp::factorize(length(files))
## Big Integer ('bigz') object of length 7:
## [1] 2 2 2 2 2 2 7
Based on this I chose this format:
no_rows <- 28
no_cols <- 16
In magick
there’s a function for appending images, image_append
, from which you get either a row or a column depending on the stack
argument. I first created all columns.
make_column <- function(i, files, no_rows){
image_read(files[(i*no_rows+1):((i+1)*no_rows)]) %>%
image_append(stack = TRUE) %>%
image_write(paste0("cols/", i, ".jpg"))
}
walk(0:(no_cols-1), make_column, files = files,
no_rows = no_rows)
And finally, I appended the columns!
image_read(dir("cols/", full.names = TRUE)) %>%
image_append(stack = FALSE) %>%
image_write("2017-03-19-facesofr.jpg")
The end
Here is the result, where many, many R users are most certainly missing. Besides, can we talk about these accounts with the old R logo? They make me feel old, while the R-Ladies logo make me happy. Too bad Forwards wasn’t included, because their logo is really pretty.
![facesofr](https://masalmon.eu/figure/2017-03-19-facesofr.jpg)
Now you can try doing the same with your followers, the people you follow, or making a doormat with base plot advocates.