Overlap map created in ggplot and shapefile - r

I am trying to overlap a shp layer on a map created with ggplot, when I plot the two graphs are independent, what do you suggest me to do to overlap both layers?
data.shape<-readOGR(dsn="departamentos",layer="DEPARTAMENTOS")
ggplot()+
geom_tile(data = tx_trend, aes(x = longitude, y = latitude, fill = slope))+
scale_fill_gradientn(colors = rev(pals::linearlhot(100)), name = "ºC/10y", limits = c(0.1,0.5)) +
#scale_fill_gradientn(colors = (pals::isol(100)), name = "ºC/10y", limits = c(0.1,0.45)) +
# geom_point(data = filter(tx_trend, sign < 0.01),aes(x = longitude, y = latitude, color = "Sign. trend \n p-value <0.01"),
geom_point(data = filter(tx_trend, sign < 0.01),aes(x = longitude, y = latitude, color = "Sign. trend \n p-value <0.01"),
size = 0.7, show.legend = T) +
scale_color_manual(values = c("black"), name = "")+
coord_fixed(1.3)+
xlab("Longitude") + ylab("Latitude")+
labs(title = "Decadal trend Summer",
subtitle = "(1981-2016)",
caption = "")+
theme_bw() +
guides(fill = guide_colourbar(barwidth = 9, barheight = 0.5, title.position="right"))+
theme(legend.position = "bottom")

Difficult without a reproducible example but I give it a try! So here are my suggestions:
Install the 'sf' package with install.packages("sf") and load library with library(sf)
Import your layer in sf format with st_read():
data.shape <- st_read(dsn="departamentos", layer="DEPARTAMENTOS")
Use the dedicated geom_sf() to plot your shape on your tile and point layers. You just need to add the following line of code in the ggplot() chunk of code:
geom_sf(data = st_geometry(data.shape), fill = NA, color = "red") +
coord_sf(default_crs = sf::st_crs(4326)) +
So I suggest:
ggplot()+
geom_tile(data = tx_trend, aes(x = longitude, y = latitude, fill = slope))+
scale_fill_gradientn(colors = rev(pals::linearlhot(100)), name = "ºC/10y", limits = c(0.1,0.5)) +
#scale_fill_gradientn(colors = (pals::isol(100)), name = "ºC/10y", limits = c(0.1,0.45)) +
# geom_point(data = filter(tx_trend, sign < 0.01),aes(x = longitude, y = latitude, color = "Sign. trend \n p-value <0.01"),
geom_point(data = filter(tx_trend, sign < 0.01),aes(x = longitude, y = latitude, color = "Sign. trend \n p-value <0.01"),
size = 0.7, show.legend = T) +
geom_sf(data = st_geometry(data.shape), fill = NA, color = "red") + # ADDED HERE
coord_sf(default_crs = sf::st_crs(4326)) + # ADDED HERE
scale_color_manual(values = c("black"), name = "")+
coord_fixed(1.3)+
xlab("Longitude") + ylab("Latitude")+
labs(title = "Decadal trend Summer",
subtitle = "(1981-2016)",
caption = "")+
theme_bw() +
guides(fill = guide_colourbar(barwidth = 9, barheight = 0.5, title.position="right"))+
theme(legend.position = "bottom")

Related

Legend with geom_line and geom_ribbon and geom_point

