I try to do this ggplot:
library (sf)
library(dplyr)
library(ggplot2)
continents.f.xy <- st_zm(continents.f)
continents_map_SA <- continents.f.xy%>%
dplyr::bind_rows() %>% #bind the list into a data.frame
sf::st_cast(to = "POINT") %>% #convert polygon to a list of points
dplyr::mutate(
long = sf::st_coordinates(geometry)[,1], #retrieve X coord
lat = sf::st_coordinates(geometry)[,2], #retrieve Y coord
group = rep(1, nrow(.)) #create a group column
) %>%
sf::st_drop_geometry() #drop the geometry column
continents_map_SA <- continents_map_SA%>%select(long,lat,group)
continents_map_SA <- fortify(continents_map_SA , region = "South America")
plotactual.high<-ggplot() +
geom_raster(data = ras.actual.df, aes(x = longitude, y = latitude, fill = hpds)) +
scale_fill_gradientn(name="hpds",colours = c("white","red"))+
#scale_y_continuous(breaks=seq(-50, 50, by = 10)) +
#scale_x_continuous(breaks=seq(-100, 0, by = 10)) +
xlab("longitude") + ylab("latitude") +
geom_polygon(data = continents_map_SA, aes(x=long, y = lat, group = group), fill = NA, color = "black") +
annotate(geom="text", x=-45, y=-45, label="Potential area = 9,338.380 km2", color="black", family = c("serif"), size=4.5) +
coord_quickmap() +
theme_bw() +
theme(panel.border = element_blank(), plot.margin = margin(r = 1, l = 1), panel.grid.major = element_blank(),
panel.grid.minor = element_blank(), axis.line = element_line(colour = "black"),
text=element_text(size=16, family="serif"),legend.position="none")
plotactual.high
and I have as a result:
I also use fortify
and group
inside aes
in geom_polygon
and arrange
.
Your problem occurs because you need to account for the fact that you are actually creating a multipolygon.
In order to do that, you need to use something like summarise()
in conjunction with st_combine()
. To ensure multipolygons are created correctly, a grouping function defining each individual polygon (ring) within a multipolygon is also required. Otherwise, they will all be joined as a single polygon. By example, you need something like:
summarise(geometry = combine(geometry), .by = c(country, sub_country))
where country is the main multipolygon group, and sub_country defines each individual polygon within country. How this is executed will depend on the structure of your data. For instance, the map_data()
world dataset that comes with ggplot2
has "region" and "group" columns for this purpose.
In your use case it is better to create geospatial objects. In other words, if you want a continent for a map, create a polygon or multipolygon sf. Then you can simply use ggplot2::geom_sf()
to plot your data.
Here is a method to create a South America multipolygon sf using data from the rnaturalearth
package. As it is already a multipolygon dataset, it skips the requirement to manipulate raw coordinate values. I have used scale = large
to return the most detailed option. This can be changed to medium
or small
if it does not suit. You may be prompted to install another rnaturalearth
package for the most detailed data.
library(sf)
library(dplyr)
library(rnaturalearth)
library(ggplot2)
sa_countries <- c("Brazil", "Peru", "Venezuela", "Chile", "Ecuador",
"Bolivia", "Paraguay", "Uruguay", "Guyana", "Suriname",
"French Guiana", "Falkland Islands", "Colombia", "Argentina")
continents_map_SA <- ne_countries(scale = "large") %>%
filter(admin %in% sa_countries) %>%
st_union()
ggplot() +
geom_sf(data = continents_map_SA)