I want to create a map using sf
and ggplot2
libraries in R and show point markers rotated by attribute value. Is there maybe a more simple way than doing it like this using geom_segment()
and vector calculation using sin()
and cos()
?
# load necessary libraries
library(ggplot2)
library(sf)
# load csv data
photo_positions <- readr::read_csv("photos_hamburg.csv") |>
sf::st_as_sf(coords=c('X', 'Y'))
# transform degrees to radians for orientation values
photo_positions[['orientation_rad']] = photo_positions[['orientation']] * pi / 180
# define the arrow length in decimal degrees
arrow_length <- 0.001
# test plot
ggplot(data = photo_positions) +
# extract coordinates
stat_sf_coordinates() +
# draw arrows with orientation from attribute
geom_segment(stat = "sf_coordinates", mapping = aes(geometry = geometry, x = after_stat(x), y = after_stat(y), xend = after_stat(x) + arrow_length * sin(photo_positions[['orientation_rad']]), yend = after_stat(y) + arrow_length * cos(photo_positions[['orientation_rad']])), arrow = arrow(), size = 2, color = "turquoise") +
# draw circle markers
geom_sf(stat = "sf_coordinates", mapping = aes(geometry = geometry, x = after_stat(x), y = after_stat(y)), size = 4, shape = 21, fill = "white") +
# axis labels
xlab("Longitude") + ylab("Latitude") +
#map title
ggtitle("Photos in Hamburg")
I tested it in QGIS. Here's the result.
And here's the CSV data used (imaginary photo spots including orientation):
X,Y,name,orientation
9.991293,53.55456,"Alster view 2",59
9.992967,53.550898,"Rathaus view 2",219
9.995563,53.556932,"Alster view 1",201
9.992591,53.551986,"Rathaus view 1",177
9.995724,53.552775,"Alster view 3",338
Any recommendations are highly appreciated!
EDIT: OK, it seems to be an appropriate solution. My only question is now: How do I add those arrows as a map legend with a horizontal arrow as example?