I've been searching the answer for two days and still can't find how to do this. The closest cases I found here and here. But the former has no points on the plots and the latter has no answer. Without much ado, how to add points to my legend?
This is my data:
Year <- c(2003:2020)
TheData <- c(72.6, 72.7, 72.6, 72.5, 72.4, 72.1, 71.8, 71.7, 71.8, 72.3, 72.7,
72.9, 73.1, 73.3, 73.8, 74.7, 75.7, 77.1)
Lower <- c(72.33316, 72.05961, 71.8218, 71.62303, 71.46657, 71.35567, 71.29362,
71.28368, 71.32915, 71.43331, 71.59947, 71.83096, 72.13113, 72.50333,
72.95092, 73.47728, 74.08581, 74.77989)
Upper <- c(73.46626, 73.24078, 73.05676, 72.91817, 72.82899, 72.79323, 72.81489,
72.89794, 73.04639, 73.26418, 73.55528, 73.92363, 74.37315, 74.90775,
75.53132, 76.24776, 77.06094, 77.97473)
Model <- c(72.89971, 72.65020, 72.43928, 72.27060, 72.14778, 72.07445, 72.05425,
72.09081, 72.18777, 72.34874, 72.57738, 72.87730, 73.25214, 73.70554,
74.24112, 74.86252, 75.57337, 76.37731)
MyDF <- data.frame(Year, TheData, Lower, Upper, Model)
This is my code:
library("ggplot2")
ggplot(MyDF, aes(x = Year, y = TheData)) +
geom_point(aes(y = TheData), size = 2.5) +
geom_line(aes(x = Year, y = Model, color = "Model", fill = "Model")) +
geom_ribbon(aes(ymin = Lower, ymax = Upper, x = Year,
fill = "Confidence Interval"), alpha = 0.15) +
scale_colour_manual(
name = "", values = c("Confidence Interval" = "transparent",
"Model" = "black")) +
scale_fill_manual(
name = "", values = c("Confidence Interval" = "grey12",
"Model" = "transparent")) +
theme(legend.position = "bottom")
This is my plot.
If you want to get a legend you have to map on an aesthetic, e.g. you could map on the shape aes to get a legend for your points too:
library("ggplot2")
ggplot(MyDF, aes(x = Year, y = TheData)) +
geom_point(aes(y = TheData, shape = "TheData"), size = 2.5) +
geom_line(aes(x = Year, y = Model, color = "Model")) +
geom_ribbon(aes(ymin = Lower, ymax = Upper, x = Year,
fill = "Confidence Interval"), alpha = 0.15) +
scale_colour_manual(
name = "", values = c("Confidence Interval" = "transparent",
"Model" = "black")) +
scale_fill_manual(
name = "", values = c("Confidence Interval" = "grey12",
"Model" = "transparent")) +
theme(legend.position = "bottom") +
labs(shape = "")
If somebody is interested to move the legend to free space on the plot there is an obvious way to do so:
ggplot(MyDF, aes(x = Year, y = TheData)) +
geom_point(aes(y = TheData, shape = "TheData"), size = 2.5) +
geom_line(aes(x = Year, y = Model, color = "Model")) +
geom_ribbon(aes(ymin = Lower, ymax = Upper, x = Year,
fill = "Confidence Interval"), alpha = 0.15) +
scale_colour_manual(
name = "", values = c("Confidence Interval" = "transparent",
"Model" = "black")) +
scale_fill_manual(
name = "", values = c("Confidence Interval" = "grey12",
"Model" = "transparent")) +
theme(legend.position = "bottom") +
labs(shape = "") +
theme(legend.position = c(.4, .7))
But the legend appears stacked:
Adding + guides(color = guide_legend(nrow = 1)) does not work:
My colleague have proposed to add legend.box = "horizontal". This code works:
ggplot(MyDF, aes(x = Year, y = TheData)) +
geom_point(aes(y = TheData, shape = "TheData"), size = 2.5) +
geom_line(aes(x = Year, y = Model, color = "Model")) +
geom_ribbon(aes(ymin = Lower, ymax = Upper, x = Year,
fill = "Confidence Interval"), alpha = 0.15) +
scale_colour_manual(
name = "", values = c("Confidence Interval" = "transparent",
"Model" = "black")) +
scale_fill_manual(
name = "", values = c("Confidence Interval" = "grey12",
"Model" = "transparent")) +
theme(legend.position = "bottom") +
labs(shape = "") +
theme(legend.position = c(.4, .7), legend.box = "horizontal") +
guides(color = guide_legend(nrow = 1))
The plot looks like this:
Still, I wonder why the legend appears in different boxes and how to put it together?

Insert US State abbreviation on Map togeter numbers with ggplot2

