library(jsonlite) # for CNN JSON
library(purrr)    # for cleaner list ops
library(dplyr)    # data munging
library(sp)       # geo
library(maptools) # geo
library(rgeos)    # geo
library(tigris)   # tx map
library(ggplot2)  # plotting
library(ggthemes) # plotting themes
library(scales)   # plotting formatting
library(svglite)  # output SVGs
library(DT)       # nicer data frame output

CNN has surprisingly good primary/election data that one can get w/o much effort. We can use it to show how what percentage of each county a (Republican) candidate won (that shows how a county leans a bit better IMO).

tx <- fromJSON("",

We build a data.frame from the CNN JSON, only keeping the person with the most votes (%) per county

tx_heat <- mutate(map_df(tx$counties$race.candidates, function(x) {
  head(arrange(x, desc(vpct)), 1)
}), FIPS=tx$counties$countycode, vpct=vpct/100)

This is a perfect use-case for tigris. Get the county map and make it a bit more lightweight than it already is.

tx_shp <- counties("Texas", TRUE)
tx_shp <- SpatialPolygonsDataFrame(gSimplify(tx_shp, 0.01, TRUE), tx_shp@data)
tx_map <- fortify(tx_shp, region="GEOID")

Now, plot:

gg <- ggplot()
gg <- gg + geom_map(data=tx_map, map=tx_map,
                    aes(x=long, y=lat, map_id=id),
                    color="#2b2b2b99", fill=NA, size=0.1)
gg <- gg + geom_map(data=tx_heat, map=tx_map,
                    aes(fill=lname, alpha=vpct, map_id=FIPS),
                    color="#2b2b2b99", size=0.1)
gg <- gg + scale_fill_brewer(name="County\nwinner", palette="Dark2")
gg <- gg + scale_alpha_continuous(name="% Votes", labels=percent)
gg <- gg + coord_map()
gg <- gg + theme_map()
gg <- gg + theme(legend.position="right")