I want to draw a map of NYC using the function map() in R.
I tried doing something like this:
map('state', region = c('new york', 'new jersey'),
xlim=c(-74.12,-73.85), ylim=c(40.58,40.87))
Using the coordinates to zoom in, but the map looks small and not very readable.
Is there a better way to do this?
Thanks,
Elena
You can also stay in base graphics/ggplot and use better shapefiles. There are many NYC shapefiles (those are just a few). I grabbed the borough borders:
library(sp)
library(rgdal)
library(rgeos)
library(ggplot2)
library(ggthemes)
url <- "http://www.nyc.gov/html/dcp/download/bytes/nybb_15b.zip"
fil <- basename(url)
if (!file.exists(fil)) download.file(url, fil)
fils <- unzip(fil)
nyc <- readOGR(fils[1], ogrListLayers(fils[1])[1], stringsAsFactors=FALSE)
# base
plot(nyc, lwd=0.5, asp=1)
# ggplot2
# simplifying the polygons speeds up ggplot2 a bit
nyc_map <- fortify(gSimplify(nyc, 0.05))
gg <- ggplot()
gg <- gg + geom_map(data=nyc_map, map=nyc_map,
aes(x=long, y=lat, map_id=id),
color="black", fill="white", size=0.25)
gg <- gg + coord_equal()
gg <- gg + theme_map()
gg
That particular shapefile is pre-projected, so you just need to ensure a 1:1 aspect ratio for the plots.
Other shapefiles give varying levels of detail.
I may be wrong, but I don't think the maps package has high resolution map data for this kind of thing.
You could try the ggmap package instead:
library(ggmap)
mymap <- get_map(location = "New York", maptype = "roadmap")
ggmap(mymap)
See the ggmap paper for a brief intro to the package.
Related
For real, I searched everywhere, and coding a scale in a map is so hard...
Adding scale bar to ggplot map
Is there a way to add a scale bar (for linear distances) to ggmap?
Could it be possible to make a simple line that scale differently to the zoom preset that we select in the function?
I have this simple map:
library(ggmap)
pngMAP_df2 = get_map(location = c(-90.5, -0.5), source = "google", zoom = 8,color = "bw")
s = ggmap(pngMAP_df2)
s
I wanted to add as well GPS coordinate in this graph:
myGPS = data.frame(lat=c( -0.6850556,-0.6854722, -0.6857778 ),lon=c(-90.22275,-90.22261, -90.22272))
Is it easy to implement?
I just want to add something realllllllllly simple. Like a line with always a round number that give an indication of the zoom in the map.
Also, is it possible with this code to make the map look even simpler. Like seeing the water in white and the contour of the land in black?
Thanks,
Something like:
library(rgdal)
library(rgeos)
library(ggplot2)
library(ggthemes)
library(ggsn)
URL <- "https://osm2.cartodb.com/api/v2/sql?filename=public.galapagos_islands&q=select+*+from+public.galapagos_islands&format=geojson&bounds=&api_key="
fil <- "gal.json"
if (!file.exists(fil)) download.file(URL, fil)
gal <- readOGR(fil, "OGRGeoJSON")
# sample some points BEFORE we convert gal
rand_pts <- SpatialPointsDataFrame(spsample(gal, 100, type="random"), data=data.frame(id=1:100))
gal <- gSimplify(gUnaryUnion(spTransform(gal, CRS("+init=epsg:31983")), id=NULL), tol=0.001)
gal_map <- fortify(gal)
# now convert our points to the new CRS
rand_pts <- spTransform(rand_pts, CRS("+init=epsg:31983"))
# and make it something ggplot can use
rand_pts_df <- as.data.frame(rand_pts)
gg <- ggplot()
gg <- gg + geom_map(map=gal_map, data=gal_map,
aes(x=long, y=lat, map_id=id),
color="black", fill="#7f7f7f", size=0.25)
gg <- gg + geom_point(data=rand_pts_df, aes(x=x, y=y), color="steelblue")
gg <- gg + coord_equal()
gg <- gg + scalebar(gal_map, dist=100, location="topright", st.size=2)
gg <- gg + theme_map()
gg
This would be the complete answer with specific points on the map.
library(rgdal)
library(rgeos)
library(ggplot2)
library(ggthemes)
library(ggsn)
myGPS = data.frame(lat=c( -0.6850556,-0.6854722, -0.6857778 ),lon=c(-90.22275,-90.22261, -90.22272))
coord.deg = myGPS
class(coord.deg)
## "data.frame"
coordinates(coord.deg)<-~lon+lat
class(coord.deg)
## "SpatialPointsDataFrame"
## attr(,"package")
## "sp"
# does it have a projection/coordinate system assigned?
proj4string(coord.deg) # nope
## NA
# Manually tell R what the coordinate system is
proj4string(coord.deg)<-CRS("+proj=longlat +ellps=WGS84 +datum=WGS84")
# now we can use the spTransform function to project. We will project
# the mapdata and for coordinate reference system (CRS) we will
# assign the projection from counties
coord.deg<-spTransform(coord.deg, CRS(proj4string(gal)))
# double check that they match
identical(proj4string(coord.deg),proj4string(gal))
## [1] TRUE
my_pts <- SpatialPointsDataFrame(coords = coord.deg, data=data.frame(id=1:length(coord.deg)))
URL <- "https://osm2.cartodb.com/api/v2/sql?filename=public.galapagos_islands&q=select+*+from+public.galapagos_islands&format=geojson&bounds=&api_key="
fil <- "gal.json"
if (!file.exists(fil)) download.file(URL, fil)
gal <- readOGR(fil, "OGRGeoJSON")
gal <- gSimplify(gUnaryUnion(spTransform(gal, CRS("+init=epsg:31983")), id=NULL), tol=0.001)
gal_map <- fortify(gal)
rand_pts <- spTransform(my_pts, CRS("+init=epsg:31983"))
# ggplot can't deal with a SpatialPointsDataFrame so we can convert back to a data.frame
my_pts <- data.frame(my_pts)
my_pts.final = my_pts[,2:3]
# we're not dealing with lat/long but with x/y
# this is not necessary but for clarity change variable names
names(my_pts.final)[names(my_pts.final)=="lat"]<-"y"
names(my_pts.final)[names(my_pts.final)=="lon"]<-"x"
gg <- ggplot()
gg <- gg + geom_map(map=gal_map, data=gal_map,
aes(x=long, y=lat, map_id=id),
color="black", fill="#FFFFFF", size=.5)
gg <- gg + coord_equal()
gg <- gg + ggsn:::scalebar(gal_map, dist=50, location="bottomleft", st.size=5)
gg <- gg + theme_map()
gg <- gg + geom_point(data=my_pts.final, aes(x=x, y=y), color="red")
gg
I'm trying to produce a nice bubble plot overlaid on top of a basemap of the US (i could import a shapefile if that is preferred but i've been using the R basemaps.
library(ggplot2,sp,raster,maps,mapdata,maptools,ggmap,rgeos)
myData = data.frame(name=c("Florida","Colorado","california","Harvard","Yellowstone"),
lat=c(28.1,39,37,42,44.6),
long=c(-81.6,-105.5,-120,-71,-110),
pop=c(280,156,128,118,202))
Using this code below, that i adapted from another stack overflow post (Create bubble plot in R using satellite map), i am able to overlay a bubble plot on a map of the US. However this renders very slowly, the extent is too tight, it is bounded in a box, i'm not able to add other layers to the plot from what i can tell, and the base map is thick and not visually clean.
xy <- myData[,c("long", "lat")]
nl <- getData('GADM', country="USA", level=1) #raster data, format SpatialPolygonsDataFrame
nl <- gSimplify(nl, tol=0.01, topologyPreserve=TRUE)
# coercing the polygon outlines to a SpatialLines object
spl <- list("sp.lines", as(nl, "SpatialLines"))
SPDF <- SpatialPointsDataFrame(coords=xy, data=myData)
coordinates(myData) <- c("lat", "long")
projection(SPDF)<- "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs +towgs84=0,0,0"
coordinates(SPDF)[1:5,] #retrieves spatial coordinates form the dataframe
bubble(SPDF, "pop", sp.layout=spl, main="This is It!")
I can draw a nice basemap using this code. I add points to the map but they are not sized by the pop column in my data. And i can add additional layers to this map. But can i control the size of the points and the symbol itself like i can using a bubble plot?
map(database= "world", ylim=c(45,90),
xlim=c(-160,-50), col="grey80",
fill=TRUE, projection="gilbert",
orientation= c(90,0,225))
coord <- mapproject(myData$lon, myData$lat, proj="gilbert",orientation=c(90, 0, 225))
points(coord, pch=20, cex=1.2, col="red")
Can anyone please guide me towards the best way to plot a bubble map in R where i can adjust the fill and outline of the symbols in the bubble map, And i can add a clean basemap, that i can a) control the colors of (fill and lines) and b) add additional layers to (for instance another shapefile layer).
Thank you in advance for any advice.
This may be helpful. I approached your question using my own way. This may be a simpler operation to achieve what you are probably trying to do. For maps, GADM is great. But, some packages already got maps. Here, you can easily get the States map in the following way. Then, you can draw the map using ggplot2. geom_path draws the US, and geom_point adds the data points in myData.If you want to control size of bubbles in ggplot2,you can use size in aes.
library(map)
library(ggplot2)
# Get US map
usa <- map_data("state")
# Draw the map and add the data points in myData
ggplot() +
geom_path(data = usa, aes(x = long, y = lat, group = group)) +
geom_point(data = myData, aes(x = long, y = lat, size = pop), color = "red")
The following take a similar approach to #jazzurro's use of ggplot and your initial approach, but
uses a different base map
further reduces the polygons (you don't need hi-res borders for a bubble plot)
uses geom_map vs geom_path or geom_polygon
uses the Albers projection in coord_map
gets rid of map chart junk
library(maptools)
library(mapproj)
library(rgeos)
library(rgdal)
library(ggplot2)
# for theme_map
devtools::source_gist("33baa3a79c5cfef0f6df")
# nice US map GeoJSON
us <- readOGR(dsn="http://eric.clst.org/wupl/Stuff/gz_2010_us_040_00_500k.json", layer="OGRGeoJSON")
# even smaller polygons
us <- SpatialPolygonsDataFrame(gSimplify(us, tol=0.1, topologyPreserve=TRUE),
data=us#data)
# don't need these for the continental base map
us <- us[!us$NAME %in% c("Alaska", "Hawaii", "Puerto Rico", "District of Columbia"),]
# for ggplot
map <- fortify(us, region="NAME")
# your data
myData <- data.frame(name=c("Florida", "Colorado", "California", "Harvard", "Yellowstone"),
lat=c(28.1, 39, 37, 42, 44.6),
long=c(-81.6, -105.5, -120, -71,-110),
pop=c(280, 156, 128, 118, 202))
# the map
gg <- ggplot()
# the base map
gg <- gg + geom_map(data=map, map=map,
aes(x=long, y=lat, map_id=id, group=group),
fill="#ffffff", color="#0e0e0e", size=0.15)
# your bubbles
gg <- gg + geom_point(data=myData,
aes(x=long, y=lat, size=pop), color="#AD655F")
gg <- gg + labs(title="Bubbles")
# much better projection for US maps
gg <- gg + coord_map(projection="albers", lat=39, lat1=45)
gg <- gg + theme_map()
gg <- gg + theme(legend.position="bottom")
gg <- gg + theme(plot.title=element_text(size=16))
gg
This should make it pretty straightforward to add other layers as well.
I am new here and I am trying to plot points on a map of a coastal region - therefore I would like to show a coastline and colour just one country, surrounded by adjoining countries.
My code is
library(maps)
library(mapdata)
map("worldHires", xlim=c(-90,-70), ylim=c(-20,-2), # Re-defines the latitude and longitude range
col = "gray", fill=TRUE)
However I would like to colour in just Peru. I have so far managed to do this:
map('worldHires', 'Peru', col = "grey90", fill=TRUE, xlim=c(-90,-70), ylim=c(-20,-2))
but this doesn't show adjoining countries, and I would really like to show all adjoining countries and just colour Peru.
I have seen advice in another thread using the simple map tool - but there is slightly less detail (see below)
library(maptools)
data(wrld_simpl)
plot(wrld_simpl,
col = c(gray(.80), "red")[grepl("Peru", wrld_simpl#data$NAME) + 1],
xlim=c(-90,-70), ylim=c(-20,-2))
Does anyone know how to do it using worldhires? It's probably really simple and I just haven't worked it out.
The trick is to use map() to extract the Peru boundaries, then overplotting the Peru fill on a worlmap outline.
library(maps)
library(mapdata)
peru <- map("worldHires", regions="Peru", plot=FALSE, fill=TRUE)
map("worldHires", xlim=c(-100,-30), ylim=c(-30,10))
map(peru, col="red", fill=TRUE, add=TRUE)
A Hadleyverse version via ggplot:
library(maps)
library(mapdata)
library(ggplot2)
coast_map <- fortify(map("worldHires", fill=TRUE, plot=FALSE))
gg <- ggplot()
gg <- gg + geom_map(data=coast_map, map=coast_map,
aes(x=long, y=lat, map_id=region),
fill="white", color="black")
gg <- gg + geom_map(data=data.frame(region="Peru"), map=coast_map,
aes(map_id=region), fill="steelblue")
gg <- gg + xlim(-90,-70) + ylim(-20,-2)
gg <- gg + coord_map()
gg <- gg + theme_bw()
gg
I'm struggling to overlay neighborhood boundaries on a google map. I'm trying to follow this code. My version is below. Do you see anything obviously wrong?
#I set the working directory just before this...
chicago = readOGR(dsn=".", layer="CommAreas")
overlay <- spTransform(chicago,CRS("+proj=longlat +datum=WGS84"))
overlay <- fortify(overlay)
location <- unlist(geocode('4135 S Morgan St, Chicago, IL 60609'))+c(0,.02)
ggmap(get_map(location=location,zoom = 10, maptype = "terrain", source = "google",col="bw")) +
geom_polygon(aes(x=long, y=lat, group=group), data=overlay, alpha=0)+
geom_path(color="red")
Any insight would be much appreciated. Thanks for your help and patience.
This worked for me:
library(rgdal)
library(ggmap)
# download shapefile from:
# https://data.cityofchicago.org/api/geospatial/cauq-8yn6?method=export&format=Shapefile
# setwd accordingly
overlay <- readOGR(".", "CommAreas")
overlay <- spTransform(overlay, CRS("+proj=longlat +datum=WGS84"))
overlay <- fortify(overlay, region="COMMUNITY") # it works w/o this, but I figure you eventually want community names
location <- unlist(geocode('4135 S Morgan St, Chicago, IL 60609'))+c(0,.02)
gmap <- get_map(location=location, zoom = 10, maptype = "terrain", source = "google", col="bw")
gg <- ggmap(gmap)
gg <- gg + geom_polygon(data=overlay, aes(x=long, y=lat, group=group), color="red", alpha=0)
gg <- gg + coord_map()
gg <- gg + theme_bw()
gg
You might want to restart your R session in the event there's anything in the environment causing issues, but you can set the line color and alpha 0 fill in the geom_polygon call (like I did).
You can also do:
gg <- gg + geom_map(map=overlay, data=overlay,
aes(map_id=id, x=long, y=lat, group=group), color="red", alpha=0)
instead of the geom_polygon which gives you the ability to draw a map and perform aesthetic mappings in one call vs two (if you're coloring based on other values).
I have a data set about all the counties in Minnesota, and one of the columns is its shape. For each county it looks something like this:
For Aitkin County:
<Polygon><outerBoundaryIs><LinearRing><coordinates>-93.051956,46.15767700000001,0 -93.434006,46.15313,0 -93.43261,46.240253,0 -93.80480900000001,46.23817100000001,0 -93.80933400000001,46.580681,0 -93.77426199999999,46.59050400000001,0 -93.77412400000001,46.802605,0 -93.77500100000002,47.030445,0 -93.058258,47.022362,0 -93.05964600000001,46.766071,0 -93.05208600000002,46.417576,0 -93.051956,46.15767700000001,0</coordinates></LinearRing></outerBoundaryIs></Polygon>
I'm fairly new to R and know nothing about Google API, HTML, etc. I'm trying to use the ggplot2 and maps packages to create an intensity map for various aspects of all the counties in Minnesota. Is there a way to use these coordinates as they are to make a layer of counties, or do I need to do something else?
Here's the code I have so far:
Map of MN:
library(maps)
library(ggplot2)
all_states <- map_data("state")
mn<-subset(all_states, region %in% c("minnesota"))
p<-ggplot()
p<-p+geom_polygon(data=mn, aes(x=long, y=lat, group=group), colour="black", fill="white")
p
And my plan is to modify the following to apply to each county, once I get those polygons:
dataset <- data.frame(region=states,val=runif(49, 0,1))
us_state_map <- map_data('state')
map_data <- merge(us_state_map, dataset, by='region', all=T)
map_data <- map_data[order(map_data$order), ]
(qplot(long, lat, data=map_data, geom="polygon", group=group, fill=val)
+ theme_bw() + labs(x="", y="", fill="")
+ scale_fill_gradient(low='#EEEEEE', high='darkgreen')
+ opts(title="Title",
legend.position="bottom", legend.direction="horizontal"))
Any suggestions would be greatly appreciated!