Overlapping labels ggmap - r

I have the Google map and a list of coordinates with a text label. When I preview this, the labels overlap and thus become unreadable:
library(ggmap)
WPmap <- qmap(c(lon=4.80324, lat=52.40738), zoom = 12, source = "google")
table kaart_rtw:
Naam lat lon
1 Nieuw-Zeelandweg 52.40466 4.80214
2 Portsmuiden 52.39014 4.78554
3 Westhavenweg 52.41602 4.82282
4 Westhavenweg 52.41702 4.82282
5 Westhavenweg 52.41802 4.82282
6 Deccaweg 52.40196 4.83910
7 Coenhavenweg 52.40364 4.86195
AmsterdamMap + geom_text(data = kaart_rtw, aes(label = kaart_rtw$Naam, x = X, y = Y))
Is there a way to stop the overlapping?

You might consider trying ggrepel to place your labels without overlaps:
library(ggmap)
install.packages("devtools")
devtools::install_github("slowkow/ggrepel")
library(ggrepel)
df <- read.table(text="Naam lat lon
Nieuw-Zeelandweg 52.40466 4.80214
Portsmuiden 52.39014 4.78554
Westhavenweg 52.41602 4.82282
Westhavenweg 52.41702 4.82282
Westhavenweg 52.41802 4.82282
Deccaweg 52.40196 4.83910
Coenhavenweg 52.40364 4.86195", header = TRUE, strip.white = TRUE)
roads <- get_map(location = c(lon = 4.82824, lat = 52.40738), zoom = 13,
maptype = "roadmap", scale = 2)
ggmap(roads) +
geom_point(
data = df,
aes(x = lon, y = lat),
alpha = 0.5, fill = "red", size = 4, shape = 21
) +
geom_label_repel(
data = df,
aes(x = lon, y = lat, label = df$Naam),
box.padding = unit(2, "lines")
) +
guides(fill = FALSE, alpha = FALSE)

Adjusting the coordinates might be the easy solution, but only when you have few observations. An example:
df <- read.table(text="Naam lat lon
Nieuw-Zeelandweg 52.40466 4.80214
Portsmuiden 52.39014 4.78554
Westhavenweg 52.41602 4.82282
Westhavenweg 52.41702 4.82282
Westhavenweg 52.41802 4.82282
Deccaweg 52.40196 4.83910
Coenhavenweg 52.40364 4.86195", header = TRUE, strip.white = TRUE)
require(ggmap)
require(ggplot2)
roads <- get_map(location = c(lon = 4.82824, lat = 52.40738), zoom = 13,
maptype = "roadmap", scale = 2)
ggmap(roads) +
geom_point(data = df, aes(x=lon, y=lat, fill="red", alpha=0.5, label = df$Naam),
size=4, shape=21) +
geom_text(data = df, aes(x = lon, y = lat, label = Naam),
size = 3, vjust = 0, hjust = -0.1) +
guides(fill = FALSE, alpha = FALSE)
The result:

Related

Create animated heatmap on a map in R

I want to created an animated heatmap on a map like this one. I am trying to use gganimate like:
library(readr)
library(dplyr)
url_csv <- 'https://raw.githubusercontent.com/d4tagirl/R-Ladies-growth-maps/master/rladies.csv'
rladies <- read_csv(url(url_csv)) %>%
select(-1)
library(DT)
datatable(rladies, rownames = FALSE,
options = list(pageLength = 5))
library(ggplot2)
library(maps)
library(ggthemes)
world <- ggplot() +
borders("world", colour = "gray85", fill = "gray80") +
theme_map()
map <- world +
geom_point(aes(x = lon, y = lat, size = followers),
data = rladies,
colour = 'purple', alpha = .5) +
scale_size_continuous(range = c(1, 8),
breaks = c(250, 500, 750, 1000)) +
labs(size = 'Followers')
library(tibble)
library(lubridate)
ghost_points_ini <- tibble(
created_at = as.Date('2011-09-01'),
followers = 0, lon = 0, lat = 0)
ghost_points_fin <- tibble(
created_at = seq(as.Date('2017-05-16'),
as.Date('2017-05-30'),
by = 'days'),
followers = 0, lon = 0, lat = 0)
map <- world +
geom_point(aes(x = lon, y = lat, size = followers,
frame = created_at,
cumulative = TRUE),
data = rladies, colour = 'purple', alpha = .5) +
geom_point(aes(x = lon, y = lat, size = followers, # this is the init transparent frame
frame = created_at,
cumulative = TRUE),
data = ghost_points_ini, alpha = 0) +
geom_point(aes(x = lon, y = lat, size = followers, # this is the final transparent frames
frame = created_at,
cumulative = TRUE),
data = ghost_points_fin, alpha = 0) +
scale_size_continuous(range = c(1, 8), breaks = c(250, 500, 750, 1000)) +
labs(size = 'Followers')
library(gganimate)
ani.options(interval = 0.2)
animate(map)
But I get : Error in animate.default(map) : animation of gg objects not supported
The other issue is that I would like the heatmap to have squares like the link I attached instead of those points.
Not sure this is what you want, but it works...
library(dplyr)
url_csv <- 'https://raw.githubusercontent.com/d4tagirl/R-Ladies-growth-maps/master/rladies.csv'
rladies <- read_csv(url(url_csv)) %>%
select(-1)
library(DT)
datatable(rladies, rownames = FALSE,
options = list(pageLength = 5))
library(ggplot2)
library(maps)
library(ggthemes)
world <- ggplot() +
borders("world", colour = "gray85", fill = "gray80") +
theme_map()
map <- world +
geom_point(aes(x = lon, y = lat, size = followers),
data = rladies,
colour = 'purple', alpha = .5) +
scale_size_continuous(range = c(1, 8),
breaks = c(250, 500, 750, 1000)) +
labs(size = 'Followers')
library(tibble)
library(lubridate)
map1 <- world +
geom_point(data = rladies, aes(x = lon, y = lat, size = followers),
colour = 'purple', alpha = .5) +
scale_size_continuous(range = c(1, 8), breaks = c(250, 500, 750, 1000)) +
labs(size = 'Followers')
library(gganimate)
map1 + transition_time(created_at)

Setting map limits in ggplot2 with Mercator projection

Very much related to this question I am trying to plot some world regions, now using a Mercator projection, but keep getting into trouble when adding x and y limits:
ggplot(world, mapping = aes(x = long, y = lat, group = group)) +
geom_polygon(fill = "black", colour = "black") +
coord_map(projection = "mercator", xlim = c(-125, -30), ylim = c(-60, 35))
Obviously not great. When I use coord_cartesian (as suggested here) to set the limits, I loose the Mercator projection:
ggplot(world, mapping = aes(x = long, y = lat, group = group)) +
geom_polygon(fill = "black", colour = "black") +
coord_map(projection = "mercator") +
coord_cartesian(xlim = c(-125, -30), ylim = c(-60, 35))
When I use lims I get what I want for Latin America:
ggplot(world, mapping = aes(x = long, y = lat, group = group)) +
geom_polygon(fill = "black", colour = "black") +
coord_map(projection = "mercator") +
lims(x = c(-125, -30), y = c(-60, 35))
Problem is, this approach does not always work, for example for Africa or Asia I start to get some crazy behaviour towards the plot border:
ggplot(world, mapping = aes(x = long, y = lat, group = group)) +
geom_polygon(fill = "black", colour = "black") +
coord_map(projection = "mercator") +
lims(x = c(-20, 45), y = c(-50, 40))
# lims(x = c(40, 150), y = c(-10, 55))
A solution here could be to convert the lat/lon coordinates to "proper" web mercator coordinates (here I'm using epsg 3857, which is the "google" projection), and then plotting using those "new" coordinates.
Assuming that original coordinates are latlon wgs84 (epsg 4326), this can be achieved like this:
worldmerc <- SpatialPointsDataFrame(coords = data_frame(x = world$long, y = world$lat),
data = world, proj4string = CRS("+proj=longlat +datum=WGS84")) %>%
subset((lat < 90 & lat > -90)) %>% # needed because transform not defined at the poles !!!!
spTransform(CRS("+init=epsg:3857"))
worldmerc <- mutate(worldmerc#data, longmerc = coordinates(worldmerc)[,1], latmerc = coordinates(worldmerc)[,2])
Plotting the whole data gives you this (Note the use of coord_fixed to preserve aspect ratio !:
ggplot(worldmerc, mapping = aes(x = longmerc, y = latmerc, group = group)) +
geom_polygon(fill = "black", colour = "black") +coord_fixed()
Now, the problem is that to do subsetting you would now need to enter "map" coordinates instead than lat long, but also that can be tweaked:
#For South America
xlim = c(-125, -30)
ylim = c(-60, 35)
lims = SpatialPoints(coords = data_frame(x = xlim, y = ylim), proj4string = CRS("+proj=longlat +datum=WGS84"))%>%
spTransform(CRS("+init=epsg:3857"))
ggplot(worldmerc, mapping = aes(x = longmerc, y = latmerc, group = group)) +
geom_polygon(fill = "black", colour = "black")+
coord_fixed(xlim = coordinates(lims)[,1], ylim = coordinates(lims)[,2])
#for africa
xlim = c(-20,45)
ylim = c(-50,40)
lims = SpatialPoints(coords = data_frame(x = xlim, y = ylim), proj4string = CRS("+proj=longlat +datum=WGS84"))%>%
spTransform(CRS("+init=epsg:3857"))
ggplot(worldmerc, mapping = aes(x = longmerc, y = latmerc, group = group)) +
geom_polygon(fill = "black", colour = "black")+
coord_fixed(xlim = coordinates(lims)[,1], ylim = coordinates(lims)[,2])
As you can see, in both cases you get "correct" maps.
Now, last thing you may want to do is maybe have "lat/lon" coordinates on the axis. That's a bit of a hack but can be done like this:
library(magrittr)
xlim = c(-125, -30)
ylim = c(-60, 35)
# Get the coordinates of the limits in mercator projection
lims = SpatialPoints(coords = data_frame(x = xlim, y = ylim),
proj4string = CRS("+proj=longlat +datum=WGS84"))%>%
spTransform(CRS("+init=epsg:3857"))
# Create regular "grids" of latlon coordinates and find points
# within xlim/ylim - will be our labels
majgrid_wid_lat = 20
majgrid_wid_lon = 30
majbreaks_lon = data_frame(x=seq(-180, 180, majgrid_wid_lon)) %>%
filter(x >= xlim[1] & x <= xlim[2]) %>%
as.data.frame()
majbreaks_lat = data_frame(x=seq(-90, 90, majgrid_wid_lat)) %>%
filter(x >= ylim[1] & x <= ylim[2]) %>%
as.data.frame()
#Find corresponding mercator coordinates
mercbreaks_lat = SpatialPoints(coords = expand.grid(x = majbreaks_lon$x, y = majbreaks_lat$x), proj4string = CRS("+init=epsg:4326"))%>%
spTransform(CRS("+init=epsg:3857")) %>% coordinates() %>% extract(,2) %>% unique()
mercbreaks_lon = SpatialPoints(coords = expand.grid(x = majbreaks_lon$x, y = majbreaks_lat$x), proj4string = CRS("+init=epsg:4326"))%>%
spTransform(CRS("+init=epsg:3857")) %>% coordinates() %>% extract(,1) %>% unique()
# Plot using mercator coordinates, but latlon labels
ggplot(worldmerc, mapping = aes(x = longmerc, y = latmerc, group = group)) +
geom_polygon(fill = "black", colour = "black") +
coord_fixed(xlim = coordinates(lims)[,1], ylim = coordinates(lims)[,2])+
scale_x_continuous("lon", breaks = mercbreaks_lon, labels = signif(majbreaks_lon$x, 2)) +
scale_y_continuous("lat", breaks = mercbreaks_lat, labels = signif(majbreaks_lat$x,2))+theme_bw()
, which gives:
It's a bit convoluted and there could be better ways, but it does the trick, and could be easily transformed in a function.
HTH,
Lorenzo

ggmap border line Issue

I am trying to create a map that to show some study sites in three states. I would like to get rid of the black border lines that go through the map. Like below:
lon <- c(-89.105917,-89.377778,-86.700278,-86.677361,-87.338083,-87.340444)
lat <- c(37.358694, 37.215278,38.460528,38.448389,37.594583,37.5945)
#crop
lon1 <- c(-86.6214142,-87.3423767,-87.6656265,-87.1565475,-87.8155823,-87.3194199,-87.3565598)
lat1 <- c(38.484581,37.7038918,37.7400513,38.0794983,37.6372185,37.4466667,37.3590546)
#CRP
lon2 <-c(-88.4263,-87.4707718,-86.435585,-87.9516907,-89.2439117,-88.3630524,-89.0109711)
lat2 <- c(37.3582993,37.5196114,37.5220261,37.4958801,37.3413811,37.2275009,37.3633308)
#Forest
lon3 <-c(-86.608551,-87.3794403,-88.9937515,-86.7436066,-86.7483826)
lat3 <- c(38.2506294,36.9505539,37.4111404,38.1277695,37.1684914)
#Pasture
lon4 <-c(-86.6036377,-86.2461395,-86.9746704,-87.4977493,-88.9970474,-86.2609634,-86.6067734,-86.9820709)
lat4 <- c(37.0606689,37.8114433,37.5391922,37.8073006,37.4703789,37.3089409,38.1600189,37.6018295)
df <- as.data.frame(cbind(lon,lat))
df1 <- as.data.frame(cbind(lon1,lat1))
df2 <- as.data.frame(cbind(lon2,lat2))
df3 <- as.data.frame(cbind(lon3,lat3))
df4 <- as.data.frame(cbind(lon4,lat4))
pdf("/Users/tribaker/Desktop/Thesis/RaCA/RaCASites.pdf")
al1 = get_map(location = c("posey county,indiana"),
zoom = 8, maptype = 'satellite')
mdat <- map_data('state',Fill=TRUE)
ggmap(al1) +
geom_path(data=mdat,aes(x=long,y=lat, regions=c('"Kentucky","Illinois","Indiana"')),colour="black",alpha=1)+
borders("county", colour="grey60", alpha=.5)+
borders("state", colour="black", alpha=.8)+
geom_point(data = df, aes(x = lon, y = lat,colour = "Study Site", alpha = 0.8), size = 8, shape = 15) +
geom_point(data = df1, aes(x = lon1, y = lat1,colour = "Crop",fill=TRUE, alpha = 0.8), size = 8, shape = 16) +
geom_point(data = df2, aes(x = lon2, y = lat2,colour = "CRP", fill = TRUE ,alpha = 0.8), size = 8, shape = 16) +
geom_point(data = df3, aes(x = lon3, y = lat3, colour = "Forest",fill = TRUE,alpha = 0.8), size = 8, shape =16) +
geom_point(data = df4, aes(x = lon4, y = lat4,colour = "Pasture",fill = TRUE,alpha = 0.8), size = 8, shape = 16) +
guides(fill=FALSE, alpha=FALSE, size=FALSE)
geom_text(aes(label = state), data = mdat, size = 2, angle = 45)
thanks in advance
I couldn't get the borders function to work correctly, but you can just do it manually...
Create an mdat2 dataframe with the county data and draw the borders yourself...
lon <- c(-89.105917,-89.377778,-86.700278,-86.677361,-87.338083,-87.340444)
lat <- c(37.358694, 37.215278,38.460528,38.448389,37.594583,37.5945)
#crop
lon1 <- c(-86.6214142,-87.3423767,-87.6656265,-87.1565475,-87.8155823,-87.3194199,-87.3565598)
lat1 <- c(38.484581,37.7038918,37.7400513,38.0794983,37.6372185,37.4466667,37.3590546)
#CRP
lon2 <-c(-88.4263,-87.4707718,-86.435585,-87.9516907,-89.2439117,-88.3630524,-89.0109711)
lat2 <- c(37.3582993,37.5196114,37.5220261,37.4958801,37.3413811,37.2275009,37.3633308)
#Forest
lon3 <-c(-86.608551,-87.3794403,-88.9937515,-86.7436066,-86.7483826)
lat3 <- c(38.2506294,36.9505539,37.4111404,38.1277695,37.1684914)
#Pasture
lon4 <-c(-86.6036377,-86.2461395,-86.9746704,-87.4977493,-88.9970474,-86.2609634,-86.6067734,-86.9820709)
lat4 <- c(37.0606689,37.8114433,37.5391922,37.8073006,37.4703789,37.3089409,38.1600189,37.6018295)
df <- as.data.frame(cbind(lon,lat))
df1 <- as.data.frame(cbind(lon1,lat1))
df2 <- as.data.frame(cbind(lon2,lat2))
df3 <- as.data.frame(cbind(lon3,lat3))
df4 <- as.data.frame(cbind(lon4,lat4))
al1 = get_map(location = c("posey county,indiana"),
zoom = 8, maptype = 'satellite')
mdat <- map_data('state', regions=c("Kentucky","Illinois","Indiana"))
mdat2 <- map_data('county', regions=c("Kentucky","Illinois","Indiana"))
ggmap(al1) +
geom_path(data=mdat2,aes(x=long,y=lat,group=group), colour="grey60", alpha=.5)+
geom_path(data=mdat,aes(x=long,y=lat,group=group), colour="black", alpha=.8)+
geom_point(data = df, aes(x = lon, y = lat,colour = "Study Site", alpha = 0.8), size = 8, shape = 15) +
geom_point(data = df1, aes(x = lon1, y = lat1,colour = "Crop",fill=TRUE, alpha = 0.8), size = 8, shape = 16) +
geom_point(data = df2, aes(x = lon2, y = lat2,colour = "CRP", fill = TRUE ,alpha = 0.8), size = 8, shape = 16) +
geom_point(data = df3, aes(x = lon3, y = lat3, colour = "Forest",fill = TRUE,alpha = 0.8), size = 8, shape =16) +
geom_point(data = df4, aes(x = lon4, y = lat4,colour = "Pasture",fill = TRUE,alpha = 0.8), size = 8, shape = 16) +
guides(fill=FALSE, alpha=FALSE, size=FALSE)
geom_text(aes(label = state), data = mdat, size = 2, angle = 45)

Draw Point on Map Without Border

library(ggplot2)
library(ggmap)
data <- read.table(file = "data.txt", sep = ",", col.names = c("lat", "lon", "place_name"), fill=FALSE, strip.white=TRUE)
# getting the map
mapgilbert <- get_map(location = c(lon = mean(data$lon), lat = mean(data$lat)),
zoom = "auto" , maptype = "roadmap", scale = 2, color = "bw")
# plotting the map with some points on it
ggmap(mapgilbert, extent = "device") +
geom_point(data = data, aes(x = lon, y = lat, fill = place_name), size = 0.5, shape = 22) +
guides(fill=FALSE, alpha=FALSE, size=FALSE)
This will produce points with different color (According to their names). Something like this:
However, I want to get rid of the black border of the points. Is there a way to do that?
Try a different shape:
data <- data.frame(lat=52.5176736, lon=13.3895097)
library(ggmap)
library(ggplot2)
mapgilbert <- get_map(location = c(lon = mean(data$lon), lat = mean(data$lat)),
zoom = "auto" , maptype = "roadmap", scale = 2, color = "bw")
ggmap(mapgilbert, extent = "device") +
geom_point(data = data, aes(x = lon, y = lat), size = 6, shape = 16, color="red") +
guides(fill=FALSE, alpha=FALSE, size=FALSE)
or set color to NA when using shape = 21:
ggmap(mapgilbert, extent = "device") +
geom_point(data = data, aes(x = lon, y = lat), size = 6, shape = 21, color=NA, fill = "red") +
guides(fill=FALSE, alpha=FALSE, size=FALSE)

Labeling locations on Google Maps using R

I have a dataframe which has three columns - Places, lat, and long. Places is a list of strings, and the lat and long values are obtained by geocoding the list.
I can plot the lat long values using
map + geom_point(data = lat_long_vec, aes(x = lat_long_vec$lon, y = lat_long_vec$lat), size = 3, colour = "blue", shape = 19)
where map = map = qmap(location=someplacename, zoom = somezoomvalue)
However, I would like to label the points using the Places column of the dataframe. I have tried the following which hasn't worked.
map + geom_point(data = lat_long_vec, aes(x = lat_long_vec$lon, y = lat_long_vec$lat), size = 3, colour = "blue", shape = 19) + geom_text(aes(label=lat_long_vec$Places),hjust=0, vjust=0)
Can someone help? Thanks
I would use geom_text like this.
library(ggmap)
mydf <- data.frame(lat = 17.245088, lon = 78.299744, places = c('My place name'))
ggmap(get_googlemap(center = paste(mydf$lat[1], mydf$lon[1]),
maptype = 'roadmap',
zoom = 10,
color = 'bw',
scale = 2),
extent = 'panel') +
geom_point(data = mydf,
aes(x = lon, y = lat),
fill = "red",
colour = "black",
size = 3,
shape = 21) +
geom_text(data = mydf,
aes(x = lon,
y = lat,
label = places),
color = 'blue')

Resources