I have the following data set:
Then with this code:
ggplot(data= data.to.work.final, aes(map_id = State_L)) +
geom_map(aes(fill = Suicide_Rate_By_Pop), color= "white", map = fifty_states) +
expand_limits(x = fifty_states$long, y = fifty_states$lat) +
coord_map() +
geom_text(data = fifty_states %>%
group_by(id) %>%
summarise(lat = mean(c(max(lat), min(lat))),
long = mean(c(max(long), min(long)))) %>%
mutate(State_L = id) %>%
left_join(data.to.work.final, by = "State_L"), size=2,
aes(x = long, y = lat, label = Suicide_Rate_By_Pop)
#aes(x = long, y = lat, label = state)
) +
scale_x_continuous(breaks = NULL) +
scale_y_continuous(breaks = NULL) +
labs(x = "", y = "") +
labs(fill = "Suicides Rate by 100,000 inhabitants")+
scale_fill_gradientn(colours=rev(heat.colors(10)),na.value="grey90",
guide = guide_colourbar(barwidth = 25, barheight = 0.4,
#put legend title on top of legend
title.position = "top")
) +
theme(legend.position = "bottom",
legend.title=element_text(size=10),
legend.text=element_text(size=08))
I produced the following map of us with suicide rate inside of each state:
I would like to insert the abbreviation of each state and below the suicide rate, like:
CA
1433
Somebody would help please?**

How do I add a legend using aes, ggplot2 and maps?

I'm trying to make a map with points plotted for the Canadian prairie provinces, but I'm having no luck adding in a legend to my map. I'm very new to mapping in r, so I'm not understanding how I should include aes to get a legend. My data for siteDataTrees is from an excel csv file and the top looks like this:
siteDataTrees
and the data for siteDataBoth is also from a csv file and the top looks like this:
siteDataBoth.
Here's what I have so far for my code:
library(maps)
library(ggplot2)
library(sf)
prairies1 <- map("worldHires","Canada", xlim = c(-120,-87), ylim = c(49,61),
plot = FALSE, fill = TRUE)
prairies <- st_as_sf(prairies1)
ggplot(data = prairies) +
geom_sf() +
geom_point(data = siteDataTrees, aes(x = long, y = lat), size = 2.5, pch = 21,
fill = "purple", show.legend = TRUE) +
geom_point(data = siteDataBoth, aes(x = long, y = lat), size = 2.5, pch = 21,
fill = "light green", show.legend = TRUE) +
geom_text(data = locations, aes(x = long, y = lat, label = name),
size = 2, col = "black", check_overlap = FALSE) +
annotation_scale(location = "tr", width_hint = 0.2) +
ggtitle("Climate Stations and Tree Chronology Locations for South AB") +
labs(x = "latitude", y = "longitude") +
theme(legend.position = "right") +
coord_sf(xlim = c(-115, -110), ylim = c(48.9, 50.49), expand = FALSE)
I've also included a map to show what it looks like without the legend.
How should I take the data frame prairies and use it with aes to include a legend? Is there another way to add in a legend in ggplot2 without using the aes function? Thank you in advance for your help and please let me know if something is missing as this is my first posting
Let me give you a couple of examples on how to work out a legend using a slightly modified example from r-spatial.
First we prepare the data:
library(maps)
library(ggplot2)
library(sf)
library(rnaturalearth)
library(rnaturalearthdata)
world <- ne_countries(scale = "medium", returnclass = "sf")
(sites <- data.frame(longitude = c(-80.144005, -80.109),
latitude = c(26.479005,26.83),
type = c("tree", "station")))
Now we plot. Case 1: color is not an issue
ggplot(data = world) +
geom_sf() +
geom_point(data = sites,
aes(x = longitude, y = latitude, fill = type),
size = 4,
shape = 23) +
coord_sf(xlim = c(-88, -78), ylim = c(24.5, 33), expand = FALSE) +
theme(legend.position = "bottom")
Case 2: fill color is an issue.
Here we can use a named vectors to pass the colors and the labels we want by type of point. For example:
mapfill <- c('tree' = "forestgreen", 'station' = "purple")
maplab <- c('tree' = "trees in prairies", 'station' = "Stations in prairies")
Then we plot combining both mapfill and maplab:
ggplot(data = world) +
geom_sf() +
geom_point(data = sites, aes(x = longitude, y = latitude, fill = type), size = 4,
shape = 23) +
scale_fill_manual(values = mapfill, labels = maplab) +
coord_sf(xlim = c(-88, -78), ylim = c(24.5, 33), expand = FALSE) +
theme(legend.position = "bottom")
Remark 1 If you do not want type in the legend title you can either delete it using legend. title = element_blank() within theme
Remark 2 If, instead of fill, you are using color, use function scale_color_manual. If you are combining both fill and color do the same with scale_***_manual
In spirit of full disclosure, if you do not mind the colors and you want a quick fix (and I cannot stress this enough) you can also code fill = "TextYouWantInLegend" within aes. See following example:
ggplot(data = world) +
geom_sf() +
geom_point(data = sites[1,], aes(x = longitude, y = latitude, fill = "toto"), size = 4,
shape = 23) +
geom_point(data = sites[2,], aes(x = longitude, y = latitude, fill = "koko"), size = 4,
shape = 23) +
coord_sf(xlim = c(-88, -78), ylim = c(24.5, 33), expand = FALSE) +
theme(legend.position = "bottom")

