我目前正在制作一张地图,1)用各自的名称标记每个多边形,2)根据每个多边形的计数给每个多边形一个特定的颜色。
阅读几个Stack溢出帖我找到一个真正帮助我很多(Labeling center of map polygons in R ggplot),但我遇到两个主要问题:1)我似乎无法指定我想要的地图的特定颜色采取,2)我似乎无法像我希望的那样得到传奇。
我将在前面提到的帖子(Labeling center of map polygons in R ggplot)中使用用户Silverfish提供的代码:
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(worldMap@data) 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 <- worldMap@data$ISO3
# "coordinates" extracts centroids of the polygons, in the order listed at worldMap@data
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 <- worldMap@data$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 :(得分:0)
最终,您需要使用离散的Categ变量提供fill
美学,而不是连续的人口变量。然后使用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()
(我知道您有理由指定您的人口类别。我只是更改了它们,以便我可以更轻松地查看我的工作是否有效。)
该代码应返回以下图:
然后,您可以通过添加+ theme(legend.position = ...)
来更改图例的位置,其中可接受的值为&#34; top&#34;,&#34; bottom&#34;,&#34; left&#34 ;,&#34;对&#34;,&#34;无&#34;或者零对一坐标系(例如,c(0.5,0.5)会将你的图例放在你的情节中间)。
所以,将+ theme(legend.position = c(0.83, 0.857), legend.background = element_rect(fill="transparent",colour=NA))
添加到你的ggplot对象会产生: