Reputation: 5897
Recently, I have started learning about the R package "leaflet". This package allows you to identify points on a map provided their latitude and longitude. I created some fake data and I was able to successfully make a leaflet plot (with popup options that display properties of each point):
library(dplyr)
library(leaflet)
map_data <- data.frame("Lat" = c(43.6426, 43.6424, 43.6544, 43.6452, 43.6629), "Long" = c(-79.3871, -79.3860, -79.3807, -79.3806,-79.3957 ),
"Job" = c("Economist", "Economist", "Teacher", "Teacher", "Lawyer"),
"First_Name" = c("John","James", "Jack", "Jason", "Jim"),
"Last_Name" = c("Smith","Charles", "Henry", "David", "Robert"),
"vehicle" = c("car", "van", "car", "none", "car"))
map_data %>% leaflet() %>% addTiles() %>% addMarkers(clusterOption=markerClusterOptions(), lng = map_data$Long, lat = map_data$Lat, popup = paste("Job", map_data$Job, "<br>", "First_Name:", map_data$First_Name, "<br>", "Last_Name:", map_data$Last_Name, "<br>", "vehicle:", map_data$vehicle, "<br>" ))
Now, I wanted to take this a few steps further and color code the points based on the "job" of each individual. I found this github tutorial over here that I want to follow: https://poldham.github.io/abs/mapgbif.html
Using the same data I previously created, I tried to re-create a similar plot (slightly modifying it by adding my own popup options). However, when I run my code, I now get an empty map. Can someone please tell me what I am doing wrong? I have attached my code below:
library(dplyr)
library(leaflet)
library(RColorBrewer)
#create map data
map_data <- data.frame("Lati" = c(43.6426, 43.6424, 43.6544, 43.6452, 43.6629), "Longi" = c(-79.3871, -79.3860, -79.3807, -79.3806,-79.3957 ),
"Job" = c("Economist", "Economist", "Teacher", "Teacher", "Lawyer"),
"First_Name" = c("John","James", "Jack", "Jason", "Jim"),
"Last_Name" = c("Smith","Charles", "Henry", "David", "Robert"),
"vehicle" = c("car", "van", "car", "none", "car"))
#create initial map
map <- leaflet::leaflet(map_data) %>%
addTiles() %>% # Add default OpenStreetMap map tiles
addMarkers(~Longi, ~Lati, popup = map_data$Job)
#add markers
map <- leaflet(map_data) %>% addTiles() %>% addCircleMarkers(~Longi,
~Lati, popup = map_data$Job, radius = 1, fillOpacity = 0.5, clusterOptions = markerClusterOptions())
map <- leaflet(map_data) %>% addTiles() %>% addCircleMarkers(~Longi, ~Lati,
popup = map_data$Job, radius = 1, weight = 2, opacity = 0.5, fill = TRUE,
fillOpacity = 0.2)
#create colors (is it possible to make the colors Red, Blue and Green?)
previewColors(colorFactor("Paired", domain = NULL), LETTERS[1:3])
kingdom <- c("Economist", "Lawyer", "Teacher")
my_palette <- brewer.pal(3, "Paired")
previewColors(colorFactor(my_palette, levels = kingdom), kingdom)
factpal <- colorFactor(my_palette, levels = kingdom)
species_circle <- leaflet(map_data) %>% addTiles() %>% addCircleMarkers(~Longi,
~Lati, popup = map_data$Job, radius = 1, weight = 2, opacity = 0.5,
fill = TRUE, fillOpacity = 0.2, color = ~factpal(kingdom))
species_circle
groups = unique(map_data$Job)
#finalize map
map = leaflet(map_data) %>% addTiles(group = "OpenStreetMap")
for (i in groups) {
data = map_data[map_data$kingdom == i, ]
map = map %>% addCircleMarkers(data = data, ~Longi, ~Lati, radius = 1,
weight = 2, opacity = 0.5, fill = TRUE, fillOpacity = 0.2, color = ~factpal(kingdom),
group = i)
}
map %>% addLayersControl(overlayGroups = groups, options = layersControlOptions(collapsed = FALSE)
%>% addTiles() %>% # Add default OpenStreetMap map tiles
addMarkers(lng = map_data$Long, lat = map_data$Lat,
popup = paste("Job", map_data$Job, "<br>",
"First_Name:", map_data$First_Name, "<br>",
"Last_Name:", map_data$Last_Name, "<br>", "vehicle:", map_data$vehicle, "<br>" ))
Thanks!
Upvotes: 0
Views: 230
Reputation: 123818
The main issue with your code is that you filter on variable map_data$kingdom
(which is no column of map_data
) in the for loop instead of on variablr map_data$Job
. Hence data
is always an empty df and you don't get any markers.
Besides that:
for
loop~factpal(Job)
on color instead of ~factpal(kingdom)
.map_data$
. Simply use the name of the variable. Leaflet by default will look for these variables in the dataset you provided with leaflet(map_data)
I reduced all the unnecessary code to focus on the main map code. For illustration purposes I increased the radius of the cirleMarkers to 10 and set the opacity to 1.
library(dplyr)
library(leaflet)
library(RColorBrewer)
# create map data
map_data <- data.frame(
"Lati" = c(43.6426, 43.6424, 43.6544, 43.6452, 43.6629), "Longi" = c(-79.3871, -79.3860, -79.3807, -79.3806, -79.3957),
"Job" = c("Economist", "Economist", "Teacher", "Teacher", "Lawyer"),
"First_Name" = c("John", "James", "Jack", "Jason", "Jim"),
"Last_Name" = c("Smith", "Charles", "Henry", "David", "Robert"),
"vehicle" = c("car", "van", "car", "none", "car")
)
kingdom <- c("Economist", "Lawyer", "Teacher")
my_palette <- brewer.pal(3, "Paired")
factpal <- colorFactor(my_palette, levels = kingdom)
groups <- unique(map_data$Job)
# finalize map
map <- leaflet(map_data) %>%
addTiles(group = "OpenStreetMap") %>%
addCircleMarkers(~Longi, ~Lati, popup = ~Job,
radius = 10, weight = 2, opacity = 1, color = ~factpal(Job),
fill = TRUE, fillOpacity = 1, group = ~Job
)
map %>%
addLayersControl(overlayGroups = groups, options = layersControlOptions(collapsed = FALSE)) %>%
addTiles() %>%
addMarkers(lng = ~Longi,
lat = ~Lati,
popup = ~paste("Job", Job, "<br>",
"First_Name:", First_Name, "<br>",
"Last_Name:", Last_Name, "<br>", "vehicle:", vehicle, "<br>"))
EDIT To achieve the features you mentioned in your comment you could do:
If you want different colors you can simply pass any color vector to colorFactor
, e.g.
my_palette <- c("red", "green", "blue")
factpal <- colorFactor(my_palette, levels = kingdom)
To remove the pins drop the line starting with addMarkers
. In that case you have to move the code for the popup
into addCircleMarkers
(but be aware that there is already a popup=~Job
in addCircleMarkers
, i.e. overwrite this one). Another option would be to add group=~Job
to addMarkers
. Doing so only the pins for checked jobs will appear on the map.
Upvotes: 1