RMD file for explorign ggrepel and maps. Gist available here
library(rvest)
library(dplyr)
library(png)
library(sp)
library(maps)
library(rgeos)
library(grid)
library(ggplot2)
library(ggthemes)
Download a bunch of flag files from Wikipedia.
#' Download Map files from Wikimedia
process_flagname <- function(fname,outdir="./flags/", prefix="http:"){
flag <- strsplit(fname, ",")[[1]][[1]]
flag <- strsplit(flag, " ")[[1]][[1]]
flagimgname <- strsplit(flag, "/")[[1]][[9]]
countryname <- strsplit(flagimgname, "\\.")[[1]][[1]]
countryname <- strsplit(countryname, "_")[[1]][[3]]
flagurl <- paste0(prefix,flag)
newflag <- paste0(outdir, countryname,".png")
download.file(flagurl, destfile = newflag)
print(paste0("Downloading flag iamge for ", countryname, "."))
}
flags <- read_html("https://en.wikipedia.org/wiki/Gallery_of_sovereign_state_flags")
flagimages <- flags %>%
html_nodes(".thumbborder") %>%
html_attr("srcset")
#get all the images
#lapply(flagimages, process_flagname)
# df of the downloaded flagfiles
flagfiles <- data.frame(flag = list.files("flags",pattern = "*.png"))
countries <- as.character(
lapply(as.character(flagfiles$flag), function(x){strsplit(x,"\\.")[[1]][[1]]}))
flagfiles$country <- countries
findboxes <- function(df, xcol, ycol, pad_point_x, pad_point_y, xlim, ylim,
force = 1e-6, maxiter = 20000) {
#x and y posiitons as a dataframe
posdf <- df[c(xcol,ycol)]
#returnd a df where columns are points
boxdf <- apply(posdf,1,function(row) { xval <- row[xcol]
yval <- row[ycol]
return(c(xval,
yval,
xval + pad_point_x,
yval + pad_point_y))})
# columns are x1,y1,x2,y2
boxmatrix = as.matrix(t(boxdf))
moved <- ggrepel:::repel_boxes(data_points=as.matrix(posdf),
pad_point_x=0.1,
pad_point_y=0.1,
boxes = boxmatrix,
xlim=xlim,
ylim=ylim,
force=force,
maxiter=maxiter)
finaldf <- cbind(posdf, moved)
names(finaldf) <- c("x1","y1","x2","y2")
return(finaldf)
}
Process countries and get centroid starting positions.
# get centroids of countries
world <- map_data("world")
getLabelPoint <- function(country) {
rgeos::gCentroid(SpatialPoints(country[c('long','lat')]))}
centroids <- by(world, world$region, getLabelPoint)
centnames <- names(centroids)
centroids <- as.data.frame(do.call(rbind, centroids) )
row.names(centroids) <- centnames
names(centroids) <- c('long', 'lat')
gg <- ggplot(world)
gg <- gg + geom_map(
data=world,
map=world,
aes(x=long,y=lat, map_id=region),
fill="grey80")
gg <- gg + theme_map()
gg
Don’t use ggrepel, just place them on the map.
centroids %>%
add_rownames("country") %>%
inner_join(flagfiles, by=c("country")) %>%
mutate(pngfile = paste0("./flags/",flag)) -> flagfiles
apply(flagfiles,
1,
function(x)
{img <- readPNG(x['pngfile'])
g <- rasterGrob(img, interpolate=TRUE)
lat <- as.numeric(x['lat'])
long <- as.numeric(x['long'])
return(list(grob=g, long=long,lat=lat))
}) -> grobs
addmap <- function(gg,g){
grob <- g$grob
lat <- g$lat
long <- g$long
#print(paste(lat,long))
xdiff = 5
ydiff = 5
gg <- gg + annotation_custom(grob,
xmin = long - xdiff,
xmax = long + xdiff,
ymin = lat - ydiff,
ymax = lat + ydiff)
return(gg)
}
# create Map
Reduce(addmap,grobs,gg)
newcentroids <- findboxes(centroids, xcol = 'long', ycol='lat',
pad_point_x = 10, pad_point_y = 10,
xlim = c(-180,180), ylim=c(-60,60),
force=0.2,
maxiter = 1000)
newcentroids %>%
add_rownames("country") %>%
inner_join(flagfiles, by=c("country")) %>%
mutate(pngfile = paste0("./flags/",flag)) -> newflagfiles
apply(newflagfiles,
1,
function(x)
{img <- readPNG(x['pngfile'])
g <- rasterGrob(img, interpolate=TRUE)
lat <- as.numeric(x['y2'])
long <- as.numeric(x['x2'])
return(list(grob=g, long=long,lat=lat))
}) -> newgrobs
gg2 <- gg + geom_point(data=newflagfiles, aes(x1,y1))
gg2 <- gg2 + geom_segment(data=newflagfiles, aes(x1,y1,xend=x2,yend=y2))
Reduce(addmap,newgrobs,gg2)
newcentroids <- findboxes(centroids, xcol = 'long', ycol='lat',
pad_point_x = 10, pad_point_y = 10,
xlim = c(-180,180), ylim=c(-60,60),
force=0.8,
maxiter = 1000)
newcentroids %>%
add_rownames("country") %>%
inner_join(flagfiles, by=c("country")) %>%
mutate(pngfile = paste0("./flags/",flag)) -> newflagfiles
apply(newflagfiles,
1,
function(x)
{img <- readPNG(x['pngfile'])
g <- rasterGrob(img, interpolate=TRUE)
lat <- as.numeric(x['y2'])
long <- as.numeric(x['x2'])
return(list(grob=g, long=long,lat=lat))
}) -> newgrobs
gg2 <- gg + geom_point(data=newflagfiles, aes(x1,y1))
gg2 <- gg2 + geom_segment(data=newflagfiles, aes(x1,y1,xend=x2,yend=y2))
Reduce(addmap,newgrobs,gg2)