This problem came up previously, and as suggested here, it was addressed. But it seems to have been only partially addressed.
First, here is code that works, showing a dot approximately at the location of the White House:
require(ggmap)
gc = geocode('the white house')
qmap(location = "the white house", maptype = "roadmap", zoom = 3) +
geom_point(aes(x = lon, y = lat), data = gc, color="red", size = 3)
However, if I change maptype to "toner", which I prefer for its simplicity and clarity of state boundaries, the White House goes north, well into Canada:
qmap(location = "the white house", maptype = "toner", zoom = 3) +
geom_point(aes(x = lon, y = lat), data = gc, color="red", size = 3)
How can I fix this?
Related
I am generating a map very similar to this
(source: dominodatalab.com)
] to visualize the frequency in which cities occur. How can I create a legend or key for this map so I can see what the size of the circles represent numerically?
Here is my code:
myLocation <- c(-124, 32, -66, 42)
myMap <- get_map(location = myLocation, source = "stamen",
maptype = "toner", crop = FALSE, zoom = 4)
ggmap(myMap) +
geom_point(aes(x = lon, y = lat), data = csr.Ax1,
col = "orange", alpha = 0.4, size = csr.Ax1$freq*.25) +
scale_size_continuous(range = range(csr.Ax1$freq), guide = "legend") +
ggtitle("CSR Active Candidates") +
legend()
EDIT: SOLVED!
The solution was placing the size=csr.Ax1$freq from the geom_point argument into the aes() argument.
The solution was placing the size=csr.Ax1$freq from the geom_point argument into the aes() argument.
I am trying to get the black and white version of a stamen map and its giving me the color version. I've tried downloading the map with get_map and get_stamenmap and both give me the color version regardless of whether I specify color as "bw" or "color". Any ideas or work arounds?
library(ggmap)
mapImage <- get_map(location = c(lon = -110.8, lat = 34.7),
source = "stamen",
maptype = "terrain",
color = "bw",
zoom = 7)
g <- ggmap(mapImage)
To get black-and-white stamen maps, use maptype = "toner". The color argument has no effect on stamen maps. You might also want a panel border around the plot. If so, use ggplot's theme_bw() or theme(panel.border = element_rect(fill = NA, colour = "black")).
library(ggmap)
mapImage <- get_map(location = c(lon = -110.8, lat = 34.7),
source = "stamen",
maptype = "toner",
# color = "bw",
zoom = 7)
ggmap(mapImage) + theme_bw()
My solution was get_stamenmap with maptype="toner".
It is like get_map with source="stamen" speaks with a southern soft R and sloppy lisp dialect that stamen does not understand.
library(ggmap)
mapImage <- get_stamenmap(bbox = c(-114,32,-107,37),
source = "stamen",
maptype = "toner",
zoom = 7)
ggmap(mapImage) +theme_bw()
did the trick for me (using Rstudio in Linux, potential bug)
Notice bbox as the alternative to location and theme_bw() as Sandy suggested
I have been trying to create a map of membership locations from postcodes across the UK as a project in learning R. I have achieved nearly the result I wanted, but it's proving very frustrating getting the glitches sorted. This image is my current best effort:
I still want to change:
get rid of the extraneous legend (the "0.16", "0.5" squares), which are coming from the size arg to geom_point. If I remove the size=0.16 arg the guide/legend disappears, but the geom size returns to the default too. This also happens for the "black" guide -- coming from a colour obviously -- but why?
properly clip the stat_density2d polygons, which are exhibiting undesireable behaviour when clipped (see bottom-right plot near the top)
have control over the line-width of the geom_path that includes the county boundaries: it's currently too thick (would like about 1/2 thickness shown) but all I can achieve by including 'size' values is to make the lines stupidly thick - so thick that they obscure the whole map.
The R code uses revgeocode() to find the placename closest to the centre point but I don't know how to include the annotation on the map. I would like to include it in a text-box over the North Sea (top right of UK maps), maybe with a line/arrow to the point itself. A simpler option could just be some text beneath the UK map, below the x-axis ... but I don't know how to do that. geom_rect/geom_text seem fraught in this context.
Finally, I wanted to export the map to a high-res image, but when I do that everything changes again, see:
which shows the high-res (~1700x1800px) image on the left and the Rstudio version (~660x720px) on the right. The proportions of the maps have changed and the geom_text and geom_point for the centre point are now tiny. I would be happy if the gap between the two map rows was always fairly small, too (rather than just small at high res).
Code
The basics: read list of members postcodes, join with mySociety table of postcode<>OSGB locations, convert locations to Lat/long with spTransform, calculate binhex and density layers, plot with ggmap.
The code for all this is somewhat lengthy so I have uploaded it as a Gist:
https://gist.github.com/rivimey/ee4ab39a6940c0092c35
but for reference the 'guts' of the mapping code is here:
# Get a stylised base map for the whole-of-uk maps.
map.bbox = c(left = -6.5, bottom = 49.5, right = 2, top = 58)
basemap.uk <- get_stamenmap(bb = map.bbox, zoom=calc_zoom(map.bbox), maptype="watercolor")
# Calculate the density plot - a continuous approximation.
smap.den <- stat_density2d(aes(x = lat, y = lon, fill = ..level.., alpha = ..level..),
data = membs.wgs84.df, geom = "polygon",
breaks=2/(1.5^seq(0,12,by=1)), na.rm = TRUE)
# Create a point on the map representing the centroid, and label it.
cmap.p <- geom_point(aes(x = clat, y = clon), show_guide = FALSE, data = centroid.df, alpha = 1)
cmap.t1 <- geom_text(aes(x = clat, y = clon+0.22, label = "Centre", size=0.16), data = centroid.df)
cmap.t2 <- geom_text(aes(x = clat, y = clon+0.1, label = "Centre", size=0.25), data = centroid.df)
# Create an alternative presentation, as binned hexagons, which is more true to the data.
smap.bin <- geom_hex(aes(x = lat, y = lon),
data = membs.wgs84.df, binwidth = c(0.15, 0.1), alpha = 0.7, na.rm = TRUE)
# Create a path for the county and country boundaries, to help identify map regions.
bounds <- geom_path(aes(x = long, y = lat, group = group, colour = "black"), show_guide = FALSE,
data = boundaries.subset, na.rm = TRUE)
# Create the first two actual maps: a whole-uk binned map, and a whole-uk density map.
map.bin <- ggmap(basemap.uk) + smap.bin + grad + cmap.p + cmap.t1
map.den <- ggmap(basemap.uk) + smap.den + alpha + cmap.p + cmap.t1
# Create a zoomed-in map for the south-east, to show greater detail. I would like to use this
# bbox but google maps don't respect it :(
map.lon.bbox = c(left = -1, bottom = 51, right = 1, top = 52)
# Get a google terrain map for the south-east, bbox roughly (-1.7,1.7, 50.1, 53)
basemap.lon <- get_map(location = c(0,51.8), zoom = 8, maptype="terrain", color = "bw")
# Create a new hexbin with more detail than earlier.
smap.lon.bin <- geom_hex(aes(x = lat, y = lon),
data = membs.wgs84.df, bins=26, alpha = 0.7, na.rm = TRUE)
# Noe create the last two maps: binned and density maps for London and the SE.
lonmap.bin <- ggmap(basemap.lon) + bounds + smap.lon.bin + grad + cmap.p + cmap.t2
lonmap.den <- ggmap(basemap.lon) + bounds + smap.den + alpha + cmap.p + cmap.t2
# Arrange the maps in 2x2 grid, and tell the grid code to let the first row be taller than the second.
multiplot(map.bin, lonmap.bin, map.den, lonmap.den, heights = unit( c(10,7), "null"), cols=2 )
I would like to create a map that is not perfectly square but rectangular and is the size I dictate.
require(ggmap)
tenmile <- get_map(location = c(lon = -122.486328, lat = 48.862813),
color = "color",
source = "google",
maptype = "roadmap",
zoom = 12)
tenmile.map <- ggmap(tenmile,
extent = "device",
ylab = "Latitude",
xlab = "Longitude")+ggtitle("GEOMean for Data from Oct 2013-Nov 2014")
tenmile.map + geom_point(data=pp, aes(x=lon, y=lat, size=geomean), color="red", alpha=0.5) +
geom_text(data=pp, aes(x=lon, y=lat, label = site), size=3, vjust = 1.25, hjust = -0.1)
I would post pictures of what I get and what I want but I do not have enough reputation points to post images. =-(
Sandy Muspratt's answer produces a rectangular map, but it gets stretched. To get an unstretched map, ratio must be adjusted to the ratio between spacing of parallels and meridians at the place of the map. That is:
ratio = 1/cos(latitude)
If latitude is given in degrees, that becomes:
ratio = 1/cos(pi*latitude/180)
I give here an example using a map of Barcelona (Barcelona makes a good example to check for stretching because most of our streets form an square grid and deformation becomes easily noticeable).
library(ggmap) library(mapproj) mapbcn <- get_map(location =
'Barcelona, Catalonia', zoom = 13)
# square map (default) ggmap(mapbcn)
# map cropped by latitude
ggmap(mapbcn) +
coord_fixed(ylim=c(41.36,41.41),
ratio=1/cos(pi*41.39/180))
# map cropped by longitude
ggmap(mapbcn) +
coord_fixed(xlim=c(2.14, 2.18),
ratio=1/cos(pi*41.39/180))
It must be noted that this way coordinates keep working for the whole map (for example to add points to the map) if the area of the map is small enough not to take in account Earth's curvature - that is, to assume that meridians are parallel in the area shown by the map. It may be inaccurate in a map spanning some hundreds of kilometres and very wrong in a continent-scale map.
If you want to keep the original limits of the bounding box but simply to change its shape, you can adjust the aspect ratio. If you want to change the limits of the bounding box, then obtain the map as before but set its limits using coord_fixed() (or coord_cartesian()). Or you can adjust both the aspect ratio and the limits of the bounding box.
tenmile <- get_map(location = c(lon = -122.486328, lat = 48.862813),
color = "color",
source = "google",
maptype = "roadmap",
zoom = 12)
tenmile.map <- ggmap(tenmile,
ylab = "Latitude",
xlab = "Longitude")+ggtitle("GEOMean for Data from Oct 2013-Nov 2014") +
coord_fixed(xlim = c(-122.55, -122.40), ratio = 2/1)
I am creating maps using ggmap and am having trouble displaying some polygons and borders in my code. I have a map of a city that has parts of 3 counties in it. I would like to display the city along with the appropriate county lines. If I set the zoom such that all 3 counties are completely visible, then the county lines appear in the map. However, if I zoom to the portion of the city, the county lines disappear.
Example 1: County lines visible on map
tempplot <- get_map(location = c(lon = -97.37605, lat = 32.94748), zoom=9, maptype = 'roadmap')
myplot <- ggmap(tempplot) + borders ("county", colour = "red", alpha = 0.5, region = "Texas")
myplot <- myplot + geom_point(aes(x = -97.37605, y = 32.94748), color = "dodgerblue4", pch = 20, size = 9)
myplot
Image: http://imgur.com/nx3XU2I
Example 2: County lines partially visible on map
tempplot <- get_map(location = c(lon = -97.37605, lat = 32.94748), zoom=10, maptype = 'roadmap')
myplot <- ggmap(tempplot) + borders ("county", colour = "red", alpha = 0.5, region = "Texas")
myplot <- myplot + geom_point(aes(x = -97.37605, y = 32.94748), color = "dodgerblue4", pch = 20, size = 9)
myplot
Example 3: No county lines visible on map
tempplot <- get_map(location = c(lon = -97.37605, lat = 32.94748), zoom=12, maptype = 'roadmap')
myplot <- ggmap(tempplot) + borders ("county", colour = "red", alpha = 0.5, region = "Texas")
myplot <- myplot + geom_point(aes(x = -97.37605, y = 32.94748), color = "dodgerblue4", pch = 20, size = 9)
myplot
Image: http://imgur.com/dIpp6kp
The only difference between these 3 examples is the zoom on the map. I need the map to be at zoom 12 to see the additional details that I will be adding (individual homes), but when I zoom in, the county lines vanish. Any suggestions?
(Sorry about the links to the images ... I am new to the forum and don't have a 10 reputation yet!)
It appears that also the borders you get in example 1 are not 100% correct. You may check with a lower Zoom lever (eg 5).
To me it looks like there is a problem with borders that are cut off by the picture; the function then tries to connect it to an edge that is still visible. In the zoom level you provided even that is not possible, and therefore it has unexpected behaviour.
To sum up: I don't know what exactly the problem is, but maybe this short analysis helps in any way!