[R] 都知事選挙を題材に学ぶ ggplot2 の作例
概要
前回 (ggplot2 で積み上げ折れ線グラフ(エリアプロット)を作成する方法) に引き続き, ggpplot の作例を紹介する. 前回は時系列データから積み上げ折れ線グラフを作成したのに対し, 今回は2014年2月9日に行われた東京都知事選挙の結果という横断面データを用いてグラフを作成する. 具体的には, 以下のような作例を紹介する.
- 棒グラフ (バープロット) を用いて候補者別・世代別得票数を可視化する
- バープロットのデザインのバリエーションをいくつか紹介
- 縦横を転置する方法
- 円グラフに変換する関数
データフレームの作成
去る2014年2月9日に行われた東京都知事選のデータから棒グラフを作成する. ここでは, 【更新】東京都知事選挙(2014年2月9日実施)投票動向分析 で算出されている主要候補者別・世代別投票数の値を借りて作成する.
# source: http://www.jgnn.net/ls/2014/02/201429.html vote <- data.frame(matrix(c(73954,230315,325399,291591,473307,718413,2112979,37339,132650,158198,145424,222066,286918,982595,22946,124288,148190,152014,259093,249532,956063,64141,126449,167988,95295,95295,61697,610865), nrow=4, ncol=7, byrow=T)) colnames(vote) <-c("twenties","thirties","forties","fifties","sixties","seventies","sum") vote$candidates <- c("舛添氏", "宇都宮氏", "細川氏", "田母神氏")
この時点で, vote オブジェクトの中身は
twenties thirties forties fifties sixties seventies sum candidates 1 73954 230315 325399 291591 473307 718413 2112979 舛添氏 2 37339 132650 158198 145424 222066 286918 982595 宇都宮氏 3 22946 124288 148190 152014 259093 249532 956063 細川氏 4 64141 126449 167988 95295 95295 61697 610865 田母神氏
となっているはずである. この数値をもとに, 出処のサイトにあるような棒グラフを作成してみる. この場合, グラフの x 軸は各候補者のラベルに, y 軸は (世代別に色分けされた) 得票数の合計になる. ここでも前回同様, reshape2 パッケージの melt 関数を利用することになる.
library(ggplot2) library(reshape2) vote.melt <- melt(vote, id.vars="candidates", measure.vars=colnames(vote)[1:6])
今回も, 積み上げ棒グラフを作成するだけなら簡単に可能である.
(g.stack <- ggplot(vote.melt) + geom_bar(mapping=aes(x=candidates, y=value, group=variable, fill=variable), stat="identity") )
前回の geom_line() 等では, 積み上げグラフにするには position="stack"
とすれば良かった. バープロットでも有効だが, 上の場合は省略できる. stat
引数は, デフォルトでは stat="bin"
となっており, これはヒストグラムの用に x に対応する行の数をカウントしてプロットする. これは集計されてないデータをプロットする際には便利だが, 今回は既に集計されたものを用いるため, 不適当であり, stat="identity"
を指定する((非集計データの場合は "stack"
を使う)). さらに, 全ての棒の高さを1に揃え, 候補者ごとに投票した世代の比率を表したい場合は, position="fill"
とする.
ggplot(vote.melt) + geom_bar(mapping=aes(x=candidates, y=value, group=variable, fill=variable), stat="identity", position="fill")
ただし, 既に参照元で示されているように, 分母 (=各候補者の総得票数, 各世代の有権者の総数) が大きくことなるため, このグラフは見る人に誤解を与える可能性が高い. 比率で表したグラフでは田母神氏に投票した40代が非常に多いように見えるが, 絶対数ではさほど多くない.
一方, 積み上げるのでなく, 横に並べたい (side-by-side chart) 場合, position="dodge"
とする.
(g.dodge <- ggplot(vote.melt) + geom_bar(mapping=aes(x=candidates, y=value, group=variable, fill=variable), stat="identity", position="dodge") )
絶対数と比率を同時に比較したい場合は, この図が一番適しているのかもしれない.
デザインの洗練
さしあたって, 前回の記述を踏まえ,
- 縦軸の目盛りを自然数表記に
- ラベルを全て日本語に
- 色を変更
といった変更をまとめて行う. これらは前回と同様の方法なので解説は省略.
label.gen <- c("20代", "30代", "40代", "50代", "60代", "70代以上") (g.dodge2 <- g.dodge + scale_y_continuous(labels=function(x) x/10000) + labs(x="候補者", y="投票者数\n (万人)", title="2014年度東京都知事選挙\n主要候補者・世代別推定投票者数") + theme(axis.title.y = element_text(angle = 90*0, vjust = 1) ) + scale_fill_brewer(palette="Spectral", name="", labels=label.gen) )
さらに, 次のような変更を加える.
- それぞれの棒にその候補者に占める比率を表示
- 凡例をグラフ下部に移動
- 候補者の並びを得票数順に.
vote.ratio <- function(x) paste(format(x/rep(vote$sum,6)*100, digits=2), "%", sep="") # 比率を計算し, 書式を整える関数を定義 ( g.dodge2 <- g.dodge2 + geom_text(aes(x=candidates, y=value, ymax=value, label=vote.ratio(value), group=variable ), position=position_dodge(width=1, height=1), size=3 ) + theme(legend.position="bottom") + scale_x_discrete(limits=c("田母神氏", "細川氏", "宇都宮氏", "舛添氏")) )
geom_text()
関数を使い, パーセントを表示した. position=“dodge” は geom_text には適用できず, %表示のテキストが重なってしまうため, position_dodge()
で代用した. 凡例の位置は, theme(legend.position="bottom")
で下部に移動. もちろん, “left”, “top” 等も可能. 候補者の並びについては, グラフを作成する前に候補者名を factor型として扱い, levels を設定することでも変えられるが, すでにグラフを作ってしまったため, scale_x_discrete()
関数で並び替えている.
縦横を転置する方法
coord_flip()
関数で棒グラフを横に伸ばすことができる.
g.dodge2 + coord_flip()
theme() で与えた軸ラベルの設定は, coord_flip() で変わらないようなので注意.
円グラフに変換する方法
棒グラフに対し + coord_polar(theta = "y")
とすると, 縦軸の大きさを角度で表した円グラフ (pie chart) として出力できる. 3D円グラフについては, ggplot2 は3D円グラフの作成に向いてないし, 作成に使わないでください.
(画像省略)
参考
- ill-identified (2014-02-22) 『ggplot2 で積み上げ折れ線グラフ(エリアプロット)を作成する方法』
- Triad sou. (2010-05-28) 『ggplot2 の自分用メモ集を作ろう』
- 不破雷蔵 (2014年2月10日 20:30) 『【更新】東京都知事選挙(2014年2月9日実施)投票動向分析』