読者です 読者をやめる 読者になる 読者になる

Mukku John Blog

取り組んでいること を つらつら と

ggplot2を使って、散布図を作る-2

Rグラフィックスクックブック 散布図

R グラフィックス クックブック 11回目

ggplot2パッケージを利用して、散布図を作成していきます。

この記事は、オーバープロット(下のグラフ)時の対処方法を対象にします。
ダイヤの大きさ:carat/価格:priceの分布です。
f:id:MukkuJohn:20160829224849p:plain
ただの黒い滝です。

オーバープロット時の解決策

オーバープロット時に、どうするか? その時には、下記のいずれかを試します。

  • 点を半透明にする
  • データをビンに詰める
  • 箱ひげ図を使う

ちなみに、データはこちらになります。
diamonds. ggplot2 0.9.3.1

> head(diamonds[ , c("carat", "price")], 3)
  carat price
1  0.23   326
2  0.21   326
3  0.23   327

> str(diamonds[ , c("carat", "price")])
'data.frame':	53940 obs. of  2 variables:
 $ carat: num  0.23 0.21 0.23 0.29 0.31 0.24 0.24 0.26 0.22 0.23 ...
 $ price: int  326 326 327 334 335 336 336 337 337 338 ...

グラフ作成時のコマンドはこちら

sp <- ggplot(diamonds, aes(x = carat, y = price))
sp + geom_point()
点を半透明にする

90%透過してみます。

sp + geom_point(alpha = .1)

f:id:MukkuJohn:20160829230257p:plain
なんとなしに、縦方向に束になっているのかなぁ。くらいですね。
黒い滝には変わりないです。


99%透過してみます。

sp + geom_point(alpha = .01)

f:id:MukkuJohn:20160829230400p:plain
う~ん、、、このグラフであれば、カラットから価格の相関が見えるかな
1.5カラットだと、大体、価格はこの範囲だよ。くらいですかね?

点を半透明にするのは、これが限界です。埒が明かないので、次の手段を取ります。

データをビンに詰める

データをビンに詰める目的は、データの分布を見るためにあります。
ビン詰めについては、この本が参考になりました。
www.diamond.co.jp
新幹線が立ち往生している時間で読み終わるくらいのページ数です。
mukkujohn.hatenablog.com


x軸とy軸で区分けされたビンの中にデータポイントを押し込んで、
そのビンの中に詰められたデータポイントの個数をプロットします。

sp + stat_bin2d()

f:id:MukkuJohn:20160829231605p:plain
このグラフであれば、データの分布が分かります。
ほとんどが、サイズが小さく、価格も安めなダイヤが多いですね。
また、1カラットくらいまでは、カラットと価格が比例してそうです。

ビンの個数や、色を指定することもできます。

sp + stat_bin2d(bins = 50) +
  scale_fill_gradient(low = "lightblue", high = "red", 
                      limits = c(0, 6000))

f:id:MukkuJohn:20160829232158p:plain
ビンの個数を増やすと、データの区分けが変わります。

デフォルトのビンの数(=30個)だと、左下が一番多いグラフでしたが、
カラットをちょっと増やしたダイヤが一番多いグラフに変わりました。


上のグラフは、x軸/y軸に対して、長方形のビンに詰めましたが
六角形のビンに詰め込む手段もあります。
CRAN - Package hexbin

library(hexbin)

sp + stat_binhex() +
  scale_fill_gradient(low = "lightblue", high = "red",
                      limits = c(0, 8000))

f:id:MukkuJohn:20160829233653p:plain


下のコードの様に、ビンに入れるデータの個数を指定することもできます。

sp + stat_binhex() +
  scale_fill_gradient(low = "lightblue", high = "red",
                      breaks = c(0, 1000, 2000, 3000, 4000, 5000),
                      limits = c(0, 5000))

f:id:MukkuJohn:20160829234254p:plain
グレーで表示されている箇所は、データの個数が範囲外を示します。
上の例だと、5000件を超えていることを示しています。


今まで、x軸もy軸も連続値のデータを扱ってきましたが、
オーバープロットは、離散値のデータでも発生しますね。

連続値と離散値を表現する場合は、箱ひげ図を使います。

箱ひげ図

このデータの、Timeとweightを使います。
R: Weight versus age of chicks on different diets

x軸にTimeを、y軸にweightをマッピングしています。
縦方向に束になっているグラフですので、分布はさっぱりです。
f:id:MukkuJohn:20160829235157p:plain
上のグラフのコードはこちら。

sp1 <- ggplot(ChickWeight, aes(x = Time, y = weight))
sp1 + geom_point()


箱ひげ図は、グループ列を指定して、geom_boxplotを使います。
箱ひげ図については、この記事で、作成方法や読み方を記載しています。
mukkujohn.hatenablog.com

sp1 + geom_boxplot(aes(group = Time))

f:id:MukkuJohn:20160829235609p:plain
箱ひげ図であれば、中央値や四分位数より、縦方向の分布が理解できます。

箱ひげ図以外にも、離散値を扱う場合には、点に揺らぎを与える方法が
揺らぎを与えて・・・???なので、必要な場面になったら掘り下げます。
コードと図だけ

sp1 + geom_point(position = "jitter")

f:id:MukkuJohn:20160830000636p:plain

次回は、散布図に線形回帰モデルの直線をプロットします。
散布図は回が多くなりそうです。