3

I am attempting to map some geom-points/cordinates to a map of the country Sri Lanka. I am able to map the district borders, and the population as expected, but I am having trouble plotting the geom points onto the map.

Install package

devtools::install_github("thiyangt/ceylon")

Load package

library("ceylon")
library(tidyverse)
library(sp)
library(viridis)

data(sf_sl_0)

Mapping only Sri Lanka

ggplot(sf_sl_0) + geom_sf()

Mapping the districts of Sri Lanka + population

ggplot(district) + geom_sf(aes(fill = population), show.legend = TRUE) +  scale_fill_viridis()

enter image description here

Mappping specific geom-cordinates onto the map of Sri Lanka districts

These are the cordinates I want to map (yes, they are definitely within SL)

df_cord <- data.frame (lat  = c("6.2441521", "6.2234515"),
                  lon = c("80.0590804", "80.2126109"))

I tried:

ggplot(district) + 
  geom_sf(df_cord) +  scale_fill_viridis() +
  geom_point(
    data = df_cord,
    aes(x = lon, y = lat),
    size = 4,
    shape = 23,
    fill = "darkred"
  )

But I get an error: Error in validate_mapping(): ! mapping must be created by aes()

It looks like I might need to find the x,y cordinates of every geom point, and then map it with cord_sf? But I am not having an luck figuring out how to do this. I found a cool function called usmap::usmap_transform, which converts US geom points to x,y cordinates... but I can't figure out how to do the same for this map of Sri Lanka.

I am very new to mapping -- could someone please advise? Many thanks! I am open to other approaches/solutions!

NewBee
  • 990
  • 1
  • 7
  • 26

3 Answers3

3

One way would be to convert the coordinates to an sf object using st_as_sf and plot them using geom_sf. Don't forget to reproject the data to the same coordinate sistem:

library(ceylon)
library(tidyverse)
library(sp)
library(viridis)
library(sf)

data(district)

df_cord <- data.frame (lat  = c(6.2441521, 6.2234515),
                       lon = c(80.0590804, 80.2126109))

df_cord  <- df_cord %>%
  st_as_sf(coords = c("lon", "lat"), crs = 4326) %>%
  st_transform(crs = st_crs(district)) #reproject coords using the coordinate system of the polygons

#plot

ggplot(district) + 
  geom_sf(aes(fill = population),  show.legend = TRUE) +
  geom_sf(data = df_cord ,
          size = 4,
          shape = 23,
          fill = "darkred") +
  scale_fill_viridis() 

enter image description here

missuse
  • 19,056
  • 3
  • 25
  • 47
0

I think you can't assign two data frames in ggplot.

Put the latitude and longitude values ​​inside the geom_point's aes(). Remember that longitude is the x-axis and latitude is the y-axis.

Try this:

ggplot() +  
  geom_sf(district) +
  scale_fill_viridis() +
  geom_point(
    aes(x = c("80.0590804", "80.2126109"), 
        y =c("6.2441521", "6.2234515")),
    size = 4,
    shape = 23,
    fill = "darkred"
  )
Lucca Nielsen
  • 1,497
  • 3
  • 16
  • Thanks for your suggestions, I am getting an error when I run your code: Error in `check_aesthetics()`: ! Aesthetics must be either length 1 or the same as the data (26): x and y – NewBee May 12 '22 at 01:51
  • Just edited the answer with other sugestion. Try again :P – Lucca Nielsen May 12 '22 at 01:56
  • Still getting Error in `validate_mapping()`: ! `mapping` must be created by `aes()` – NewBee May 12 '22 at 03:17
0

You can add annotations (annotate) which will display your two coordinates. Also, set the right coordinate system like this:

ggplot(district) + 
  geom_sf(aes(fill = population), show.legend = TRUE) +  
  annotate("point", x = 80.0590804, y = 6.2441521, colour = "red", size = 2) +
  annotate("point", x = 80.2126109, y = 6.2234515, colour = "red", size = 2) +
  coord_sf(default_crs = sf::st_crs(4326)) +
  scale_fill_viridis()

Output:

enter image description here

Quinten
  • 35,235
  • 5
  • 20
  • 53