customize two legends inside one graph in ggplot2

I wanted to comment on the following doubt.
Using this code:
Plot<-data.frame(Age=c(0,0,0,0,0),Density=c(0,0,0,0,0),Sensitivity=c(0,0,0,0,0),inf=c(0,0,0,0,0),sup=c(0,0,0,0,0),tde=c(0,0,0,0,0))
Plot[1,]<-c(1,1,0.857,0.793,0.904,0.00209834)
Plot[2,]<-c(1,2,0.771 ,0.74,0.799,0.00348286)
Plot[3,]<-c(1,3,0.763 ,0.717,0.804,0.00577784)
Plot[4,]<-c(1,4,0.724 ,0.653,0.785,0.00504161)
Plot[5,]<-c(2,1,0.906,0.866,0.934,0.00365742)
Plot[6,]<-c(2,2,0.785 ,0.754,0.813,0.00440399)
Plot[7,]<-c(2,3,0.660,0.593,0.722,0.00542849)
Plot[8,]<-c(2,4,0.544,0.425,0.658,0.00433052)
names(Plot)<-c("Age","Mammographyc density","Sensitivity","inf","sup","tde")
Plot$Age<-c("50-59","50-59","50-59","50-59","60-69","60-69","60-69","60-69")
Plot$Density<-c("Almost entirely fat","Scattered fibroglandular density","Heterogeneously dense","Extremely dense","Almost entirely fat","Scattered fibroglandular density","Heterogeneously dense","Extremely dense")
levels(Plot$Age)<-c("50-59","60-69")
levels(Plot$Density)<-c("Almost entirely fat","Scattered fibroglandular density","Heterogeneously dense","Extremely dense")
pd <- position_dodge(0.2) #
Plot$Density <- reorder(Plot$Density, 1-Plot$Sensitivity)
ggplot(Plot, aes(x = Density, y = 100*Sensitivity, colour=Age)) +
geom_errorbar(aes(ymin = 100*inf, ymax = 100*sup), width = .1, position = pd) +
geom_line(position = pd, aes(group = Age), linetype = c("dashed")) +
geom_point(position = pd, size = 4)+
scale_y_continuous(expand = c(0, 0),name = 'Sensitivity (%)',sec.axis = sec_axis(~./5, name = 'Breast cancer detection rate (per 1000 mammograms)', breaks = c(0,5,10,15,20),
labels = c('0‰',"5‰", '10‰', '15‰', '20‰')), limits = c(0,100)) +
geom_line(position = pd, aes(x = Density, y = tde * 5000, colour = Age, group = Age), linetype = c("dashed"), data = Plot) +
geom_point(shape=18,aes(x = Density, y = tde * 5000, colour = Age, group = Age), position = pd, size = 4) +
theme_light() +
scale_color_manual(name="Age (years)",values = c("50-59"= "grey55", "60-69" = "grey15")) +
theme(legend.position="bottom") + guides(colour = guide_legend(), size = guide_legend(),
shape = guide_legend())
I have made the following graph,
in which the axis on the left is the scale of the circles and the axis on the right is the scale of the diamonds. The fact is that I would like to have a legend approximately like this:
But it is impossible for me, I have tried suggestions of other threads like scale_shape and different commands in guides but I have not got success. I just want to make clear the difference in what shape and color represent.
Would someone know how to help me?
Best regards,
What you should do is a panel plot to avoid the confusion of double axes:
library(dplyr)
library(tidyr)
Plot %>%
gather(measure, Result, Sensitivity, tde) %>%
ggplot(aes(x = Density, y = Result, colour=Age)) +
geom_errorbar(aes(ymin = inf, ymax = sup), width = .1, position = pd,
data = . %>% filter(measure == "Sensitivity")) +
geom_line(aes(group = Age), position = pd, linetype = "dashed") +
geom_point(position = pd, size = 4)+
# scale_y_continuous(expand = c(0, 0), limits = c(0, 1)) +
scale_y_continuous(labels = scales::percent) +
facet_wrap(~measure, ncol = 1, scales = "free_y") +
theme_light() +
scale_color_manual(name="Age (years)",values = c("50-59"= "grey55", "60-69" = "grey15")) +
theme(legend.position="bottom")
But to do what you asked, you problem is that you have only 1 non-positional aesthetic mapped so you cannot get more than one legend. To force a second legend, you need to add a second mapping. It can be a dummy mapping that has no effect, as below we map alpha but then manually scale both levels to 100%. This solution is not advisable because, as you have done in your example of a desired legend, it is easy to mix up the mappings and have your viz tell a lie by mislabeling which points are sensitivity and which are detection rate.
ggplot(Plot, aes(x = Density, y = 100*Sensitivity, colour=Age, alpha = Age)) +
geom_errorbar(aes(ymin = 100*inf, ymax = 100*sup), width = .1, position = pd) +
geom_line(position = pd, aes(group = Age), linetype = c("dashed")) +
geom_point(position = pd, size = 4)+
scale_y_continuous(expand = c(0, 0),name = 'Sensitivity (%)',sec.axis = sec_axis(~./5, name = 'Breast cancer detection rate (per 1000 mammograms)', breaks = c(0,5,10,15,20),
labels = c('0‰',"5‰", '10‰', '15‰', '20‰')), limits = c(0,100)) +
geom_line(position = pd, aes(x = Density, y = tde * 5000, colour = Age, group = Age), linetype = c("dashed"), data = Plot) +
geom_point(shape=18,aes(x = Density, y = tde * 5000, colour = Age, group = Age), position = pd, size = 4) +
theme_light() +
scale_color_manual(name="Age (years)",values = c("50-59"= "grey55", "60-69" = "grey15")) +
scale_alpha_manual(values = c(1, 1)) +
guides(alpha = guide_legend("Sensitivity"),
color = guide_legend("Detection Rate", override.aes = list(shape = 18))) +
theme(legend.position="bottom")

Mapping issue with fill when plotting multiple countries

I am trying to plot a map with Peru and Ecuador, that presents two simple lat and long points (San Jose and Lima in Peru).
I'm having some issue with the fill when incorporating both Peru and Ecuador into my map.
library(ggplot2)
library(ggmap)
library(maps)
library(mapdata)
peru_ecuador <- map_data("world",c("peru", "ecuador"))
# Add study site points (San Jose and Lima)
points <- data.frame(
long = c(-79.81, -77.04),
lat = c(-6.77, -12.04),
names = c("San Jose", "Lima"),
stringsAsFactors = FALSE
)
# Plot the map
ggplot() +
geom_polygon(data = peru_ecuador, aes(x=long, y = lat), fill = "grey40", color
= "grey90", alpha = 1) +
geom_point(data = points, aes(x = long, y = lat), color = "red", size = 2,
alpha = 0.8) +
geom_text(aes(x = long, y = lat, label = c("San Jose", "Lima")), data =
points, size = 2, hjust = 1.3) +
geom_area(x = 10) +
coord_fixed(1.3) +
labs(x = "Longitude", y = "Latitude", size = 2) +
theme_bw(base_size = 5)
I would also really love some advise on how best to resize the plot area window of the map. As in change the x and y axis width and length. When I plot just a map of Peru, some of my map information is cut off by the size of the plot area. Please see below:
peru <- map_data("world","peru")
ggplot() +
geom_polygon(data = peru, aes(x=long, y = lat), fill = "grey40", color =
"grey90", alpha = 1) +
geom_point(data = points, aes(x = long, y = lat), color = "red", size = 2,
alpha = 0.8) +
geom_text(aes(x = long, y = lat, label = c("San Jose", "Lima")), data =
points, size = 2, hjust = 1.3) +
geom_area(x = 10) +
coord_fixed(1.3) +
labs(x = "Longitude", y = "Latitude", size = 2) +
theme_bw(base_size = 5)

Resources