Общая функция для вставки цветов кластеров в мою карту, сделанную пакетом листовок в R - PullRequest
1 голос
/ 04 мая 2020

Как мне сделать общую функцию для вставки цветов кластеров? Я использовал пакет листовки для создания карты. То, как я это сделал, было «если еще», это сработало, но если, например, у меня есть 15 кластеров, у меня будет много «если еще». Кто-нибудь может мне помочь ?? Кроме того, если возможно, я бы хотел добавить легенду о скоплениях на мою карту. Мой исполняемый код ниже:

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

Большое спасибо !!

Вставить 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

Изображение в качестве примера:

enter image description here

1 Ответ

3 голосов
/ 05 мая 2020

Один хороший и простой способ назначить цвета кластерам - просто индексировать вектор цветов по вектору кластеров. В R цвета могут быть указаны как имена («белый», «красный») или как числа. И есть встроенная функция ?colors(), которая позволяет легко производить выборку или индексирование по другому номеру c вектора:

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

Но leaflet::awesomeIcons поддерживает только определенные цвета, которые выглядят довольно неплохо. Вы можете получить этот список из ?awesomeIcons:

markerColor
Возможные значения: «красный», «затемненный», «светлый», «оранжевый», «бежевый», «зеленый», «темно-зеленый», «светло-зеленый», «синий», «темно-синий», «светло-голубой», «фиолетовый», «темно-пурпурный», «розовый», «кадетовый», «белый», «серый», «светло-серый», «черный» "

Таким образом, мы можем поместить их в вектор и проиндексировать их с помощью столбца кластера:

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" 

Это будет работать до тех пор, пока число кластеров меньше или равно на количество цветов, допустимое в awesomeIcons.


Полный код:

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

Редактировать: добавить два набора точек в одну легенду

Мы можем объединить точки второго набора данных с первым и построить их вместе. Затем, когда мы добавим легенду, все будет вместе.

Мы можем добавить кластер № 19 для второго набора точек. Это будет соответствовать последнему цвету в наборе цветов awesomeIcons. (Вы можете установить это на что угодно, но имейте в виду, что количество кластеров зависит от количества доступных цветов.)

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)

Затем построите график, как раньше:

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
...