統計グラフの色

はじめに

統計グラフに色を付けることは広く行われています。しかし,色は万人に共通のものではありません。日本人男性の5%,白人男性の8%は,RGB(赤緑青)のうち赤と緑の区別がうまくできません。その内訳は1:3で赤の感受性がないP型(1型,protanopia)と緑の感受性がないD型(2型,deuteranopia)に分かれます。青を感じない人や,RGBのうち2色以上を感じない人もいます。少数ですが女性にもあります。RGBをすべて区別できることを前提とした統計グラフは避けなければなりません。形やパターンを併用するなどの工夫が必要です。その上で,できるだけ多くの人に見分けやすく快い色遣いをしましょう。

Rでの色指定

Rの多くの描画関数では col="red" のようなオプションで色が指定できます。"red" のように名前が付いたものは数百色あり,Rのコンソールに colors() と打ち込めば列挙されます。より便利な指定法はHTMLと同じ16進6桁または8桁の "#rrggbb" または "#rrggbbaa" という書き方です(aa は不透明度を表すアルファ値)。あるいは0〜1の実数値を使って rgb(r,g,b) あるいは rgb(r,g,b,a) と書くこともできます。例えば "red""#FF0000""#FF0000FF"rgb(1,0,0)rgb(1,0,0,1) と同じです。

rgb() 以外に hsv()hcl() でも指定できます。色の変換には col2rgb()convertColor()adjustcolor() といった関数が用意されています。詳しくはヘルプをご覧ください(コンソールに例えば ?hcl と打ち込みます)。

モノクロ印刷物の場合は gray(0)(黒)から gray(1)(白)までの実数値による指定が便利でしょう。カラー印刷物に使われるCMYKについては下で説明します。

パレットの選び方

色を名前やRGB値で指定するより,色の集合すなわちパレットを用意しておき,そこから選んで使うほうが便利です。

色見本

Rでデフォルトのパレット palette()black, red, green3, blue, cyan, magenta, yellow, gray の8色です:

# png("rgbcolors.png", 400, 200)
# par(mar=c(0,0,0,0))
barplot(rep(1,8), col=palette(), axes=FALSE)
# dev.off()

上のような原色は,目が痛くなるので,なるべく使わないようにしましょう。

rainbow() を使えば任意の個数の色が作れますが,やはり原色に近く,明暗の差があるのでカテゴリーデータに向かないという説もあります。colorspace パッケージの rainbow_hcl() を使えば,できるだけ同じ明度・彩度の色になります。

色見本
library(colorspace)
# png("colors.png", 400, 200)
# par(mar=c(0,0,0,0))
plot(NULL, xlim=c(0,7), ylim=c(0,2),
     axes=FALSE, xlab="", ylab="")
rect(0:6, 1.1, 1:7, 2, col=rainbow(7))
rect(0:6, 0, 1:7, 0.9, col=rainbow_hcl(7, c=100))
# dev.off()

この rainbow_hcl() はHCL色空間で一定のC(chroma,彩度),L(luminance,明度)を保ちながらH(hue,色相)だけを変えて色を作ります。デフォルトでは彩度 c = 50,明度 l = 70 ですが,上の例では彩度を少し上げています。

印刷にはRGBベースではなくCMYKベースの色を使います。有名な W. S. Cleveland の The Elements of Graphing Data という本ではCMYKをベースに次の5色をカテゴリーデータ用に薦めています。

(c,m,y,k)#rrggbb (R)#rrggbb (Photoshop)色名
(1,0,0,0)#00ffff#00a0e9cyan
(0,1,0,0)#ff00ff#e4007fmagenta
(1,0,1,0)#00ff00#009944green
(0,0.5,1,0)#ff8000#f39800orange
(1,0.5,0,0)#0080ff#0068b7royal blue

最後の色をClevelandはlight blueと書いていますが,ここではより適切と思われるroyal blueを使いました。

上の表でPhotoshopのRGB値はPhotoshop CS5でJapan Color 2001 CoatedからsRGBに変換したものです。一方,RではRGB→CMYKを便宜上次のような簡単なアルゴリズムで変換しています:

c = 1.0 - r
m = 1.0 - g
y = 1.0 - b
k = min(c, m, y)
if (k == 1.0) {
  c = m = y = 0.0
} else {
  c = (c-k)/(1-k)
  m = (m-k)/(1-k)
  y = (y-k)/(1-k)
}

RではCMYK値を直接指定することができないので,上のアルゴリズムを逆に計算したRGB値を使って色を指定し,PostScriptなどのCMYKデバイスに出力します。例えばオレンジ (c,m,y,k) = (0,0.5,1,0) を使いたいならRでは #ff8000 を指定します。

色見本

ちなみにClevelandは連続量をcyanとmagentaの濃淡で表す右図のような方法も提案しています。

色見本

私がよく使うのは紺(#0068b7)からオレンジ(#f39800)にかけての色です。オレンジはRGBのうち赤と緑を含み,紺は青を多く含むので,赤または緑の感受性を持たない人にも見分けやすいというわけです。

display.brewer.all() の出力

より現代的な色の選択を提案するサイトとして,Colorbrewer: Color Advice for Maps があります。RのパッケージRColorBrewerも開発されています。右図はRColorBrewerパッケージのサンプル

display.brewer.all()

の出力です。3段に分かれています。上のグループは順次的(sequential)と呼ばれるもので,小さい量から大きい量までの段階を表すのに使われます。真ん中のグループは定性的(qualitative)と呼ばれるもので,大小関係のないカテゴリー(名義尺度)を表すのに使われます。下のグループは発散的(diverging)と呼ばれるもので,正負の両側に延びる量を表すのに使われます。

例えばこの中のDark2というものに興味があれば,

display.brewer.pal(8, "Dark2")

でこの8色だけサンプル出力します。実際の色を取り出すには,例えば

cols = brewer.pal(8, "Dark2")

とすれば cols[1] から cols[8] までに色が入ります。

自前でこのようなパレットを作るには colorRampPalette() 関数を使います。

# png("110905d.png", 450, 80)
# par(mar=c(0,0,0,0))
cols = colorRampPalette(c("#0068b7","white","#f39800"))
plot(NULL, xlim=c(0,10), ylim=c(0,1),
     axes=FALSE, xlab="", ylab="")
rect(0:9, 0, 1:10, 1, col=cols(10))
# dev.off()
colorRampPalette() の例

連続色

0から1までの実数に色を対応させる関数を作るには,例えば次のようにします。

cols = colorRamp(c("#0080ff","white","#ff8000"))

これで cols(0)#0080ffcols(1)#ff8000 に対応するような0〜255の三つ組を返す関数 cols() が生成されます。これを使って何か描いてみましょう。

# png("110905b.png", 450, 80)
# par(mar=c(0,0,0,0))
plot(NULL, xlim=c(0,100), ylim=c(0,1), axes=FALSE, xlab="", ylab="")
rect(0:99, 0, 1:100, 1, col=rgb(cols(0:99/99)/255), border=NA)
# dev.off()
連続色の例1

colorRamp() にいろいろな色を与えてやってみてください。例:

cols = colorRamp(c("#004080","#0080ff","white","#ff8000","#804000"))
連続色の例2

(追記)corrplot パッケージのデフォルト色がオレンジ(負)〜紺(正)であることに気づきました:

colorRampPalette(c("#67001F", "#B2182B", "#D6604D", "#F4A582", "#FDDBC7",
                   "#FFFFFF", "#D1E5F0", "#92C5DE", "#4393C3", "#2166AC", "#053061"))
corrplotのデフォルト色

カラーユニバーサルデザインについて

色覚バリアフリーまたはカラーユニバーサルデザインの考え方について少し補足しておきます。

まず必要なことは,自分以外の色覚の人がどのように見えるかを把握することです。CS4以降のAdobe PhotoshopやAdobe IllustratorにはP型・D型の見え方に変換する機能があります。Adobe Photoshop CS5の場合,「表示」→「校正設定」→「P型(1型)色覚」または「D型(2型)色覚」を選びます(CS4では「表示」が「ビュー」になります)。

Adobe Photoshop CS5の色覚校正

例えば福島県放射能測定マップの色分けは次のようになっています:

福島県放射能測定マップの色分け

これをPhotoshop CS5で「D型(2型)色覚」にしてみます:

福島県放射能測定マップの色分け・D型色覚

緑とオレンジが同じような色になってしまうことがわかります。そうでなくてもこの色分けは明るい色(黄)を中心に両側に暗い色があるので,これでマップを作ると明るい色の輪に見えてしまうことが,下に挙げた“Escaping RGBland”論文でも指摘されています。正の値が大きいか小さいかを表すにはsequentialな色分けが適当ですが,その前に一つ予備知識。

Rでカラーユニバーサルデザインの考え方に基づいて作られたパッケージに dichromat があります。

dichromatパッケージの例
library(dichromat)
# png("dichromat.png", 400, 200)
# par(mar=c(0,0,0,0))
plot(NULL, xlim=c(0,12), ylim=c(0,2),
     axes=FALSE, xlab="", ylab="")
rect(0:11, 1.1, 1:12, 2, col=colorschemes$Categorical.12)
rect(0:11, 0, 1:12, 0.9, col=dichromat(colorschemes$Categorical.12))
# dev.off()

colorschemes$Categorical.12 は12色のカテゴリカル用の色です。このパッケージに含まれる色に限らず,どんな色でも dichromat() 関数を通せば色覚を変化させることができます(オプション type="deutan"type="protan" が指定できます。デフォルトは前者)。

そこで,先ほどの福島県放射能測定マップの色分けですが,色そのものはRColorBrewerの適当なsequentialな色分けを使うのでよいと思います。dichromat() 関数でD型色覚の見え方も調べてみましょう。

RColorBrewerのYlOrBrの8色とD型色覚
# library(RColorBrewer)
# library(dichromat)
# png("110922c.png", 400, 200)
# par(mar=c(0,0,0,0))
cols = brewer.pal(8, "YlOrBr")
plot(NULL, xlim=c(0,8), ylim=c(0,2),
     axes=FALSE, xlab="", ylab="")
rect(0:7, 1.1, 1:8, 2, col=cols)
rect(0:7, 0, 1:8, 0.9, col=dichromat(cols))
# dev.off()

もっとも,これはグレースケールだけで判別できるので,調べるまでもなかったのですが。

RGBをグレースケールに変換する一番簡単な式は 0.3r + 0.59g + 0.11b です。これとdichromatパッケージを使ってD型・P型・グレイスケールへの変換結果を表示するには次のようにすればいいでしょう。

library(dichromat)

rgb2gray = function(col) {
  m = matrix(c(rep(0.3,3),rep(0.59,3),rep(0.11,3)), nrow=3)
  rgb(t((m/255) %*% col2rgb(col)))
}

rects = function(col) {
  n = length(col)
  oldpar = par(mar=c(0,0,0,0))
  plot(NULL, xlim=c(0,n), ylim=c(0,4.6), axes=FALSE, xlab="", ylab="")
  rect(0:(n-1), 3.6, 1:n, 4.6, col=col)
  rect(0:(n-1), 2.4, 1:n, 3.4, col=dichromat(col,type="deutan"))
  rect(0:(n-1), 1.2, 1:n, 2.2, col=dichromat(col,type="protan"))
  rect(0:(n-1), 0.0, 1:n, 1.0, col=rgb2gray(col))
  par(oldpar)
}

最後に,カラーユニバーサルデザイン推奨配色セットにあるアクセントカラー・ベースカラー・無彩色の #rrggbb 値を載せておきます。

      #ff2800
      黄色#faf500
      #35a16b
      #0041ff
      空色#66ccff
      ピンク#ff99a0
      オレンジ#ff9900
      #9a0079
      #663300
      明るいピンク#ffd1d1
      クリーム#ffff99
      明るい黄緑#cbf266
      明るい空色#b4ebfa
      ベージュ#edc58f
      明るい緑#87e7b0
      明るい紫#c7b2de
      #ffffff
      明るいグレー#c8c8cb
      グレー#7f878f
      #000000

参考文献・サイト


Last modified: