大阪市塗り分け地図まとめ

TeachingDemos,mapplots,RColorBrewer パッケージ

(参考・使用したデータ等)
大阪市における特別区の設置についての投票
大阪各区の開票結果

(地図のデータ)
マップナビおおさかオープンデータ一覧
地図情報(マップナビおおさか掲載情報以外)区域画像(Shapefile)

(準備)
地図データをダウンロードー>解凍
ー>ファイル名「24区画像」を「osaka」(例えば、「24区画像.shp」は「osaka.shp」) にリネーム
ー>作業ディレクトリに保存

(参考・使用したデータ等)
区ごとの年齢構成

使用するOS、Rのバージョンによってデータを取り込む命令が異なる。
使うデータはあらかじめダウンロードしておくのが一番よい。

ここではOSはzorin。RのバージョンR3.1.2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
library(maptools)
library(RColorBrewer)
#osaka <- readShapePoly("osaka.shp")
library(rgdal)
osaka<-readOGR("osaka.shp", layer="osaka",encoding="Shift_JIS")
osakadata <- osaka@data
vote <- read.csv("http://oku.edu.mie-u.ac.jp/~okumura/stat/data/osaka2015.csv", header=TRUE,fileEncoding="UTF-8")
#vote <- read.csv("osaka2015.csv", header=TRUE)
head(vote)
osakadata<-merge(x=osakadata,y=vote,by.x="ATTR2",by.y="区名",sort=F)
library(downloader)
download("https://raw.githubusercontent.com/yutannihilation/osaka_age_composition/master/osaka_age_composition.csv","age.csv")
age<-read.csv("age.csv",fileEncoding="UTF-8")
#層別集計作業(80歳以上まとめた)
age$class<- cut(age$age,breaks=c(seq(0,80,10),101), right=F, ordered_result=TRUE)
age2 <- subset(age, class!="[0,10)" & class!="[10,20)", select=c(class,district,total))
unique(osakadata$ATTR2);unique(age2$district)

[1] 此花区 城東区 生野区 西区 西成区 鶴見区 都島区 大正区 中央区 住之江区 西淀川区 天王寺区 東住吉区 東成区 東淀川区
[16] 平野区 北区 淀川区 阿倍野区 福島区 浪速区 旭区 港区 住吉区
24 Levels: 阿倍野区 旭区 港区 此花区 住吉区 住之江区 城東区 生野区 西区 西成区 西淀川区 大正区 中央区 鶴見区 天王寺区 都島区 … 浪速区
[1] 北 都島 福島 此花 中央 西 港 大正 天王寺 浪速 西淀川 淀川 東淀川 東成 生野 旭 城東 鶴見 阿倍野
[20] 住之江 住吉 東住吉 平野 西成
Levels: 阿倍野 旭 港 此花 住吉 住之江 城東 生野 西 西成 西淀川 大正 中央 鶴見 天王寺 都島 東住吉 東成 東淀川 福島 平野 北 淀川 浪速

地図上に年齢構成割合の円グラフを書くためにはオブジェクトageの並び順をosakadata$ATTR2の並び順にに合わせる必要あり。

方法1:年齢構成割合も投票数のようにosakadataにマージする

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
temp<-xtabs(as.vector(total)~as.vector(district)+as.vector(class),age2)
age3<-data.frame(paste(rownames(temp),"区",sep=""),temp[,])
colnames(age3)<-c("district",colnames(temp))
osakadata<-merge(x=osakadata,y=age3,by.x="ATTR2",by.y="district",sort=F)
#library(RColorBrewer)
#library(mapplots)
#png("osaka06.png",width=1000,height=800)
plot(osaka)
#区名を書く座標(ポリゴンの重心を得る)
cents <- coordinates(osaka)
x <- cents[,1]
y <- cents[,2]
rr <- (max(cents[,2])-min(cents[,2]))/20
box()
j=1
for(i in unique(osakadata[,"ATTR2"])){
df= subset(osakadata,ATTR2==i)
add.pie(z=as.numeric(df[,c("[20,30)", "[30,40)", "[40,50)", "[50,60)", "[60,70)", "[70,80)", "[80,101)")]),
x=cents[j,1], y=cents[j,2],radius=rr,label.dist=NA,col=brewer.pal(7, "Set3"))
j=j+1
}
legend("topright",legend=c("二十代","三十代","四十代","五十代","六十代","七十代","八十以上"),
cex=0.7,fill=brewer.pal(7, "Set3"),text.col='black',ncol=2)
title("年齢構成")
#dev.off()

方法2:age2の行順をosakadataの行順に合わせる。

1
2
3
4
5
6
7
8
9
10
11
#districtに区をつけてage$district2に保存(osakadata$ATTR2には区がついている)
age2$district2<-paste(age2$district,"区",sep="")
#osakadata$ATTR2の順序をvalsに入れる
vals <- as.vector(unique(osakadata$ATTR2))
#levels=vals:osakadata$ATTR2の順序
age2$district2<-factor(age2$district2,levels=vals)
#levelsの順番のsortlistを作り、
sortlist <- order(age2$district2)
#並べ替える。
D<-age2[sortlist,]
unique(D$district2)

[1] 此花区 城東区 生野区 西区 西成区 鶴見区 都島区 大正区 中央区 住之江区 西淀川区 天王寺区
[13] 東住吉区 東成区 東淀川区 平野区 北区 淀川区 阿倍野区 福島区 浪速区 旭区 港区 住吉区
24 Levels: 此花区 城東区 生野区 西区 西成区 鶴見区 都島区 大正区 中央区 住之江区 西淀川区 天王寺区 東住吉区 … 住吉区

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#library(RColorBrewer)
options(scipen=10)
#縦書き関数を定義
tate <- function(x){
x<-as.vector(x)
for(i in 1:length(x)){
xx<-chartr("ー", "|",x[i])
xx<-unlist(strsplit(xx,""))
x[i]<-paste(xx,collapse= "\n")
}
return(x)
}
# 層別グラフ(画面24分割)
#png("osaka07.png",width=1000,height=800)
par(mfrow=c(4,6))
for(i in unique(D[,"district"])){
df= subset(D,district==i)
b<-barplot(aggregate(total~class,df,sum)$total,names.arg=NA,
horiz=F,las=1,cex.names=0.8,col=brewer.pal(8, "Set3"),ylim=c(0,max(xtabs(total~class+district,D))))
text(b[1:7,],-1000,labels=tate(c("二十代","三十代","四十代","五十代","六十代","七十代","八十以上")),
srt=0,col=c(rep("black",30),"red",rep("black",16)),xpd=TRUE,pos=1)
mtext(side=3, line=1, text=paste("年齢構成(20~):",i,"区",sep=""))
}
par(mfrow=c(1,1))
#dev.off()

osakadataの区順と同じになるので比較が容易

1
2
3
4
5
6
7
8
9
10
#png("osaka08.png",width=1000,height=800)
par(mfrow=c(4,6))
DD1 <- osakadata$賛成/(osakadata$賛成+osakadata$反対)
DD2 <- 1-DD1
for (i in 1:nrow(osakadata)) {
pie(c(yes=DD1[i],no=DD2[i]),clockwise = T)
mtext(side=3, line=1,text=paste(osakadata$ATTR2[i]))
}
par(mfrow=c(1,1))
#dev.off()

塗り分け地図+円グラフ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#library(mapplots)
#賛成の割合、反対の割合に応じて色の濃さを変える
#
DD <- osakadata$賛成/(osakadata$投票者男+osakadata$投票者女)
cutnum<-20
classes <- cut(DD,seq(0.4,0.6,length=cutnum+1),include.lowest=T)
#区名を書く座標(ポリゴンの重心を得る)
cents <- coordinates(osaka)
x <- cents[,1]
y <- cents[,2]
rr <- (max(cents[,2])-min(cents[,2]))/20
#plot
par(cex=0.9)
colblue <- colorRampPalette(c("blue","#C6C6FF"))
colred <- colorRampPalette(c("#FFC6C6","red"))
cols<-rev(c(colblue(10),colred(10)))
#png("osaka09.png",width=1000,height=800)
plot(osaka,col=cols[classes],xlab="",ylab="",axes=F)
box()
j=1
for(i in unique(D[,"district"])){
df= subset(D,district==i)
add.pie(z=aggregate(total~class,df,sum)$total,x=cents[j,1], y=cents[j,2],radius=rr,label.dist=NA,col=brewer.pal(7, "Set3"))
j=j+1
}
#区名を書く
#text(x,y,as.character(osakadata$ATTR2),cex=0.7,pos=1,offset=0,col="black")
#凡例とタイトル
cols2 <- c(colblue(10),colred(10))
legend("topleft",legend=names(rev(table(classes))),cex=0.7,fill=cols2,text.col='black',ncol=2)
legend("topright",legend=c("二十代","三十代","四十代","五十代","六十代","七十代","八十以上"),
cex=0.7,fill=brewer.pal(7, "Set3"),text.col='black',ncol=2)
title("色分け:都構想に賛成の割合・年齢構成:円グラフ")
#legend.pie("bottomleft",labels=c("二十代","三十代","四十代","五十代","六十代","七十代","八十以上"), radius=1.5*rr, bty="n", col=brewer.pal(7, "Set3"),
#cex=0.8, label.dist=1.3)
#dev.off()

地図上に棒グラフ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
library(TeachingDemos)
#png("osaka10.png",width=1000,height=800)
plot(osaka)
j=1
for(i in unique(D[,"district"])){
df= subset(D,district==i)
subplot(barplot(height=aggregate(total~class,df,sum)$total,axes=F,col=brewer.pal(7, "Set3"),ylim=c(0,max(xtabs(total~class+district,D)))),
x=as.numeric(cents[j,1]), y=as.numeric(cents[j,2]), size=c(0.8,1))
j=j+1
}
#凡例とタイトル
legend("topright",legend=c("二十代","三十代","四十代","五十代","六十代","七十代","八十以上"),
cex=0.7,fill=brewer.pal(7, "Set3"),text.col='black',ncol=2)
title("年齢構成:棒グラフ")
box()
#dev.off()