日々のつれづれ

不惑をむかえ戸惑いを隠せない男性の独り言

色の話・その3

以前の日記で少し前フリしていた色の話。の続き。

  • 色は視認性が高いグラフを書くときに大切な要素
  • 色の多用は、グラフの本質を隠してしまう
  • 人が理解できる限界は3~4色じゃないだろうか

と、思ってます。

ここでは、Rを起動すると自動的に読み込まれるgrDevicesパッケージの話。

  • colorRampPalette関数

返り値は色のベクトルでなく関数。使い方がrainbows関数やgray関数と違う。
引数colorで指定する色を基準にグラデーションを作成する。
他の引数は
bias…グラデーションを取るときに色と色の間にgapを作る
space…グラデーションを作るときのカラーモデル。RGB系か、CIELAB系*1
interpolate…グラデーションを作るときに線形補完かスプライン補完か選ぶ

> x <- seq(-2*pi,2*pi,length.out=100)
> dat <- outer(x,x,function(x,y) { r <- sqrt(x^2+y^2);10*sin(r)/r})
> library(fields)
> 
> jpeg("colorRampPalette.jpg")
> filled.contour(dat,color=colorRampPalette(color=c("blue","yellow","red"))
+ ,main='colorRampPalette(color=c("blue","yellow","red")')
> dev.off()

で、こうなる。

colorRampPalette関数は関数を返すので、引数に使える関数は限られる。
僕はfilled.contour関数、hexbinパッケージのhexbin関数、densCol関数ぐらいしか知らない。

    • hexbin関数

xbinsで指定する単位で散布図をグループ化(bin)する関数。
で、plotで引数colrampにcolorRampPallette関数を付与することで、各binをdensityで色分けしてくれる。
データポイント数が多いときは出力ファイルの容量が小さくなるので便利。

> library(hexbin)
> dat <- hexbin(rnorm(2^16,sd=1),rnorm(2^16,sd=5),xbins=50)
> summary(dat)
'hexbin' object from call: hexbin(x = rnorm(2^16, sd = 1), y = rnorm(2^16, sd = 5), xbins = 50) 
n = 65536  points in	nc = 1590  hexagon cells in grid dimensions  60 by 51 
      cell            count             xcm                 ycm          
 Min.   :  19.0   Min.   :  1.00   Min.   :-3.831576   Min.   :-21.2651  
 1st Qu.: 977.2   1st Qu.:  3.00   1st Qu.:-1.396720   1st Qu.: -6.7679  
 Median :1453.5   Median : 12.00   Median : 0.013372   Median :  0.1448  
 Mean   :1450.4   Mean   : 41.22   Mean   :-0.004961   Mean   :  0.1094  
 3rd Qu.:1924.8   3rd Qu.: 54.00   3rd Qu.: 1.386504   3rd Qu.:  7.0692  
 Max.   :2985.0   Max.   :284.00   Max.   : 4.025059   Max.   : 22.8828  
> 
> jpeg("colorRampPalette2.jpg")
> plot(dat,colramp=colorRampPalette(c("blue","yellow","red"))
+ ,main='colorRampPalette(c("blue","yellow","red")')
> dev.off()

で、こうなる。

    • でも、colorRampPallete関数は関数を返すので、色コードを作ることができる。
> BYR <- colorRampPalette(c("blue","yellow","red"))
> # オブジェクトBYRは、青 -> 黄 -> 赤のグラデーションを作る関数になる
> BYR
function (n) 
{
    x <- ramp(seq.int(0, 1, length.out = n))
    rgb(x[, 1], x[, 2], x[, 3], maxColorValue = 255)
}
<bytecode: 0xa778d24>
<environment: 0xa019fec>
>
> BYR(20)
 [1] "#0000FF" "#1A1AE4" "#3535C9" "#5050AE" "#6B6B93" "#868678" "#A1A15D"
 [8] "#BBBB43" "#D6D628" "#F1F10D" "#FFF100" "#FFD600" "#FFBB00" "#FFA100"
[15] "#FF8600" "#FF6B00" "#FF5000" "#FF3500" "#FF1A00" "#FF0000"
> x <- seq(-2*pi,2*pi,length.out=100)
> dat <- outer(x,x,function(x,y) { r <- sqrt(x^2+y^2);10*sin(r)/r})
> library(fields)
> jpeg("colorRampPalette3.jpg")
> image.plot(dat,col=BYR(20)
+ ,main='BYR <- colorRampPalette(c("blue","yellow","red"))')
> dev.off()

で、こうなる。

つまり、ワンクッションおくと便利な関数になる。

    • densCols関数

引数x, yで与える次元に対して、nbinで指定する単位でグループ化(bin)する。
で、各binのdensityに応じた濃淡をつけてくれる。
色のグラデーションはcolrampで指定できる。デフォルトは前の日記に書いたBlues9

> x <- cbind(rnorm(2^16,sd=1),rnorm(2^16,sd=5))
> dcol <- densCols(x,nbin=50
+ ,colramp=colorRampPalette(c("blue","yellow","red")))
> 
> jpeg("colorRampPalette4.jpg")
> plot(x,col=dcol,pch=46,cex=2
+ ,main='densCols_colorRampPalette(c("blue","yellow","red")')
> dev.off()

で、こうなる。

ただ、densCols関数はdensityに従って色をつけているだけなので、plotした点の数は変わってない(と思う)。そのため、出力したファイルサイズは変わらない。
そういう意味では、hexbinの方が実用的と思う。

今日はこの辺で。

*1:正式名称は、1976 CIE L*a*b* Space