2017-02-10 2 views
1

В настоящее время я пытаюсь создать карту, которая 1) наклеивает каждый многоугольник на соответствующее имя и 2) дает каждому полигону определенный цвет, основанный на количестве из подсчетов, которые он имеет.Создание определенной легенды в R ggplot: вручную назначать цвета и значения полигонов следует принимать

Чтение нескольких сообщений о переполнении стека. Я нашел тот, который действительно очень помог мне (Labeling center of map polygons in R ggplot), но я столкнулся с двумя основными проблемами: 1) Я не могу указать конкретные цвета, которые я хочу получить, и 2) я не могу получить легенду так, как хочу.

Я собираюсь использовать код, указанный пользователем серебрянки в должности (Labeling center of map polygons in R ggplot) я уже упоминал ранее:

library(rgdal) # used to read world map data 
library(rgeos) # to fortify without needing gpclib 
library(maptools) 
library(ggplot2) 
library(scales) # for formatting ggplot scales with commas 

#Data from http://thematicmapping.org/downloads/world_borders.php. 
#Direct link: http://thematicmapping.org/downloads/TM_WORLD_BORDERS_SIMPL-0.3.zip 
#Unpack and put the files in a dir 'data' 

worldMap <- readOGR(dsn="data", layer="TM_WORLD_BORDERS_SIMPL-0.3") 
# Change "data" to your path in the above! 
worldMap.fort <- fortify(worldMap, region = "ISO3") 
# Fortifying a map makes the data frame ggplot uses to draw the map outlines. 
# "region" or "id" identifies those polygons, and links them to your data. 
# Look at head([email protected]) to see other choices for id. 
# Your data frame needs a column with matching ids to set as the map_id aesthetic in ggplot. 
idList <- [email protected]$ISO3 
# "coordinates" extracts centroids of the polygons, in the order listed at [email protected] 
centroids.df <- as.data.frame(coordinates(worldMap)) 
names(centroids.df) <- c("Longitude", "Latitude") #more sensible column names 
# This shapefile contained population data, let's plot it. 
popList <- [email protected]$POP2005 

pop.df <- data.frame(id = idList, population = popList, centroids.df) 

ggplot(pop.df, aes(map_id = id)) + #"id" is col in your df, not in the map object 
    geom_map(aes(fill = population), colour= "grey", map = worldMap.fort) + 
    expand_limits(x = worldMap.fort$long, y = worldMap.fort$lat) + 
    scale_fill_gradient(high = "red", low = "white", guide = "colorbar", labels = comma) + 
    geom_text(aes(label = id, x = Longitude, y = Latitude)) + #add labels at centroids 
    coord_equal(xlim = c(-90,-30), ylim = c(-60, 20)) + #let's view South America 
    labs(x = "Longitude", y = "Latitude", title = "World Population") + 
    theme_bw() 

This is what the code currently outputs

Этот пример позволил мне узнать, как разместить ярлыки на полигонах в карту, но мне нужно было сделать несколько изменений, прежде чем я получу то, где мне нужно: 1) Мне нужен масштаб, чтобы не быть градиентом, но в виде легенды, дающей цвет для определенного диапазона значений. Цвет и диапазон, которые я хочу, следующие (цвета указаны в форме HEX): - Диапазон: 0 Цвет: «Белый» - Диапазон: 1-99 Цвет: «# d3c874» - Диапазон: 100-249 Цвет: "# d69b26" - Диапазон: 250-499 Цвет: "# 89280d" - Диапазон: 500+ Цвет: "# 411614"

2) Мне нужна легенда, чтобы появиться на дне и идут слева направо

3) Мне нужно многоугольников, чтобы взять их правильные цвета на основе их подсчета

в «» pop.df кадра данных я создал еще один столбец (CATEG), присваивая значения «1», «2 «3», «4» или «5» в зависимости от ранее упомянутых диапазонов: - Диапазон: 0 Значение: «1» - Диапазон: 1-99 Значение: «2» - Диапазон: 100- 249 Значение: «3» - Диапазон: 250-499 Значение: «4» - Диапазон: 500+ Значение: «5» (ПРИМЕЧАНИЕ: видя, что подсчеты, используемые в этом примере, являются очень большими числами, я знаю, что каждый одиночный полигон, скорее всего, будет выше 500+, это только диапазоны, которые я использую в своих целях).

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

Я использовал этот код, чтобы это произошло:

Pop.df$Categ <- ifelse(Pop.df$population < 1, "1", 
          ifelse(Pop.df$population >= 1 & Pop.df$population < 100, "2", 
            ifelse(Pop.df$population >= 100 & Pop.df$population < 250, "3", 
              ifelse(Pop.df$population >= 250 & Pop.df$population < 500, "4", "5")))) 

