I have a data like this:
YEAR-STORM-DATETIME-NORTH-WEST-PRESSURE-WIND-SPEED-TRACKDATE
2011-arlene-6/28/2011 6:00-19.9-92.8-1007-30-NA-6/28/2011
2011-arlene-6/28/2011 12:00-20.3-93.1-1006-35-4-6/28/2011
2011-arlene-6/28/2011 18:00-20.7-93.5-1006-40-5-6/28/2011
so on..
I am new to R and I am plotting a density-plot over ggmap. I am also using shiny R to display them in website. The problem is the output are all non-widescreen (squared) maps. I want to have a rectangular map, like google maps provided by Openlayers or KML.
My code is :
library(ggplot2)
library(ggmap)
mydata <- read.csv("C:/R Data/Analytics/dMetrics.csv")
slice_year <- mydata[mydata$YEAR=='2009',]
map <- get_map(c(lon = -55.3632715, lat = 31.7632836), zoom = 3,
source = 'google', maptype = c("terrain"), messaging = FALSE,
color = 'color')
world <- ggmap(map) #extent = 'device'
world <- world +
stat_density2d(data = slice_year,
aes(x = WEST, y = NORTH, fill = ..level.., alpha = ..level..),
show_guide = FALSE, geom = "polygon", na.rm = TRUE) +
scale_fill_gradient(name = "Density", low = "maroon", high = "yellow",
guide = 'colorbar')
world
Please guide me through to create a widescreen resolution map, possibly a high resolution.
To save the image as widescreen, add this to the end: ggsave(file="map.pdf", width=8, height=4.5)
To open a widescreen window, add this before calling world: windows(800,450)
Edit
It looks like ggmap just doesn't support non-sqaure aspect ratios.
The documentation claims that a bounding box can be passed into the location property, but it appears to just ignore it.
scale <- 5
ratio <- 16/9
size <- c(ratio, 1) * scale
latlongCenter <- c(0, 45)
latlongBox <- c(latlongCenter - size/2, latlongCenter + size/2)
map <- get_map(location = latlongBox)
ggmap(map)
One solution would be to produce a bigger map, and then crop the piece you don't need.
But I'm still trying to figure how to produce a big, high-resolution map (the map I'm getting is 1280x1280 - that's enough for most needs, but not to print a big map). I think there's no function for that, or bots could occupy all of Google's bandwidth. A simpler solution is to get many square maps and assemble them together, but then you'll have the Google logo in all of them.
I think the only way to do that is to produce the small square maps and cut the bottom, where the logo and copyright information are. To add their logo again in the borders of the final map (cutting them differently) would give even more work...
Related
I'm using library(choroplethr) for some market analysis and I have some questions about making my county_choropleth and either overlaying it on top of a ggmap() or using reference_map=TRUE in my code. What I'm trying to do is take my county choropleth and place state interstates/highways and draw circles/radii on top of it.
What I currently have is this:
library(choroplethr)
data <- Data.frame(County.FIPS = c(19153,19163,19153,19153,19153,19153,19153,19113,19007,19169), Score=c(812.6,769.5,757.9,757.2,722.6,712.4,69727,690.2,64539,642.5)
county <-aggregate(data$Score~data$County.FIPS,data=data,sum)
colnames(county) <- c("region", "value")
mp <- county_choropleth(county, state_zoom=c("iowa"), num_colors = 1) +
theme(legend.position="none")+
scale_fill_gradient2("Score",
high = "dark green",
low = "red",
na.value = "grey90",
breaks = pretty(county$value, n = 10),
label = scales::dollar_format())
...which gives me this plot.
From here, what I would like to do is overlay the main interstates in the state of Iowa on top of my map and also create some radius circles to show distance from certain cities in miles. I would like it to take elements from this map and ideally incorporate them into my choroplethr map because, in my opinion, it looks a lot cleaner than in this example:
I used this code to retrieve the second map:
library(ggmap)
test<-get_map(location = c(lon=-93.57217,lat=41.67269), maptype="roadmap",source="google",zoom=7,scale="auto")
yup <- data.frame(lon=c(-93.57217,-95.87509), lat=c(41.67269,41.23238),score=c(1,1))
ggmap(test) + stat_density2d(aes(x = lon, y = lat, fill = score,alpha=score),
size = 2, bins = 2, data = yup, geom = "polygon") +
theme(legend.position="none")
My main problem with using reference_map=TRUE in the choroplethr library is that it grays out labels, roads, etc. when I place my county_choropleth on top of it. e.g.,
So, is there an easy workaround for including roads and drawing circles on a map or do I need to abandon using choroplethr and move to ggmap, ggplot2 or something else? I also have been able to locate the Iowa DOT shapefiles for roads on their website, so that is an option to include, but I don't know how specifically to only ask it to use main interstates/highways when plotting and reading into R.
Here is my "ideal" MS Paint solution to this problem:
Thank you in advance for any and all help and please let me know if you have any clarification questions that need to be answered in order to help!
For those who stumble upon this later. I was able to achieve what I was hoping to do by changing libraries to leaflet and tigris.
I plan on making final tweaks for personal use, but here is the code used:
library(tigris)
library(leaflet)
data <- data.frame(County.FIPS = c(19153,19163,19153,19153,19153,19153,19153,19113,19007,19169), Score=c(812.6,769.5,757.9,757.2,722.6,712.4,69727,690.2,64539,642.5))
county <-aggregate(data$Score~data$County.FIPS,data=data,sum)
colnames(county) <- c("GEOID", "Score")
IA_counties <- counties(state="IA", cb=TRUE, resolution ="20m")
IA_merged <- geo_join(IA_counties,county,"GEOID", "GEOID")
pal <- colorQuantile("Greens",NULL,n=3)
popup <- paste0("Profitability: ", as.character(IA_merged$Score))
yup2 <- data.frame(lon=c(-93.57217,-95.93779),lat=c(41.67269,41.25861),score=c(1,1))
leaflet() %>%
addProviderTiles("Esri.WorldStreetMap") %>%
addLegend(pal = pal,
values = IA_merged$Score,
position = "bottomright",
title = "County Profitablity: ") %>%
addCircles(lng=yup2$lon, lat=yup2$lat,weight=1,fillOpacity=0.05,color="red",
radius = 96560) %>%
addCircles(lng=yup2$lon, lat=yup2$lat,weight=1,fillOpacity=0.025,color="blue",
radius = 193121) %>%
addPolygons(data = IA_counties,
fillColor = ~pal(IA_merged$Score),
fillOpacity = 0.15,
weight = 0.2,
popup = popup)
I am trying to map some data in R using ggmap. When I get the map it looks something like this.
cen <- geocode('Danmark')
center <- as.numeric(cen)
map <- get_googlemap(center = center, zoom = 6,
size = c(640, 640), scale = 2, region="dk",crop = TRUE,color="bw")
ggmap(map) #+ geom_point(aes(x = lon, y = lat, size=antal), data=df, colour="darkred")
The problem is that the island of Bornholm is located to the far east of Denmark. This makes the map very large. To increase the space usage I would like to move Bornholm to the upper right corner. Something like this
How can I do this in ggmap and still overlay data?
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 have been playing around with ggplot2 a bunch and found Adding table within the plotting region of a ggplot in r
I was wondering is there any method for this for plotting using non cartesian coordinates, eg if map coordinates were used for the positioning of the table. I had some maps and thought it would be cool if they could have their corresponding data in a table for points to show more detail.
If anyone knows a work around for annotation_custom for non cartesian coordinates it would be greatly appreciated.
EDIT:Here is a image of what my map looks like, I was just thinking is there another way to plot the table on the left side of this.
EDIT: here is what Im attempting to do
EDIT: Here is the basic code structure for the plot
library(ggplot2)
library(ggmap)
plotdata <- read.csv("WellSummary_All_SE_NRM.csv", header = T)
plotdata <- na.omit(plotdata)
plotdata <- plotdata[1:20, c("Unit_No","neg_decimal_lat", "decimal_long", "max_drill_depth", "max_drill_date")]
map.plot<- get_map(location = c(min(plotdata$decimal_long),
min(plotdata$neg_decimal_lat),
max(plotdata$decimal_long),
max(plotdata$neg_decimal_lat)),
maptype ="hybrid",source = "google", zoom=8)
theme_set(theme_bw(base_size = 8))
colormap <- c("darkblue","blue","lightblue", "green", "yellow", "orange","darkorange", "red", "darkred")
myBreaks <- c(0,2, 10, 50, 250, 1250, 2000, 2500)
static.map <- ggmap(map.plot) %+% plotdata +
aes(x = decimal_long,
y = neg_decimal_lat,
z= max_drill_depth)+
stat_summary2d(fun = median, binwidth = c(.03, .03),alpha = 0.7) +
scale_fill_gradientn(name = "depth", colours= colormap, breaks=myBreaks,labels = format(myBreaks),
limits= c(0,2600), space = "Lab") +
labs(x = "Longitude",y = "Latitude")+
geom_text(aes(label=Unit_No),hjust=0, vjust=0,size=2,
position = position_dodge(width=0.9), angle = 45)+
coord_map()
#Creates image of the plot in file to Working Directory
filename=paste("2dmap",".png", sep="")
cat("\t",filename,"file created, saving...\n")
print(static.map)
cat("\tpassed mapping, file now being made\n")
ggsave(filename=filename,
plot = static.map,
scale = 1,
width = 6, height = 4,
dpi = 300)
I will try to upload the data today, cheers for some of the pointers already!
I have uploaded the data, dont worry about the positioning of the gradient values and text tags as I can fix them later I will also link the current ggmap code but I am using a very large loop for the data to be sorted.
https://drive.google.com/file/d/0B8qOIJ-nPp9rM1U1dkEzMUM0Znc/edit?usp=sharing
try this,
library(gridExtra)
grid.arrange(tableGrob(head(iris)), qplot(1,1), ncol=2)
annotation_custom wouldn't help, it's meant for adding things inside the plot panel, not to the side.