This is a visualization that was made using data from American Fact Finder. A large portion is based on a tutorial done at Flowingdata.com. The dots location of the dots are randomly generated in each census location to get a general idea of where populations are most dense.
library(plyr)
library(maptools)
## Loading required package: sp
## Checking rgeos availability: TRUE
##
## Attaching package: 'maptools'
## The following object is masked from 'package:sp':
##
## nowrapSpatialLines
# Virginia population data
virpop <- read.csv("data/ACS_14_5YR_B01003_with_ann.csv", stringsAsFactors=FALSE)
virpop <- virpop[-1,]
virpop <- rename(virpop, c("GEO.id"= "geoid","GEO.id2"="geoid2", "GEO.display.label"="geoname", "HD01_VD01"="totalpop", "HD02_VD01"="maroferror"))
virpop.sub <- virpop[,c(2,4)]
virpop.sub$totalpop <- as.numeric(virpop.sub$totalpop)
# Virginia shapefile for Census tracts
vir.shp <- readShapePoly("data/cb_2015_51_tract_500k/cb_2015_51_tract_500k.shp", proj4string=CRS("+proj=longlat"))
virpolys <- SpatialPolygonsDataFrame(vir.shp, data=as(vir.shp, "data.frame"))
virdata <- merge(virpolys@data, virpop.sub, by.x="GEOID", by.y="geoid2", sort=FALSE)
virvar <- virdata$totalpop/200
par(mar=c(0,0,0,0))
virdots.rand <- dotsInPolys(virpolys, as.integer(virvar), f="random")
Each dot is represents a 200 people
plot(virpolys, lwd=0.1)
plot(virdots.rand, add=TRUE, pch=19, cex=0.1, col="#00880030")
# Merge race data with geography (multiple races)
virrace <- read.csv("data/ACS_14_5YR_B02001/ACS_14_5YR_B02001_with_ann.csv", stringsAsFactors=FALSE)
colnames(virrace) <- virrace[1, ]
virrace <- virrace[-1, ]
virrace <- rename(virrace, c("Estimate; Total: - White alone"= "White","Estimate; Total: - Black or African American alone"="Black", "Estimate; Total: - American Indian and Alaska Native alone"="American Indian", "Estimate; Total: - Asian alone"="Asian", "Estimate; Total: - Native Hawaiian and Other Pacific Islander alone"="Hawaiian"))
virrace.sub <- virrace[,c(2,6,8,10,12,14)]
virrace.sub$White <- as.numeric(virrace.sub$White)
virrace.sub$Black <- as.numeric(virrace.sub$Black)
virrace.sub$`American Indian` <- as.numeric(virrace.sub$`American Indian`)
virrace.sub$Asian <- as.numeric(virrace.sub$Asian)
virrace.sub$Hawaiian <- as.numeric(virrace.sub$Hawaiian)
virdata <- merge(virpolys@data, virrace.sub, by.x="GEOID", by.y="Id2", sort=FALSE)
races <- c("White", "Black", "American Indian", "Asian", "Hawaiian")
dotCols <- c("red", "blue", "violet", "yellow", "green")
Here each dot represents 50 people. red = White, blue = African American, violet = American Indian, yellow = Asian, green = Hawaiian
plot(virpolys, lwd=0.1)
for (i in 1:length(races)) {
virvar <- virdata[,races[i]] / 50
virdots.race <- dotsInPolys(virpolys, as.integer(virvar), f="random")
plot(virdots.race, add=TRUE, pch=19, cex=0.01, col=dotCols[i])
}