Видя, что цвета мне нужно не являются частью определенной палитры, и что мне нужны эти конкретные цвета в карте, я начал использовать 'scale_colour_manual' вместо подхода scale_fill_gradient, чтобы настроить легенду, как мне нужно, но она, похоже, не работает. Конкретными препятствиями, с которыми я сталкиваюсь, являются: a) Я не могу заставить легенду быть от градиента до дискретных значений. b) Цвета, которые некоторые на карте не похожи на нужные мне цвета. Я не знаю, из-за кода HEX или чего-то еще.

Я подошел к этому несколькими способами.Самый последний код, который я использовал это один:

ggplot(pop.df, aes(map_id = id)) + 
geom_map(aes(fill = population), colour= "black", map 
= worldMap.fort) + 
expand_limits(x = worldMap.fort$long, y = worldMap.fort$lat) + 
scale_colour_manual(values = c("white", "#d3c874", "#d69b26", "#89280d", "#411614"), 
         limits = c("1", "2", "3", "4", "5"), breaks = c("1", "2", "3", "4", "5")) + #This is my attempts to getting the legend to work 
geom_text(aes(label = id, x = Longitude, y = Latitude)) + #add labels at centroids 
coord_equal(xlim = c(-90,-30), ylim = c(-60, 20)) + #let's view South America 
labs(x = "Longitude", y = "Latitude", title = "World Population") + 
theme_bw() 

Что касается позиции легенды, я даже не начал решать эту проблему, видя я первую попытку сделать это отображается правильно.

Любое понимание было бы замечательными парнями! Спасибо

ответ

0

В конечном счете, вам нужно было поставить эстетику с вашей дискретной переменной Categ вместо переменной непрерывной совокупности. Затем используйте scale_fill_manual(), потому что вы хотите заполнить страны цветом (не цвет границ), и вы уже окрашиваете границы черными в geom_map(). См. Код с комментариями ниже.

# same code as in your question, 
# but (1) changed population categories (added four zeroes) so that 
# more countries fall in different bins, 
# (just so I could see if my subsequent solutions worked) 
# and (2) used the hex colors you supplied as category values, rather than 1-5 
pop.df$Categ <- ifelse(pop.df$population < 1, "#ffffff", 
        ifelse(pop.df$population >= 1 & pop.df$population < 1000000, "#d3c874", 
          ifelse(pop.df$population >= 1000000 & pop.df$population < 2500000, "#d69b26", 
           ifelse(pop.df$population >= 2500000 & pop.df$population < 5000000, "#89280d", "#411614")))) 
# convert Categ to factor 
pop.df$Categ <- factor(pop.df$Categ, levels = c("#ffffff", "#d3c874", "#d69b26", "#89280d", "#411614")) 
# plot 
ggplot(pop.df, aes(map_id = id)) + 
    geom_map(aes(fill=Categ), colour= "black", map = worldMap.fort) + 
    expand_limits(x = worldMap.fort$long, y = worldMap.fort$lat) + 
    scale_fill_manual(values = c("#ffffff", "#d3c874", "#d69b26", "#89280d", "#411614"), 
       breaks = c("#ffffff", "#d3c874", "#d69b26", "#89280d", "#411614"), 
       labels = c("zero", "< 1 million", "1 to 2.5 million", "2.5 to 5 million", "> 5 million")) 
    geom_text(aes(label = id, x = Longitude, y = Latitude)) + #add labels at centroids 
    coord_equal(xlim = c(-90,-30), ylim = c(-60, 20)) + #let's view South America 
    labs(x = "Longitude", y = "Latitude", title = "World Population") + 
    theme_bw() 

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

Этот код должен вернуться следующий сюжет:

enter image description here

Вы можете изменить положение легенды путем добавления + theme(legend.position = ...), где допустимые значения являются «сверху», «снизу», «влево», «вправо», «ни один ", или ze система координат «один на один» (например, c (0,5, 0,5) поставит вашу легенду в середине вашего сюжета).

так, добавляя + theme(legend.position = c(0.83, 0.857), legend.background = element_rect(fill="transparent",colour=NA)) к объекту ggplot даст:

enter image description here

+0

код работает отлично, спасибо так много! Я хотел посмотреть, могу ли я задать некоторые последующие вопросы, чтобы понять код и не использовать то, что я не понимаю: 1) В 'scale_fill_manual': правильно ли сказать, что' breaks' и 'values' работают вместе, чтобы определить, какой цвет предоставляется каждому полигону? 2) если да, то какова опция 'limits', используемая в контексте' scale_fill_manual'? –

+0

'breaks' определяет порядок значений вашей категории, как указано в легенде, но' limits' указывает, какие значения категорий получают какие цвета (хотя у меня лично никогда не было случая, когда порядок значений должен отличаться от порядка отображается в легенде). Итак, если вы указали 'limits = c (" 3 "," 1 "," 2 "," 4 "," 5 ")', тогда значение категории "3" получит первый цвет, указанный в 'values'. См. Последние три примера по адресу http://docs.ggplot2.org/0.9.3/scale_manual.html. –

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