2016-05-30 4 views
3

Следующий код создает фоновую картограмму согласно Иерархической кластеризации (с использованием hclust() и cutree()):г: Choropleth с настраиваемой легендой и постоянным отображением названий стран

library(plotly) 
library(cluster) 

hc <- hclust(dist(df), method = "complete") 
df$member <- cutree(hc, 5) 

cluster.means = (as.data.frame(aggregate(df[,-1], list(cluster= df$member), mean)))[,-4] 

g = list(
    scope = 'africa', 
    showframe = T, 
    showland = T, 
    landcolor = toRGB("white") 
) 

plot_ly(df, z = member, type = 'choropleth', locations = Country, 
       locationmode = 'country names', text = Country, hoverinfo = "text") %>% 
     layout(geo = g, title = "Energy markets in Africa") 

Теперь я хотел бы изменить две вещей:

  1. Постоянная отображение названий стран, т.е. не только при наведении курсора на интерактивную диаграмму в RStudio. Я попытался применить ответ this post к моему, без успеха.
  2. Некондиционный масштаб. В идеале, я бы хотел иметь шкалу не всех BUT 5 для каждого кластера, каждый из которых имеет следующие три характеристики: (1) Цвет коробки должен соответствовать соответствующему цвету в choropleth (2) Каждая коробка должна содержать число стран, возложенных на него, то есть к соответствующему кластеру (3) Каждый блок должен содержать соответствующий кластер средство для двух переменных (X1, X2), которые содержатся в cluster.means

Я прикрепленные такие образцовый сюжет того, что я имею в виду (он не должен выглядеть точно так же - просто для передачи идеи).

An exemplary choroplot containing only 2, instead of 5 boxes

Любая помощь, советы, Типп высоко ценится!

(Scaled) данные выглядят следующим образом:

df <- structure(list(Country = structure(1:50, .Label = c("Angola", 
"Benin", "Botswana", "Burkina Faso", "Burundi", "Cabo Verde", 
"Cameroon", "Central African Republic", "Chad", "Comoros", "Congo", 
"Cote d'Ivoire", "Democratic Republic of Congo", "Djibouti", 
"Equatorial Guinea", "Eritrea", "Ethiopia", "Gabon", "Gambia", 
"Ghana", "Guinea", "Guinea-Bissau", "Kenya", "Lesotho", "Liberia", 
"Madagascar", "Malawi", "Mali", "Mauritania", "Mauritius", "Mozambique", 
"Namibia", "Niger", "Nigeria", "Reunion", "Rwanda", "Sao Tome and Principe", 
"Senegal", "Seychelles", "Sierra Leone", "Somalia", "South Africa", 
"South Sudan", "Sudan", "Swaziland", "Tanzania", "Togo", "Uganda", 
"Zambia", "Zimbabwe"), class = "factor"), X1 = c(-0.18, -1.03, 
0.6, 1.55, 0.22, 0.26, 0.76, 2.15, -1.43, 0.99, 1.79, -0.39, 
1.73, 1.57, 1.11, -0.09, -1.49, -0.46, -0.48, -1.22, -0.78, -1.46, 
-1.22, 0.35, 0.45, 1.29, -1.37, -0.61, 0.92, -1.3, 0.42, -1.18, 
1.4, -0.83, 0.06, -0.76, -0.19, -0.37, -0.63, 0.64, 0.93, 0.33, 
-0.76, -0.21, -0.59, -0.41, -0.74, 0.39, -1.1, 1.35), X2 = c(-0.22, 
-0.42, 0.72, -0.59, -1.27, 0.64, -1.35, -1.4, -0.35, -1.43, 1.07, 
-0.01, -0.51, 0.11, 1.14, -0.89, 0.77, 1.45, -1.67, -0.83, 0.71, 
0.92, 1.63, 1.68, 0.23, -0.18, 0.07, 0.8, -0.02, 0.82, -0.72, 
-0.41, -0.26, 0.02, -1.68, 1.67, 0.18, 0.98, 1.45, 0.31, -1.23, 
-1.38, -0.63, 1.41, -0.12, 0, -1.3, -1.64, 0.21, 1.52)), .Names = c("Country", 
"X1", "X2"), row.names = c(NA, -50L), class = "data.frame") 

