2015-03-28 12 views
0

Я пытаюсь сделать карту Choropleth в Германии, используя ggplot2. Мои данные представляют собой CSV-файл с 2 строками (RS = содержит номера от 1 до 16 для каждого немецкого состояния & Тариф = 16 случайных положительных и отрицательных чисел).Неправильное отображение данных на карте Choropleth с ggplot2 в R

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. Я хочу сделать, чтобы построить это положительное и отрицательное числа на карте германии для каждого состояния, с двумя цветами (положительный = зеленый и отрицательный = красный). Ниже мой код

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") 
[email protected]<- [email protected][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 #### 
[email protected]<-merge([email protected], eeg, by="RS", all=TRUE) 

# #### Shapes Plot #### 
[email protected]$id <- (as.numeric(rownames([email protected]))-1) 
bundesl.df<-fortify(bundesland) 
bundesl.df <- join(bundesl.df, [email protected], 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 

До сих пор мне удалось построить карту, но с отображением неправильных данных. Я имею в виду состояние с положительным Тарифом, например, Шлезвиг-Гольштейн должен быть зеленым, но красным, а Бавария - красным, но зеленым.

Мое предположение, что есть проблема с fortify function. Мои данные - всего 16 строк, но после фортификации он печатает 1000+ строк. Зачем?? и это то, что вызывает несоответствие данных. Я сделал все поиски в Интернете, которые, возможно, смогу для решения. Я был бы признателен, если кто-нибудь может дать мне ответ о том, почему эта проблема происходит.

Благодарим за помощь!

ответ

2

fortify ставит полигоны из шейп-файла во что-то ggplot может отпечатать, следовательно, 1000+ строк. Пока вы можете прикрепить значения к обогащенным многоугольникам, это необязательно.

Итак, вам не обязательно проходить через все эти неприятности для choropleth. Взгляните на следующее. Я добавил в некоторых дополнительных бит, чтобы показать, значения которых получают карту, к которой 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") 
[email protected]<- [email protected][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([email protected][,c(2,4)], egg[,2])) 

grid.arrange(gg, gt, ncol=2) 

enter image description here

08 & 16 имеют Юникода в них, следовательно, отсутствие дисплея без преобразования. Я также понимаю, что построение номера RS на центроиде проблематично для Берлина & Бранденбург, но это должно было дать общую идею, а не быть совершенным.

Я бы предложил использовать cut для определения 5 или 6 стандартизованных разрывов для значений с использованием непрерывной шкалы.

+0

Спасибо за помощь @hrbmstr, ваш ответ разъясняет, что происходит не так. Но я все еще не могу решить настоящую проблему. Боже, помоги мне :(PS Извините за ответ так поздно, жизнь мешала. Спасибо еще раз. – RNovice

+0

@hrbemstr Можете ли вы рассказать мне, почему вы использовали spTransform? – RNovice

+0

Как говорится в комментариях, он предпроектирует координаты на международном уровне признанный правильный прогноз для использования с Германией. Вы можете избавиться от этого и либо просто использовать 'coord_map()' (вместо 'coord_equal()'), который будет иметь 'ggplot' дело с использованием проекции для вас (и это будет быть Mercator по умолчанию), или вы можете использовать альтернативный предложенный в комментариях 'coord_map (« mollweide »)'. Без 'coord_map' или' spTransform' + 'coord_equal' у вас будет карта, которая перескакивает до размеров графика – hrbrmstr

0

Это немного устарело, но, поскольку это лучший вопрос о картах немецких choropleth, я хотел добавить несколько вещей, которые я узнал, следуя отличному ответу @ hrbrmstr.

Как вы можете видеть на карте, которую он построил, Берлин просто приобретает цвет Бранденбурга. Чтобы исправить это, нужно отредактировать порядок в файле bundesl_map, чтобы убедиться, что Берлин (10) приходит после Бранденбурга (11). Таким образом, полная обработка карты должна выглядеть следующим образом:

library(rgdal) 
library(rgeos) 
library(maptools) 

bundesl <- readOGR("vg2500_geo84/vg2500_bld.shp", "vg2500_bld") 
[email protected]<- [email protected][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() 
    ) 
} 

Это даст карту так:

map