我正在尝试使用ggplot2制作德国的Choropleth地图。我的数据是一个包含2行的.csv文件( RS =每个德国州都包含数字1到16,关税= 16个随机正数和负数)。
RS Tariff
1 01 -5.25
2 02 7.16
3 03 6.65
4 04 3.10
5 05 3.69
6 06 2.49
7 07 1.89
8 08 3.93
9 09 -5.84
10 10 -2.61
11 11 -0.21
12 12 2.35
13 13 -5.94
14 14 -7.54
15 15 -3.27
16 16 -8.75
我还有一个形状文件Germany shape file。我想做的是将这个正数和负数映射到每个州的德国地图上,有2种颜色(正面=绿色和负面=红色)。以下是我的代码
library(XLConnect)
library(sp)
library(rgdal)
library(ggplot2)
library(plyr)
library(RColorBrewer)
library(DataCombine)
library(rgeos)
library(maptools)
#### EEG Data Read ####
eeg<-read.csv(file = "data/testdata1.csv", skip = 0, sep = ",", dec=".", header=TRUE)
colnames(eeg)<-c("RS", "Tariff")
eeg$RS<- c("01","02","03","04","05","06","07","08","09","10","11","12","13","14","15","16")
eeg$RS<-as.factor(eeg$RS)
eeg$Tariff<- as.numeric(eeg$Tariff)
#### Shape Data Read ####
bundesl<-readOGR("data/new_shape/vg2500_bld.shp", "vg2500_bld")
bundesl@data<- bundesl@data[order(bundesl$RS, na.last=NA),]
### Rearrange shape data for better merging ###
levels(bundesl$GEN)<- c("Schleswig-Holstein", "Mecklenburg-Vorpommern", "Hamburg", "Bremen", "Niedersachsen", "Sachsen-Anhalt", "Brandenburg",
"Berlin", "Nordrhein-Westfalen", "Hessen","Thüringen","Sachsen", "Rheinland-Pfalz", "Saarland", "Baden- Württemberg", "Bayern")
bundesl$GEN<- c("Schleswig-Holstein", "Mecklenburg-Vorpommern", "Hamburg", "Bremen", "Niedersachsen", "Sachsen-Anhalt", "Brandenburg",
"Berlin", "Nordrhein-Westfalen", "Hessen","Thüringen","Sachsen", "Rheinland-Pfalz", "Saarland", "Baden-Württemberg", "Bayern")
bundesl$SHAPE_LENG<- c("1217255.7","1780980.8","175253.8","154971.6","2016496.4","949096.8",
"1295460.4","180751.2","1352108","1105092.8","961942.7","979294.3","910650.4",
"282910.8","1298891.7","2046039.3")
bundesl$SHAPE_AREA<- c("15857425536","23044684847","760539820","405480872","47716406483","20494982327","29653902483","886480139","34047269991","21092318103","16178531941","18401642456","19834907486","2578541706","35801397076","70550070623")
# #### Shape Data und EEG Data join ####
bundesl@data<-merge(bundesl@data, eeg, by="RS", all=TRUE)
# #### Shapes Plot ####
bundesl@data$id <- (as.numeric(rownames(bundesl@data))-1)
bundesl.df<-fortify(bundesland)
bundesl.df <- join(bundesl.df, bundesl@data, by="id")
ggp <- ggplot(data=bundesl.df, aes(x=long, y=lat, group=group))
ggp <- ggp + geom_polygon(aes(fill=Tariff), col="black")
ggp <- ggp + coord_map()
ggp <- ggp + scale_fill_continuous(name=expression(Tariff), low = "red", high = "green", space = "Lab", na.value = "white", guide = "colourbar")
ggp <- ggp + theme_minimal()
ggp <- ggp + theme(axis.title=element_blank(), axis.ticks=element_blank(), axis.text=element_blank())
ggp
到目前为止,我设法绘制地图,但使用错误的数据映射。我的意思是像石勒苏益格 - 荷尔斯泰因这样的积极关税的国家应该是绿色但是红色,巴伐利亚应该是红色但是绿色。
我的猜测是 强化功能 存在问题。我的数据只有16行,但强化后会打印1000多行。为什么??这是导致数据不匹配的原因。我在互联网上做了所有的搜索,我可以为解决方案。如果有人能够回答为什么会出现这个问题,我将不胜感激。
提前感谢您的帮助!
答案 0 :(得分:2)
fortify
将shapefile中的多边形放入ggplot
可以绘制的内容中,因此可以绘制1,000多行。虽然可以将值附加到强化多边形,但这不是必需的。
所以,你真的不必为了理论而烦恼。看一下以下内容。我添加了一些额外的位来显示哪些值被映射到哪个RS
:
library(rgdal)
library(ggplot2)
library(gridExtra)
egg <- read.table(text="RS Tariff
01 -5.25
02 7.16
03 6.65
04 3.10
05 3.69
06 2.49
07 1.89
08 3.93
09 -5.84
10 -2.61
11 -0.21
12 2.35
13 -5.94
14 -7.54
15 -3.27
16 -8.75", header=TRUE, colClasses=c("character", "numeric"))
bundesl <- readOGR("vg2500_geo84/vg2500_bld.shp", "vg2500_bld")
bundesl@data<- bundesl@data[order(bundesl$RS, na.last=NA),]
# good projection for germany but if you intende to draw additional
# lines or points you'll have to project them before plotting so this
# may be more trouble than it's worth and you can just use
# coord_map("mollweide") or something else that works for you besides mercator
bundesl <- spTransform(bundesl, CRS("+proj=utm +zone=33 +ellps=WGS84 +datum=WGS84 +units=m +no_defs "))
bundesl_map <- fortify(bundesl, region="RS")
# only doing this bit to plot the RS # at the center of each polygon
# totally not necessary for the choropleth
egg <- cbind(egg, data.frame(gCentroid(bundesl, byid=TRUE)))
gg <- ggplot()
# this bit ensures you have the outlines
gg <- gg + geom_map(data=bundesl_map, map=bundesl_map,
aes(x=long, y=lat, map_id=id),
color="#7f7f7f", size=0.15)
# this bit here does your choropleth
gg <- gg + geom_map(data=egg, map=bundesl_map,
aes(fill=Tariff, map_id=RS),
color="#7f7f7f", size=0.15)
gg <- gg + geom_text(data=egg, aes(x=x, y=y, label=RS), size=3)
gg <- gg + coord_equal() # we already projected it
gg <- gg + scale_fill_continuous(name=expression(Tariff),
low="red", high="green", space="Lab",
na.value="white", guide="colourbar")
gg <- gg + labs(x=NULL, y=NULL)
# decent map theme
gg <- gg + theme_bw()
gg <- gg + theme(panel.grid=element_blank())
gg <- gg + theme(panel.border=element_blank())
gg <- gg + theme(axis.ticks=element_blank())
gg <- gg + theme(axis.text=element_blank())
gt <- tableGrob(cbind(bundesl@data[,c(2,4)], egg[,2]))
grid.arrange(gg, gt, ncol=2)
08
&amp; 16
中包含unicode,因此缺少显示而没有转换。我也意识到在质心上绘制RS
数字对于柏林而言是有问题的。勃兰登堡,但它是一个大致的想法,而不是完美的。
我强烈建议使用cut
为值定义5或6个标准化中断,并使用连续刻度。
答案 1 :(得分:0)
这有点旧,但由于这是关于德国等值线图的最佳问题,我想在追随@ hrbrmstr的好答案时添加一些我学到的东西。
正如你在地图上看到的那样,柏林正在彰显勃兰登堡的色彩。要解决此问题,必须编辑bundesl_map中的顺序,以确保柏林(10)位于勃兰登堡(11)之后。因此,地图的完整处理应如下所示:
library(rgdal)
library(rgeos)
library(maptools)
bundesl <- readOGR("vg2500_geo84/vg2500_bld.shp", "vg2500_bld")
bundesl@data<- bundesl@data[order(bundesl$RS, na.last=NA),]
bundesl_map <- fortify(bundesl, region="RS")
bundesl_map <- rbind(
bundesl_map[bundesl_map$id != 10, ],
bundesl_map[bundesl_map$id == 10, ]
)
saveRDS(bundesl_map, "bundesland")
在最后一步中,我们保存地图以供将来使用(bundesl_map <- readRDS("budesland")
)。 Here is a copy of the file I created with named ids.
绘图也可以更加简洁如下:
library(magrittr)
library(ggplot2)
library(viridis)
egg %>% ggplot(aes(fill=Tariff, map_id=RS)) +
geom_map(map=bundesl_map, color="white", size=0.2) +
geom_text(aes(x=x, y=y, label=egg$RS), size=2, color="white") +
coord_map("mercator") +
expand_limits(x=bundesl_map$long, y=bundesl_map$lat) +
scale_fill_viridis(begin=0.4, end=0.9, breaks=-8:7, guide=guide_legend(reverse=T)) +
theme_map(base_size=8)
其中theme_map
定义为:
theme_map <- function(...) {
theme_classic(...) %+replace%
theme(
axis.ticks = element_blank(),
axis.text = element_blank(),
axis.title = element_blank(),
line=element_blank()
)
}
这将生成如下地图: