Contour Maps

Purpose:

When you have a bunch of data points with latitude and longitude, sticking all of them on a map is straightforward. But it can get cluttered in a hurry when you have a lot of dots on your map. Areas with a lot of points overlap. A contour map, on the other hand, can better show geographic density.

Data = 60k documented UFO sightings from Infochimps. Counts recorded for every 20 mile radius across the US.

getwd()
## [1] "/Users/hollyjones/Desktop/FlowingData/geopath"
setwd("/Users/hollyjones/Desktop/FlowingData/geopath/contour")
dir()
## [1] "build_matrix.py" "cnt_matrix.txt"  "ufo.R"
counts = read.csv("cnt_matrix.txt", header = FALSE)
#head(counts)
cnts_matrix = as.matrix(counts)
#head(cnts_matrix)

# Transform counts matrix
cnts_matrix = t(cnts_matrix[105:1,])

#remove default dimension names
dimnames(cnts_matrix)[[2]] = NULL

#default plot
#PROBLEM = counts matrix is sparse, high values visually dominate (i.e. you can only see dense city areas)
contour(cnts_matrix, main = "Default Plot")

#SOLUTION = One common way to unearth the lower values is to use a logarithmic scale
# Contour plot with logarithmic scale
#nlevels arg used to control granularity of markings
contour(log(cnts_matrix+1), xaxt = "n", yaxt = "n", nlevels = 10, col = rainbow(12), main = "UFO Sightings \n 1906 - 2007")

#Filled Contour Map to provide more contrast
#lighter areas indicate a higher number of UFO sightings
# Black-red-white palette for filled contours
redpal <- colorRampPalette(c("black", "red", "white"))
cyanpal <- colorRampPalette(c("black", "cyan", "white"))

# Make the filled contour plot
filled.contour(log(cnts_matrix+1), color.palette=cyanpal, nlevels=30, plot.axes = FALSE, main = "UFO Sightings \n 1906 - 2007")

Geopaths

Data = 1k running routes tracked by RunKeeper users in San Francisco.

getwd()
## [1] "/Users/hollyjones/Desktop/FlowingData/geopath"
setwd("/Users/hollyjones/Desktop/FlowingData/geopath/runpaths")
dir()
## [1] "map-paths.R"             "runkeeper-routes-sf.csv"
routes = read.csv("runkeeper-routes-sf.csv", stringsAsFactors = FALSE)
head(routes)
##   tempid latitude longitude
## 1      1 37.78913 -122.4170
## 2      1 37.79080 -122.4191
## 3      1 37.79890 -122.3984
## 4      1 37.79544 -122.3938
## 5      1 37.79307 -122.4028
## 6      1 37.78964 -122.4136
par(mar = c(4, 4, 4, 4))

#The most straightforward way to look at this data is with a dot plot - one point per location
plot(routes$latitude, routes$longitude, type = "n", main = "One Thousand Running Routes, \n San Francisco", xlab = "Latitude", ylab = "Longitude", las = 1, cex.axis = 0.7, cex.lab = 0.8, mgp=c(3,0.6,0.1))
points(routes$latitude, routes$longitude, pch = 20, cex = 0.3, col = "purple")

#adding lines instead of dots
#need to add a line for each recorded route
plot(routes$latitude, routes$longitude, type = "n", main = "Routes of 1,000 Unique Users", xlab = " ", ylab = " ", las = 1, cex.axis = 0.8,  mgp=c(3,0.6,0.1))
mtext("San Francisco RunKeeper Community")

head(routes)
##   tempid latitude longitude
## 1      1 37.78913 -122.4170
## 2      1 37.79080 -122.4191
## 3      1 37.79890 -122.3984
## 4      1 37.79544 -122.3938
## 5      1 37.79307 -122.4028
## 6      1 37.78964 -122.4136
route_id = unique(routes$tempid)
# there are 1k unique route_ids as expected
for(i in 1:length(route_id)) {
  curr_route = subset(routes, tempid == route_id[i])
  lines(curr_route$latitude, curr_route$longitude, col="#00000020", lwd=0.7)
}


##################################################################################################
# Introduce base map
##################################################################################################

library(ggmap)
## Loading required package: ggplot2

detailMap <- function(bbox, thedata) {
    basemap <- get_map(location=bbox, source='google', maptype="roadmap", color="bw")
    ggmap(basemap) + theme(axis.text = element_blank(), axis.ticks = element_blank(), axis.title = element_blank(), plot.title = element_text(lineheight=.8, face="bold", size = 20)) + geom_path(aes(x=longitude, y=latitude, group=tempid), size=0.3, color="blue", alpha=0.3, data=thedata)
}
sanfran <- c(-122.50476977783954, 37.70528090348771, -122.3619475122155, 37.83825794027055)
detailMap(sanfran, routes)
## Warning: bounding box given to google - spatial extent only approximate.
## converting bounding box to center/zoom specification. (experimental)
## Map from URL : http://maps.googleapis.com/maps/api/staticmap?center=37.771769,-122.433359&zoom=13&size=640x640&scale=2&maptype=roadmap&language=en-EN&sensor=false
## Warning: Removed 99 rows containing missing values (geom_path).

####################################################################################################