Antonio
Antonio

Reputation: 1111

General function to insert the colors of the clusters in my map made by the leaflet package in R

How I do a general function to insert the colors of the clusters? I used the leaflet package to generate the map. The way I did it was "if else", it worked, but if for example, I have 15 clusters, I will have many "if else". Can anybody help me ?? In addition, if possible I would like to put legend of the clusters on my map as well. My executable code is below:

library(leaflet)
library(geosphere)

#database
df<-structure(list(Properties = c(1,2,3,4,5,6,7,8,9,10), Latitude = c(-23.2, -23.6, -23.9, -23.9, -23.6,  -23.5, -23.9, -23.9, -23.6, -23.9), 
Longitude = c(-49.6, -49.6, -49.6, -49.4, -49.3, -49.9, -49.3, -49.2, -49.6, -49.9)), class="data.frame",row.names = c(NA, -10L))

#clusters
d<-as.dist(distm(df[,2:1]))
fit.average<-hclust(d,method="average") 
clusters<-cutree(fit.average, 4) 
df$cluster<-clusters

#Map using leaflet

example=df
getColor <- function(example) {
  sapply(example$cluster, function(cluster) {
    if(cluster == 1) {
      "blue"
    } else if(cluster == 2) {
      "green"
    } else if(cluster == 3) {
      "orange"
    } else {
      "red"
    } })
}

icons <- awesomeIcons(
  icon = 'ios-close',
  iconColor = 'black',
  library = 'ion',
  markerColor = getColor(example)
)

m=leaflet(example) %>% addTiles() %>%
  addAwesomeMarkers(lat=~Latitude, lng = ~Longitude, icon=icons, label=~as.character(cluster))
m

enter image description here

Thank you very much!!

Insert addLegend

df1<-structure(list(Properties = c(1,2,3,4,5), Latitude = c(-23.8, -23.4, -23.2, -23.7,-23.8), 
Longitude = c(-49.9, -49.2, -49.3, -49.1,-49.9)), class="data.frame",row.names = c(NA, -5L))

m = leaflet(example) %>% addTiles() %>%
  addAwesomeMarkers(lat =  ~ Latitude,lng = ~ Longitude,icon = icons,label =  ~ as.character(cluster)) %>% 
addLegend( position = "topright", title="Cluster", colors = ai_colors[1:max(df$cluster)],labels = unique(df$cluster))%>%
addAwesomeMarkers(leaflet(df1) %>% addTiles(), lat=~df1$Latitude, lng = ~df1$Longitude)
m

Image as example:

enter image description here

Upvotes: 1

Views: 648

Answers (1)

teofil
teofil

Reputation: 2384

One good and simple way to assign colors to clusters is to simply index a vector of colors by a vector of clusters. In R colors can be specified as names ('white', 'red') or as numbers. And there is a built in function ?colors() that makes it easy to sample or index by another numeric vector:

> colors()[c(1,4,5,6,9)]
[1] "white"         "antiquewhite1" "antiquewhite2" "antiquewhite3" "aquamarine1" 

But leaflet::awesomeIcons only supports certain colors that look pretty good. You can get this list from ?awesomeIcons:

markerColor
Possible values are "red", "darkred", "lightred", "orange", "beige", "green", "darkgreen", "lightgreen", "blue", "darkblue", "lightblue", "purple", "darkpurple", "pink", "cadetblue", "white", "gray", "lightgray", "black"

So we can put these in a vector and index them with the cluster column:

ai_cols <- c("red", "darkred", "lightred", "orange", "beige", "green", "darkgreen", "lightgreen", "blue", "darkblue", "lightblue", "purple", "darkpurple", "pink", "cadetblue", "white", "gray", "lightgray", "black")
ai_cols[example$cluster]
[1] "red"      "red"      "darkred"  "darkred"  "lightred" "lightred" "orange"   "orange"   "orange"   "orange" 

This will work as long as the number of clusters is less than or equal to the number of colors allowed in awesomeIcons.


Full code:

library(leaflet)
library(geosphere)

#database
df <-
  structure(
    list(
      Properties = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
      Latitude = c(
        -23.2,
        -23.6,
        -23.9,
        -23.9,
        -23.6,
        -23.5,
        -23.9,
        -23.9,
        -23.6,
        -23.9
      ),
      Longitude = c(
        -49.6,
        -49.6,
        -49.6,
        -49.4,
        -49.3,
        -49.9,
        -49.3,
        -49.2,
        -49.6,
        -49.9
      )
    ),
    class = "data.frame",
    row.names = c(NA,-10L)
  )

#clusters
d <- as.dist(distm(df[, 2:1]))
fit.average <- hclust(d, method = "average")
clusters <- cutree(fit.average, 4)
df$cluster <- clusters

#Map using leaflet

example = df
ai_colors <-
  c(
    "red",
    "darkred",
    "lightred",
    "orange",
    "beige",
    "green",
    "darkgreen",
    "lightgreen",
    "blue",
    "darkblue",
    "lightblue",
    "purple",
    "darkpurple",
    "pink",
    "cadetblue",
    "white",
    "gray",
    "lightgray",
    "black"
  )

clust_colors <- ai_colors[example$cluster]

icons <- awesomeIcons(
  icon = 'ios-close',
  iconColor = 'black',
  library = 'ion',
  markerColor = clust_colors
)

m = leaflet(example) %>% addTiles() %>%
  addAwesomeMarkers(
    lat =  ~ Latitude,
    lng = ~ Longitude,
    icon = icons,
    label =  ~ as.character(cluster)
  )
m

Edit: add two sets of points in one legend

We can combine the points of the second dataset with the first, and plot them together. Then when we add legend, everything is going to be together.

We can add a cluster number 19 for the second set of points. This would correspond to the last color in the awesomeIcons color set. (You can set this to anything, but keep in mind the number of clusters vs. number of available colors.)

df1 <-
  structure(
    list(
      Properties = c(1, 2, 3, 4, 5),
      Latitude = c(-23.8,-23.4,-23.2,-23.7, -23.8),
      Longitude = c(-49.9,-49.2,-49.3,-49.1, -49.9)
    ),
    class = "data.frame",
    row.names = c(NA,-5L)
  )


df1$cluster <- 19
all_points <- rbind(example, df1)

Then plot as before:

clust_colors <- ai_colors[all_points$cluster]

icons <- awesomeIcons(
  icon = 'ios-close',
  iconColor = 'black',
  library = 'ion',
  markerColor = clust_colors
)

m = leaflet(all_points) %>% addTiles() %>%
  addAwesomeMarkers(
    lat =  ~ Latitude,
    lng = ~ Longitude,
    icon = icons,
    label =  ~ as.character(all_points$cluster)
  ) %>%
  addLegend(
    position = "topright",
    title = "Cluster",
    colors = ai_colors[unique(all_points$cluster)],
    labels = unique(all_points$cluster)
  ) 
m

Upvotes: 2

Related Questions