ответ

5

«В идеале, я хотел бы не иметь масштаба вообще»: Это достигается путем добавления Аргумента showscale=F в plot_ly().

«Постоянное отображение названий стран»: Это делается путем добавления scattergeo участка слоя с, как описано в this post, с незначительной разницей. Поскольку ваш dataframe содержит столбец названий стран, но ни один из кодов стран, вам нужно добавить этот аргумент locationmode = 'country names'

p <- plot_ly(df, z = member, type = 'choropleth', 
      locations = Country, locationmode = 'country names', 
      text = Country, hoverinfo = "text", 
      showscale=F, inherit =F) %>% 
    layout(geo = g, title = "Energy markets in Africa") %>% 
    add_trace(type="scattergeo", 
      locationmode = 'country names', locations = Country, 
      text = Country, mode="text", 
      textfont = list(color=rgb(1,0.5,0.3), size =12)) 

Вам нужно будет попробовать различные цветовые схемы, чтобы найти тот, который эффективно показывает кластеры, в то время как делая контрастные изображения на ярлыках с названиями стран. Вероятно, мало что можно сделать по тому факту, что метки с названиями постоянных стран будут перекрываться друг с другом, когда карта будет уменьшена. С дополнительными усилиями вы могли бы указать длинную позицию для каждой из ярлыков, а не полагаться на свои позиции по умолчанию, и это может помочь улучшить внешний вид карты, разделив метки лучше. Я предполагаю, однако, что с тех пор, как вы попросили постоянные лейблы, вы намереваетесь использовать карту только с подходящим увеличением, где они выглядят нормально.

Чтобы добавить текстовые поля, которые вы описываете, вы можете использовать макеты аннотаций (одна аннотация для каждого кластера). Я показываю здесь, как добавить один с фиолетовой рамкой, и второй бирюзовый. Вам нужно будет настроить это на цветовую схему, которую вы используете.

box1 <- list(
    x = 0.3, 
    y = 0.5, 
    yanchor = "top", 
    borderpad = 2, 
    bordercolor = rgb(0.5,0.1,0.5),  # set this same as color of cluster 1 
    borderwidth = 5, 
    text = paste("1. Cluster, ", 
       sum(df$member==1),  # number of countries in cluster 
       " Countries<br>X1 = ", # use <br> for line breaks 
       format(round(cluster.means[1,]$X1, 2), nsmall = 2), 
       "<br>X2 = ", 
       format(round(cluster.means[1,]$X2, 2), nsmall = 2)), 
    align = "left", 
    showarrow = F) 

box2 <- list(
    x = 0.3, 
    y = 0.4, 
    yanchor = "top", 
    borderpad = 2, 
    bordercolor = rgb(0.1,0.5,0.5), 
    borderwidth = 5, 
    text = paste("2. Cluster, ", 
       sum(df$member==2), 
       " Countries<br>X1 = ", 
       format(round(cluster.means[2,]$X1, 2), nsmall = 2), 
       "<br>X2 = ", 
       format(round(cluster.means[2,]$X2, 2), nsmall = 2)), 
    align = "left", 
    showarrow = F) 

p %>% layout(annotations = list(box1, box2)) 

enter image description here

+0

Wow! Это замечательно, спасибо :-) У меня есть один вопрос: я добавляю другие поля и делаю «y-value» каждого окна на 0,1 меньше, чем указано выше. В конце я присоединяю их все вместе, как этот 'box = list (box1, box2, box3, box4, box5)' и присваивает 'box'' аннотации'. Но, к сожалению, расстояние между ящиками не всегда одинаково ... почему? – Joni

+0

Анкер для аннотаций по умолчанию - «автоматический». К сожалению, это означает, что сюжетная линия выбирает привязать каждую ячейку к положению x, y по-разному, в зависимости от того, какая точка привязки ближе всего к заданной координате y. Средство простое. Добавьте строку 'yanchor =" top "' в каждый из списков аннотаций. Я отредактировал ответ с этим. – dww

+0

Также отредактировал неуместную круглую скобку в инструкции paste() (теперь исправлено) и увеличенное дополнение к текстовым полям для улучшения внешнего вида. – dww

 Смежные вопросы

  • Нет связанных вопросов^_^