数量の可視化に対しては棒グラフ、比率の可視化に対しては円グラフを用いた。
では、変化する値の可視化に対しては何を使うべきか?というのが今回の話。
実は、多くの人が意識していないのが、この種のデータの可視化方法。
「とりあえず、棒グラフで良いですかね〜?」
とする人は意外に多いように思える。いや、言ってる人を最近見た。
特別な理由があるわけでもなく、このような選択をしてはいないか?
Excelなど、多くのスプレッドシートソフトは、既定の状態で、棒グラフを表示する。
「いやいや、ちゃんと考えて可視化方法を選びなさい。」
という私のコメントに、
「えっ、グラフの選び方ってあるんですか?聞いたことありません。」
と言われた。ええ、有ります。物事の理屈を考えない人が多い。
重要なことは何を表現したいか、あるいは、どのように表現したいか?
確かに、ある時点における数量を表しているのだから、
棒グラフでも可視化方法として正しいのかもしれない。
しかしながら、ここで改めて考えてみたいことがある。
そもそも、「変化」とは何か?という問題である。
我々が変化する値を観察するときに留意するべきことは、
ある観測した瞬間と、次の瞬間の間にも変化が起きているか、ということである。
実は、折れ線グラフは、そのような連続的な変化を可視化する方法である。
棒グラフの話でも述べたが、基本的に棒グラフに順番は関係無い。
一方、折れ線グラフは、変化の順番が大きな意味が持ち、
その順番は、一般的には時間的な軸に従う順番である。
また、棒グラフや円グラフと同様に、
折れ線グラフを描く際には、色々と注意すべきこともある。
適当に描いて良いという訳ではない。
とりあえず、今回もRで実演しながら折れ線グラフについて考えてみよう。
今回は、法務省出入国管理統計統計表の「国籍別入国外国人(1950−2005)」の一部と、
財務省貿易統計年別輸出入総額のデータを編集し、合わせたもの。
国籍別入国外国人のデータは非常に大きいため、数カ国に絞っている。
国の選択は、私の個人的な興味であり、選択された国同士には何の脈絡も無い。
なお、年別輸出入総額のデータの単位は「千円」である。
いつものように。
# Windows と Linux の人は次のコマンド
X <- read.table("clipboard", sep=",")
# Mac の人は次のコマンド
X <- read.table(pipe("pbpaste") , sep=",")
データを読み込む。
China,Taiwan,Xianggang,Korea,Philippine,USA,Brazil,Export,Import
1964,562,12357,3844,18865,9105,129908,823,2402348862,2857515493
1965,576,15583,4326,17065,8945,150253,782,3042627204,2940846741
1966,503,17744,4229,25791,10824,173593,1154,3519500700,3428172558
1967,150,20789,4840,33558,12028,187373,1516,3758966022,4198711492
1968,11,25115,5567,39634,14190,199581,2196,4669798348,4675407477
1969,16,27501,6199,44654,13573,255663,2983,5756405162,5408472791
1970,139,46535,12506,71790,20477,315211,5866,6954367159,6797220528
1971,283,38774,8112,77545,12672,271029,3270,8392768263,6909956155
1972,994,47536,12645,85757,10860,281853,4772,8806072248,7228978838
1973,1991,50866,16893,110804,7874,287988,6734,10031426859,10404355041
1974,3161,60876,15463,124263,10411,245826,5765,16207879577,18076381928
1975,4441,77091,19318,129186,12574,237219,6522,16545313718,17170026976
1976,4018,82898,22721,141123,13073,274686,7804,19934618464,19229168610
1977,4039,88813,25620,156605,16138,303755,6153,21648070431,19131779700
1978,5951,99237,23273,184101,20375,275240,7696,20555840563,16727624005
1979,11622,165708,24094,199146,23223,256507,7488,22531538859,24245350997
1980,18336,235549,32239,212973,27902,277980,8381,29382471938,31995325202
1981,17550,305233,46614,250709,37483,310726,9438,33468984502,31464145741
1982,20532,311125,59898,284598,37878,352208,10336,34432500947,32656302574
1983,26606,331634,64727,283971,47887,400984,7992,34909268599,30014784056
1984,51010,351294,52750,292483,49511,437745,9250,40325293701,32321126640
1985,100972,356934,49153,296708,65529,487713,13889,41955659471,31084935207
1986,75275,300272,32271,299602,80508,482670,13434,35289713887,21550717070
1987,73030,360636,30569,360159,85267,479891,12126,33315191383,21736912673
1988,112389,392723,29127,515807,86567,457620,16789,33939183158,24006319859
1989,100144,501907,32007,806065,88296,538117,29241,37822534626,28978572581
1990,117814,610652,38622,978984,108292,564958,67303,41456939674,33855207638
1991,142150,686076,37483,1097601,125329,554147,96337,42359892974,31900153522
1992,187681,745835,39460,1094724,120660,574181,81495,43012281444,29527419360
1993,204302,700294,33391,1069450,109353,549090,70719,40202448725,26826357239
1994,210476,681183,31535,1140372,126739,548265,72236,40497552697,28104327343
1995,229965,614931,20378,1103566,105838,558474,90322,41530895121,31548753881
1996,257393,756785,27761,1224441,106394,606652,94068,44731311206,37993421106
1997,283467,857877,30806,1236597,124856,642933,104323,50937991859,40956182573
1998,299573,874985,53278,960556,129053,688006,77569,50645003938,36653647183
1999,327005,963701,42283,1160034,144305,720142,70794,47547556241,35268008063
2000,385296,944019,49423,1286583,169755,749343,101513,51654197760,40938422968
2001,444441,838001,74704,1342987,186262,715036,81800,48979244311,42415533002
2002,527796,909654,136482,1472096,197136,755196,71763,52108955735,42227505945
2003,537700,816692,163254,1621903,209525,678935,79692,54548350172,44362023352
2004,741659,1117950,226321,1774872,236291,785916,79960,61169979094,49216636346
2005,780924,1315594,250366,2008418,221309,853845,91268,65656544157,56949392181
このデータは、毎年の国籍入国者のデータと毎年の輸出入総額のデータである。
この二種類のデータは、本来は毎日のデータであって、それが年毎に集計されている。
また、年毎に区切っているのは、あくまで、等間隔に観測地点を置くためであって、
毎年のデータの切れ目は実質的に無意味である。したがって、
1月1日〜12月31日を一つの区切りにしようが、
4月1日〜3月31日を区切りにしようが、
9月1日〜8月31日を区切りにしようが、
実質的には変わらないハズ。
重要なことは、実際には常に変化しているが、
観測上の区切りが必要であるというイメージが出来ていること。
折れ線グラフというのは、このイメージを反映した可視化法なのである。
先頭が中国なので、まずは、中国のグラフから書いてみる。
plot(X$China, type="l")
流石に、これは大丈夫であろう。「l」は「line」の頭文字。折れ線グラフを描く。
何が足りていないかも大丈夫であろう。そうそう。タイトルが抜けている。
plot(X$China, type="l")
title("The number of Chinese entrants to Japan")
この状態でもグラフとしては不完全である。
まず、x軸とy軸の軸ラベル、目盛りラベルが不適切である。
# 折れ線グラフを書いてみる
plot(X$China, type="l", xlab="Year", ylab="The number of entry", xaxt="n")
# タイトルを加える
title("The number of Chinese entrants to Japan")
# x軸の目盛りラベルを付ける
axis(side=1, at=c(1:nrow(X)), labels=rownames(X), las=2)
ここでは、plot()関数で、xaxt="n"とし、この段階ではx軸を描かず、
最後のaxis()関数で、改めて描き直している。
ふむ。これで、一応の体裁は整った。しかし、y軸の目盛りラベルが見難い。
数が非常に大きいので、表現の仕方がコンピュータ上での表現になっている。
とりあえず、見やすいように、千人単位にしてみる。
# 折れ線グラフを描く
plot(X$China, type="l", xlab="Year", ylab="The number of entry", xaxt="n", yaxt="n")
# タイトルを加える
title("The number of Chinese entrants to Japan")
# x軸の目盛りラベルを配置し、
axis(side=1, at=c(1:nrow(X)), labels=rownames(X), las=2)
# y軸の目盛りラベルを単位を変えて配置する
axis(side=2, at=seq(0, 8e+05, by=1e+05), labels=seq(0, 8e+02, by=1e+02), las=2)
さて、これで、かなり見やすくなったのが、
y軸の目盛りラベルを修正したことによって、y軸の単位が変更されている。
軸ラベルを「1000人単位」であることが解るように修正しなければならない。
plot(X$China, type="l", xlab="Year", ylab="The number of entry (Thousands)", xaxt="n", yaxt="n")
title("The number of Chinese entrants to Japan")
axis(side=1, at=c(1:nrow(X)), labels=rownames(X), las=2)
axis(side=2, at=c(2e+05, 4e+05, 6e+05, 8e+05), labels=c(2e+02, 4e+02, 6e+02, 8e+02), las=2)
これで、何のデータであるかが理解できる。
折れ線グラフというのは、このように、変化を表すために利用する。
実は、線で結ばれているのは、ある観測点から次の観測点の間も、
「実は、変化し続けている」という状況を表している。
このように、本来は存在するのだけれど、
実際には観測していないので、仮説的に観測点同士をつなげることを、
「補間(interpolation)」と呼ぶ。
補間は、折れ線グラフのように1次元のデータだけではなく二次元での補間もある。
二次元での補間を行うことで、数学的に等高線が描けるのであるが、
今回、この話は置いておくことにする。
もちろん、直線では無く、曲線で補間することもあるが、
なぜ、曲線で表すべきであるか、についても考える必要がある。
単に、「格好良い」とか、そういう理由で安易に曲線にするべきではない。
今回の例では、数を数えただけの値なので、わざわざ、曲線で表す必要は無いだろう。
さて、話を戻そう。
先程の例では、中国人の入国者数だけであったが、
今度は、他の国の入国者数も同時に表現してみる。
# 前回のプロットを初期化
dev.off()
# For文を使って折れ線グラフを連続して描く
for(i in 1:7){
par(new=TRUE)
plot(x=X[,i], type="l", xlab="", ylab="", xaxt="n", yaxt="n", ylim=c(0,2010000))
}
# グラフタイトル、x軸ラベル、y軸ラベルをそれぞれ加える
title("The number of foreigners for entry to Japan",
xlab="Year", ylab="The number of entry (Thousands)")
# x軸とy軸をそれぞれ描き直す
axis(side=1, at=c(1:nrow(X)), labels=rownames(X), las=2)
axis(side=2, at=seq(0,2010000,by=500000), labels=seq(0,2010,by=500), las=2)
# 補助線を描き入れる
abline(h=seq(0,2010000,by=500000), lty=2, col="gray")
ここの処理は、円グラフを作成した方法の応用。
For文を使って、複数のグラフを重ね描きしている。
ここでは、新しくseq()関数が登場している。
この関数は、規則的に並んでいるベクトルを作成するための関数で、
from、 to、 by の3つのパラメータによって指定する。
今回は、from=0, to=2010000, by=500000 となっている。
すなわち、0〜2010000 の値を 500000 でベクトルを作成している。
同様に、1000人を単位にしているラベルに関しては、
from=0, to=2010, by=500でベクトルを作成している。
今回の処理でポイントなるのは、
plot()関数の ylim パラメータを明示的に指定している点である。
Rのplot()関数は、データの下限と上限にあわせて、相対的に描画するため、
プロットを重ね描きする際には、全データの上限と下限を確認し、設定する必要がある。
また、plot()関数の他のパラメータは、x軸とy軸のタイトルを空白で指定し、
後のtitle()関数のパラメータを使って描画している。
このように設定しないと、For文の繰り返し回数分だけラベルが重ね描きされる。
さて、今度は、重ね描きをしたことで色々と問題が生じている。
まず、どの線が何を表しているかが不明である。これは技術的な問題。
今回は、線種で分けて、凡例を追加することにする。
# 前回のプロットを初期化
dev.off()
# For文を使って折れ線グラフを連続して描く
for(i in 1:7){
par(new=TRUE)
plot(x=X[,i], type="l", xlab="", ylab="", xaxt="n", yaxt="n",
ylim=c(0,2010000), lty=i)
}
# グラフタイトル、x軸ラベル、y軸ラベルをそれぞれ加える
title("The number of foreigners for entry to Japan",
xlab="Year",
ylab="The number of entry (Thousands)")
# x軸とy軸をそれぞれ描き直す
axis(side=1, at=c(1:nrow(X)), labels=rownames(X), las=2)
axis(side=2, at=seq(0,2010000,by=500000), labels=seq(0,2010,by=500), las=2)
# 補助線を描き入れる
abline(h=seq(0,2010000,by=500000), lty=2, col="gray")
# 凡例を加える
legend("topleft",legend=colnames(X[,1:7]), lty=c(1:7))
今度は、折れ線の右端に行名を布置してある。
これで、どの線が何を示しているのかが良く解る。
このプロットでは、実際のデータよりも、
4ポイント分(4年分)だけ上限を余分に調整し、
さらに、text()関数を使って、行名(国名)を布置している。
ここで、テキストのx軸の位置は、最終年(2005年)+2年を指定し、
y軸はの位置は、最終年における入国者数を指定している。
この辺りの微調整は直感であり、何回か実験して最終的な位置を決めている。
慣れれば、1〜2回程度の微調整で上手く調整できる。
ふむ。これでかなり見やすくなった。
この結果から、米国よりも韓国と台湾からの入国者数が多く、
米国と中国からの入国者数が意外に近いことが解る。
また、中国からの入国者数は、2000年頃から急激に増え始めており、
それ以前は、米国や韓国、台湾からの入国者数と比較してかなり低いことが解る。
さて、このグラフには根本的な問題がある。実は、フィリピン、香港、ブラジルは、
このデータの上位の4カ国と比較して、
全体的に値が小さいので、読み取れる情報限られる。
このような場合、何をグラフに記載するべきか、改めて検討するべきである。
述べたいことに対して、情報が不足しているのは大きな問題であるが、
逆に、情報過多となることも避けなければならない。
安易に一つの図に全てを重ね合わせるのではなく、
状況に応じて、複数のグラフに分けることも重要である。
ということで、今度は、フィリピンとブラジルだけを分けることにする。
では、変化する値の可視化に対しては何を使うべきか?というのが今回の話。
実は、多くの人が意識していないのが、この種のデータの可視化方法。
「とりあえず、棒グラフで良いですかね〜?」
とする人は意外に多いように思える。いや、言ってる人を最近見た。
特別な理由があるわけでもなく、このような選択をしてはいないか?
Excelなど、多くのスプレッドシートソフトは、既定の状態で、棒グラフを表示する。
「いやいや、ちゃんと考えて可視化方法を選びなさい。」
という私のコメントに、
「えっ、グラフの選び方ってあるんですか?聞いたことありません。」
と言われた。ええ、有ります。物事の理屈を考えない人が多い。
重要なことは何を表現したいか、あるいは、どのように表現したいか?
確かに、ある時点における数量を表しているのだから、
棒グラフでも可視化方法として正しいのかもしれない。
しかしながら、ここで改めて考えてみたいことがある。
そもそも、「変化」とは何か?という問題である。
我々が変化する値を観察するときに留意するべきことは、
ある観測した瞬間と、次の瞬間の間にも変化が起きているか、ということである。
実は、折れ線グラフは、そのような連続的な変化を可視化する方法である。
棒グラフの話でも述べたが、基本的に棒グラフに順番は関係無い。
一方、折れ線グラフは、変化の順番が大きな意味が持ち、
その順番は、一般的には時間的な軸に従う順番である。
また、棒グラフや円グラフと同様に、
折れ線グラフを描く際には、色々と注意すべきこともある。
適当に描いて良いという訳ではない。
とりあえず、今回もRで実演しながら折れ線グラフについて考えてみよう。
今回は、法務省出入国管理統計統計表の「国籍別入国外国人(1950−2005)」の一部と、
財務省貿易統計年別輸出入総額のデータを編集し、合わせたもの。
国籍別入国外国人のデータは非常に大きいため、数カ国に絞っている。
国の選択は、私の個人的な興味であり、選択された国同士には何の脈絡も無い。
なお、年別輸出入総額のデータの単位は「千円」である。
いつものように。
# Windows と Linux の人は次のコマンド
X <- read.table("clipboard", sep=",")
# Mac の人は次のコマンド
X <- read.table(pipe("pbpaste") , sep=",")
データを読み込む。
China,Taiwan,Xianggang,Korea,Philippine,USA,Brazil,Export,Import
1964,562,12357,3844,18865,9105,129908,823,2402348862,2857515493
1965,576,15583,4326,17065,8945,150253,782,3042627204,2940846741
1966,503,17744,4229,25791,10824,173593,1154,3519500700,3428172558
1967,150,20789,4840,33558,12028,187373,1516,3758966022,4198711492
1968,11,25115,5567,39634,14190,199581,2196,4669798348,4675407477
1969,16,27501,6199,44654,13573,255663,2983,5756405162,5408472791
1970,139,46535,12506,71790,20477,315211,5866,6954367159,6797220528
1971,283,38774,8112,77545,12672,271029,3270,8392768263,6909956155
1972,994,47536,12645,85757,10860,281853,4772,8806072248,7228978838
1973,1991,50866,16893,110804,7874,287988,6734,10031426859,10404355041
1974,3161,60876,15463,124263,10411,245826,5765,16207879577,18076381928
1975,4441,77091,19318,129186,12574,237219,6522,16545313718,17170026976
1976,4018,82898,22721,141123,13073,274686,7804,19934618464,19229168610
1977,4039,88813,25620,156605,16138,303755,6153,21648070431,19131779700
1978,5951,99237,23273,184101,20375,275240,7696,20555840563,16727624005
1979,11622,165708,24094,199146,23223,256507,7488,22531538859,24245350997
1980,18336,235549,32239,212973,27902,277980,8381,29382471938,31995325202
1981,17550,305233,46614,250709,37483,310726,9438,33468984502,31464145741
1982,20532,311125,59898,284598,37878,352208,10336,34432500947,32656302574
1983,26606,331634,64727,283971,47887,400984,7992,34909268599,30014784056
1984,51010,351294,52750,292483,49511,437745,9250,40325293701,32321126640
1985,100972,356934,49153,296708,65529,487713,13889,41955659471,31084935207
1986,75275,300272,32271,299602,80508,482670,13434,35289713887,21550717070
1987,73030,360636,30569,360159,85267,479891,12126,33315191383,21736912673
1988,112389,392723,29127,515807,86567,457620,16789,33939183158,24006319859
1989,100144,501907,32007,806065,88296,538117,29241,37822534626,28978572581
1990,117814,610652,38622,978984,108292,564958,67303,41456939674,33855207638
1991,142150,686076,37483,1097601,125329,554147,96337,42359892974,31900153522
1992,187681,745835,39460,1094724,120660,574181,81495,43012281444,29527419360
1993,204302,700294,33391,1069450,109353,549090,70719,40202448725,26826357239
1994,210476,681183,31535,1140372,126739,548265,72236,40497552697,28104327343
1995,229965,614931,20378,1103566,105838,558474,90322,41530895121,31548753881
1996,257393,756785,27761,1224441,106394,606652,94068,44731311206,37993421106
1997,283467,857877,30806,1236597,124856,642933,104323,50937991859,40956182573
1998,299573,874985,53278,960556,129053,688006,77569,50645003938,36653647183
1999,327005,963701,42283,1160034,144305,720142,70794,47547556241,35268008063
2000,385296,944019,49423,1286583,169755,749343,101513,51654197760,40938422968
2001,444441,838001,74704,1342987,186262,715036,81800,48979244311,42415533002
2002,527796,909654,136482,1472096,197136,755196,71763,52108955735,42227505945
2003,537700,816692,163254,1621903,209525,678935,79692,54548350172,44362023352
2004,741659,1117950,226321,1774872,236291,785916,79960,61169979094,49216636346
2005,780924,1315594,250366,2008418,221309,853845,91268,65656544157,56949392181
このデータは、毎年の国籍入国者のデータと毎年の輸出入総額のデータである。
この二種類のデータは、本来は毎日のデータであって、それが年毎に集計されている。
また、年毎に区切っているのは、あくまで、等間隔に観測地点を置くためであって、
毎年のデータの切れ目は実質的に無意味である。したがって、
1月1日〜12月31日を一つの区切りにしようが、
4月1日〜3月31日を区切りにしようが、
9月1日〜8月31日を区切りにしようが、
実質的には変わらないハズ。
重要なことは、実際には常に変化しているが、
観測上の区切りが必要であるというイメージが出来ていること。
折れ線グラフというのは、このイメージを反映した可視化法なのである。
先頭が中国なので、まずは、中国のグラフから書いてみる。
plot(X$China, type="l")
流石に、これは大丈夫であろう。「l」は「line」の頭文字。折れ線グラフを描く。
何が足りていないかも大丈夫であろう。そうそう。タイトルが抜けている。
plot(X$China, type="l")
title("The number of Chinese entrants to Japan")
この状態でもグラフとしては不完全である。
まず、x軸とy軸の軸ラベル、目盛りラベルが不適切である。
# 折れ線グラフを書いてみる
plot(X$China, type="l", xlab="Year", ylab="The number of entry", xaxt="n")
# タイトルを加える
title("The number of Chinese entrants to Japan")
# x軸の目盛りラベルを付ける
axis(side=1, at=c(1:nrow(X)), labels=rownames(X), las=2)
ここでは、plot()関数で、xaxt="n"とし、この段階ではx軸を描かず、
最後のaxis()関数で、改めて描き直している。
ふむ。これで、一応の体裁は整った。しかし、y軸の目盛りラベルが見難い。
数が非常に大きいので、表現の仕方がコンピュータ上での表現になっている。
とりあえず、見やすいように、千人単位にしてみる。
# 折れ線グラフを描く
plot(X$China, type="l", xlab="Year", ylab="The number of entry", xaxt="n", yaxt="n")
# タイトルを加える
title("The number of Chinese entrants to Japan")
# x軸の目盛りラベルを配置し、
axis(side=1, at=c(1:nrow(X)), labels=rownames(X), las=2)
# y軸の目盛りラベルを単位を変えて配置する
axis(side=2, at=seq(0, 8e+05, by=1e+05), labels=seq(0, 8e+02, by=1e+02), las=2)
さて、これで、かなり見やすくなったのが、
y軸の目盛りラベルを修正したことによって、y軸の単位が変更されている。
軸ラベルを「1000人単位」であることが解るように修正しなければならない。
plot(X$China, type="l", xlab="Year", ylab="The number of entry (Thousands)", xaxt="n", yaxt="n")
title("The number of Chinese entrants to Japan")
axis(side=1, at=c(1:nrow(X)), labels=rownames(X), las=2)
axis(side=2, at=c(2e+05, 4e+05, 6e+05, 8e+05), labels=c(2e+02, 4e+02, 6e+02, 8e+02), las=2)
これで、何のデータであるかが理解できる。
折れ線グラフというのは、このように、変化を表すために利用する。
実は、線で結ばれているのは、ある観測点から次の観測点の間も、
「実は、変化し続けている」という状況を表している。
このように、本来は存在するのだけれど、
実際には観測していないので、仮説的に観測点同士をつなげることを、
「補間(interpolation)」と呼ぶ。
補間は、折れ線グラフのように1次元のデータだけではなく二次元での補間もある。
二次元での補間を行うことで、数学的に等高線が描けるのであるが、
今回、この話は置いておくことにする。
もちろん、直線では無く、曲線で補間することもあるが、
なぜ、曲線で表すべきであるか、についても考える必要がある。
単に、「格好良い」とか、そういう理由で安易に曲線にするべきではない。
今回の例では、数を数えただけの値なので、わざわざ、曲線で表す必要は無いだろう。
さて、話を戻そう。
先程の例では、中国人の入国者数だけであったが、
今度は、他の国の入国者数も同時に表現してみる。
# 前回のプロットを初期化
dev.off()
# For文を使って折れ線グラフを連続して描く
for(i in 1:7){
par(new=TRUE)
plot(x=X[,i], type="l", xlab="", ylab="", xaxt="n", yaxt="n", ylim=c(0,2010000))
}
# グラフタイトル、x軸ラベル、y軸ラベルをそれぞれ加える
title("The number of foreigners for entry to Japan",
xlab="Year", ylab="The number of entry (Thousands)")
# x軸とy軸をそれぞれ描き直す
axis(side=1, at=c(1:nrow(X)), labels=rownames(X), las=2)
axis(side=2, at=seq(0,2010000,by=500000), labels=seq(0,2010,by=500), las=2)
# 補助線を描き入れる
abline(h=seq(0,2010000,by=500000), lty=2, col="gray")
ここの処理は、円グラフを作成した方法の応用。
For文を使って、複数のグラフを重ね描きしている。
ここでは、新しくseq()関数が登場している。
この関数は、規則的に並んでいるベクトルを作成するための関数で、
from、 to、 by の3つのパラメータによって指定する。
今回は、from=0, to=2010000, by=500000 となっている。
すなわち、0〜2010000 の値を 500000 でベクトルを作成している。
同様に、1000人を単位にしているラベルに関しては、
from=0, to=2010, by=500でベクトルを作成している。
今回の処理でポイントなるのは、
plot()関数の ylim パラメータを明示的に指定している点である。
Rのplot()関数は、データの下限と上限にあわせて、相対的に描画するため、
プロットを重ね描きする際には、全データの上限と下限を確認し、設定する必要がある。
また、plot()関数の他のパラメータは、x軸とy軸のタイトルを空白で指定し、
後のtitle()関数のパラメータを使って描画している。
このように設定しないと、For文の繰り返し回数分だけラベルが重ね描きされる。
さて、今度は、重ね描きをしたことで色々と問題が生じている。
まず、どの線が何を表しているかが不明である。これは技術的な問題。
今回は、線種で分けて、凡例を追加することにする。
# 前回のプロットを初期化
dev.off()
# For文を使って折れ線グラフを連続して描く
for(i in 1:7){
par(new=TRUE)
plot(x=X[,i], type="l", xlab="", ylab="", xaxt="n", yaxt="n",
ylim=c(0,2010000), lty=i)
}
# グラフタイトル、x軸ラベル、y軸ラベルをそれぞれ加える
title("The number of foreigners for entry to Japan",
xlab="Year",
ylab="The number of entry (Thousands)")
# x軸とy軸をそれぞれ描き直す
axis(side=1, at=c(1:nrow(X)), labels=rownames(X), las=2)
axis(side=2, at=seq(0,2010000,by=500000), labels=seq(0,2010,by=500), las=2)
# 補助線を描き入れる
abline(h=seq(0,2010000,by=500000), lty=2, col="gray")
# 凡例を加える
legend("topleft",legend=colnames(X[,1:7]), lty=c(1:7))
線種は「i」という変数で指定している。
したがって、繰り返し処理が発生する度に1〜7の順で線種が選択される。
これでも良いが、やはり、少々見難い。
さらに、見易いようにもうひと工夫してみる。
# 前回のプロットを初期化
dev.off()
# 描画範囲を右方向に少しだけ広げる
for(i in 1:7){
par(new=TRUE)
plot(x=X[,i], type="l", xlab="", ylab="", xaxt="n",
yaxt="n", ylim=c(0, 2010000), xlim=c(0,nrow(X)+4), lty=i)
# 行名(国名)を text()関数 を使って描き入れる
text(x=nrow(X)+2, y=X[nrow(X),i], colnames(X)[i], cex=0.8)
}
# タイトルとx軸、y軸ラベルはそのまま
title("The number of foreigners for entry to Japan",
xlab="Year", ylab="The number of entry (Thousands)")
# x軸、y軸、補助線、凡例をそれぞれ加える
axis(side=1, at=c(1:nrow(X)), labels=rownames(X), las=2)
axis(side=2, at=seq(0,2010000,by=500000), labels=seq(0,2010,by=500), las=2)
abline(h=seq(0,2010000,by=500000), lty=2, col="gray")
legend("topleft",legend=colnames(X[,1:7]), lty=c(1:7))
par(new=TRUE)
plot(x=X[,i], type="l", xlab="", ylab="", xaxt="n",
yaxt="n", ylim=c(0, 2010000), xlim=c(0,nrow(X)+4), lty=i)
# 行名(国名)を text()関数 を使って描き入れる
text(x=nrow(X)+2, y=X[nrow(X),i], colnames(X)[i], cex=0.8)
}
# タイトルとx軸、y軸ラベルはそのまま
title("The number of foreigners for entry to Japan",
xlab="Year", ylab="The number of entry (Thousands)")
# x軸、y軸、補助線、凡例をそれぞれ加える
axis(side=1, at=c(1:nrow(X)), labels=rownames(X), las=2)
axis(side=2, at=seq(0,2010000,by=500000), labels=seq(0,2010,by=500), las=2)
abline(h=seq(0,2010000,by=500000), lty=2, col="gray")
legend("topleft",legend=colnames(X[,1:7]), lty=c(1:7))
今度は、折れ線の右端に行名を布置してある。
これで、どの線が何を示しているのかが良く解る。
このプロットでは、実際のデータよりも、
4ポイント分(4年分)だけ上限を余分に調整し、
さらに、text()関数を使って、行名(国名)を布置している。
ここで、テキストのx軸の位置は、最終年(2005年)+2年を指定し、
y軸はの位置は、最終年における入国者数を指定している。
この辺りの微調整は直感であり、何回か実験して最終的な位置を決めている。
慣れれば、1〜2回程度の微調整で上手く調整できる。
ふむ。これでかなり見やすくなった。
この結果から、米国よりも韓国と台湾からの入国者数が多く、
米国と中国からの入国者数が意外に近いことが解る。
また、中国からの入国者数は、2000年頃から急激に増え始めており、
それ以前は、米国や韓国、台湾からの入国者数と比較してかなり低いことが解る。
さて、このグラフには根本的な問題がある。実は、フィリピン、香港、ブラジルは、
このデータの上位の4カ国と比較して、
全体的に値が小さいので、読み取れる情報限られる。
このような場合、何をグラフに記載するべきか、改めて検討するべきである。
述べたいことに対して、情報が不足しているのは大きな問題であるが、
逆に、情報過多となることも避けなければならない。
安易に一つの図に全てを重ね合わせるのではなく、
状況に応じて、複数のグラフに分けることも重要である。
ということで、今度は、フィリピンとブラジルだけを分けることにする。
# 前回のプロットを初期化
dev.off()
# For文で回すのは5番目(フィリピン)と7番目(ブラジル)のデータだけ
for(i in c(5,7)){
par(new=TRUE)
# y軸の上限は、フィリピンとブラジルのデータに合わせて再設定
plot(x=X[,i], type="l", xlab="", ylab="", xaxt="n",
yaxt="n", ylim=c(0,300000), xlim=c(0,nrow(X)+4), lty=i)
text(x=nrow(X)+2, y=X[nrow(X),i], colnames(X)[i], cex=0.8)
}
# グラフタイトルは通常通りに
title("The number of foreigners for entry to Japan",
xlab="Year", ylab="The number of entry (Thousands)")
# x軸の描画も今までと同じ
axis(side=1, at=c(1:nrow(X)), labels=rownames(X), las=2)
# y軸の上限は、フィリピンとブラジルのデータに合わせて再設定
axis(side=2, at=seq(0,300000,by=100000), labels=seq(0,300,by=100), las=2)
# 補助線の位置も軸目盛りに合わせて再設定が必要。
abline(h=seq(0,300000,by=100000), lty=2, col="gray")
# 凡例は、5番目と7番目だけ。
legend("topleft",legend=colnames(X[,c(5,7)]), lty=c(5,7))
先程のゴチャ混ぜグラフよりも、フィリピンとブラジルの状況が見易い。
フィリピンは、1990年〜1997年ごろまで、水平に移行する時期があるものの、
基本的に、入国者数は増加傾向にあることが解る。
一方、ブラジルは、1989年ごろから、急激に入国者数が増加し、
1990年以降は、水平に移行していることが解る。
これらの傾向は、先程のグラフでは、差が見え難く、
判らなかったことである。
折れ線グラフは、他のグラフと比較して、
複数のデータ重ねあわせて描画することが多い。
それゆえに、気を付けないといけないことも多い。
まず、不必要に大量なデータを重ね合わせることを避け、
目的を絞って、必要最低限のものに留める。
特に、値の高低差が激しいデータを扱うときには気を付ける必要がある。
実際には、重要な意味が潜んでいるかもしれないが、
高低差が見難いが故に、重要な情報を見落とす可能性がある。
さてさて、以上が折れ線グラフの基本である。
これらのポイントを抑えておけば、見易く、説得力のあるグラフが作れるだろう。
ところで、今回のデータは、年別輸出入総額のデータも含まれていた。
今度は、外国人の入国者数と、輸出入総額のデータの比較もやってみたい。
まずは、年別の輸出総額のデータから。
少し長いが、良く見れば、理解できるはず。
# 凡例を書き入れる
par(new=TRUE)
# y軸の上限は、フィリピンとブラジルのデータに合わせて再設定
plot(x=X[,i], type="l", xlab="", ylab="", xaxt="n",
yaxt="n", ylim=c(0,300000), xlim=c(0,nrow(X)+4), lty=i)
text(x=nrow(X)+2, y=X[nrow(X),i], colnames(X)[i], cex=0.8)
}
# グラフタイトルは通常通りに
title("The number of foreigners for entry to Japan",
xlab="Year", ylab="The number of entry (Thousands)")
# x軸の描画も今までと同じ
axis(side=1, at=c(1:nrow(X)), labels=rownames(X), las=2)
# y軸の上限は、フィリピンとブラジルのデータに合わせて再設定
axis(side=2, at=seq(0,300000,by=100000), labels=seq(0,300,by=100), las=2)
# 補助線の位置も軸目盛りに合わせて再設定が必要。
abline(h=seq(0,300000,by=100000), lty=2, col="gray")
# 凡例は、5番目と7番目だけ。
legend("topleft",legend=colnames(X[,c(5,7)]), lty=c(5,7))
先程のゴチャ混ぜグラフよりも、フィリピンとブラジルの状況が見易い。
フィリピンは、1990年〜1997年ごろまで、水平に移行する時期があるものの、
基本的に、入国者数は増加傾向にあることが解る。
一方、ブラジルは、1989年ごろから、急激に入国者数が増加し、
1990年以降は、水平に移行していることが解る。
これらの傾向は、先程のグラフでは、差が見え難く、
判らなかったことである。
折れ線グラフは、他のグラフと比較して、
複数のデータ重ねあわせて描画することが多い。
それゆえに、気を付けないといけないことも多い。
まず、不必要に大量なデータを重ね合わせることを避け、
目的を絞って、必要最低限のものに留める。
特に、値の高低差が激しいデータを扱うときには気を付ける必要がある。
実際には、重要な意味が潜んでいるかもしれないが、
高低差が見難いが故に、重要な情報を見落とす可能性がある。
さてさて、以上が折れ線グラフの基本である。
これらのポイントを抑えておけば、見易く、説得力のあるグラフが作れるだろう。
ところで、今回のデータは、年別輸出入総額のデータも含まれていた。
今度は、外国人の入国者数と、輸出入総額のデータの比較もやってみたい。
まずは、年別の輸出総額のデータから。
少し長いが、良く見れば、理解できるはず。
# 前回のプロットを初期化
dev.off()
png(width=600)
# 第二軸の軸ラベルを描くために余白を調整する
par(oma=c(1,1,1,5))
# 入国者数のグラフを描く
for(i in c(1:4,6)){
par(new=TRUE)
plot(x=X[,i], type="l", xlab="", ylab="", xaxt="n", yaxt="n", ylim=c(0,2010000), xlim=c(0,nrow(X)+4), lty=i)
text(x=nrow(X)+2, y=X[nrow(X),i], colnames(X)[i], cex=0.8)
}
# グラフタイトルとx軸、y軸を加える
title(paste("The number of foreigners for entry to Japan", "and total exports", sep="\n"),
xlab="Year", ylab="The number of entry (Thousands)")
axis(side=1, at=c(1:nrow(X)), labels=rownames(X), las=2)
axis(side=2, at=seq(0,2010000,by=500000), labels=seq(0,2010,by=500), las=2)
# 補助線を加える
abline(h=seq(0,2010000,by=500000), lty=2, col="gray")
# 輸出総額のグラフを追加する
par(new=TRUE)
plot(x=X[,8], type="l", xlab="", ylab="", xaxt="n", yaxt="n", xlim=c(0,nrow(X)+4), col="blue")
axis(side=4, at=seq(0,max(X[,8]),by=10000000000),
labels=formatC(seq(0,max(X[,8]/1000000),by=10000), format="d"), las=2)
# 第二軸の軸ラベルを描画する
mtext("Total exports (Billions)", side=4, outer=TRUE, line=3)
# 凡例を書き入れる
legend("topleft",legend=colnames(X[, c(1:4,6,8)]), lty=c(1:4,6,1), col=rep(c("black","blue"),c(5,1)))
最初のpar()関数では、oma パラメータを指定している。
これは、outer margin のことで、グラフエリアの外側の余白の設定を意味する。
元の状態では、右側の余白が狭すぎて、ラベルや軸メモリを描けないため、
この部分で、微調整を行なっている。値の設定は「勘」。慣れが必要。
ここで新しく登場した関数は、formatC()関数である。
ここでは「1e+05」のような、コンピュータ独自の表現を
通常の数値に直すために用いている。
さて、今回は、入国者数の単位は「人」で、輸出総額の単位は「千円」である。
したがって、今回のグラフでは「単位」が異なる二つのグラフを描いているので、
左側を第一軸(入国者)、右側を第二軸(輸出総額)とするグラフとなっている。
また、輸出総額の単位は、千円の状態であると、値が大きすぎるので、
第二軸のメモリラベルの単位が「10億円」となるように調整している。
次は、輸入総額との比較。
# 前回のプロットを初期化
dev.off()
# 第二軸の軸ラベルを描くために余白を調整する
par(oma=c(1,1,1,5))
# 入国者数のグラフを描く
for(i in c(1:4,6)){
par(new=TRUE)
plot(x=X[,i], type="l", xlab="", ylab="", xaxt="n", yaxt="n", ylim=c(0,2010000), xlim=c(0,nrow(X)+4), lty=i)
text(x=nrow(X)+2, y=X[nrow(X),i], colnames(X)[i], cex=0.8)
}
# グラフタイトルとx軸、y軸を加える
title(paste("The number of foreigners for entry to Japan", "and total imports", sep="\n"),
xlab="Year", ylab="The number of entry (Thousands)")
axis(side=1, at=c(1:nrow(X)), labels=rownames(X), las=2)
axis(side=2, at=seq(0,2010000,by=500000), labels=seq(0,2010,by=500), las=2)
# 補助線を加える
abline(h=seq(0,2010000,by=500000), lty=2, col="gray")
# 輸入総額のグラフを追加する
par(new=TRUE)
plot(x=X[,9], type="l", xlab="", ylab="", xaxt="n", yaxt="n", xlim=c(0,nrow(X)+4), col="red")
axis(side=4, at=seq(0,max(X[,9]),by=10000000000),
labels=formatC(seq(0,max(X[,9]/1000000),by=10000), format="d"), las=2)
# 第二軸の軸ラベルを描画する
mtext("Total imports (Billions)", side=4, outer=TRUE, line=3)
# 凡例を書き入れる
legend("topleft",legend=colnames(X[, c(1:4,6,8)]), lty=c(1:4,6,1), col=rep(c("black","red"),c(5,1)))
さて、折れ線グラフは、このように描かれた。
重要なことは、「変化」を表すために用いるのが折れ線グラフであるということ。
また、折れ線グラフの「線」は、観測点同士を視覚的に結んでいるのでは無く、
「補間」であるという認識も重要。したがって、理屈上は、
観測されていない間も潜在的にはデータは存在している。
折れ線グラフでは、異なる単位のデータを重ねることもできる。
その場合には、第一軸と第二軸を分けて、左側に第一軸の軸と軸ラベルを、
右側に第二軸の軸と軸ラベルを用いるのが一般的である。
注意すべき点は、必要以上にグラフを描き入れて、情報過多にならないようにすること。
状況に応じて、複数のグラフに分けることも重要である。
0 件のコメント:
コメントを投稿