Reputation: 1111
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
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:
Upvotes: 1
Views: 648
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