グラフィックス参考実例集:棒グラフ、ヒストグラムを描く barplot, hist

(グラフィックス参考実例集に戻る。Rのグラフィックスパラメータを参照する。)


単純な棒グラフ

barplot 関数は棒グラフを描きます。棒グラフは、棒の長さにより観測値の大きさや度数を表すものです。数値ベクトルを引数として与えるのが、関数barplotもっとも簡単な使い方です。こうするとベクトルのそれぞれの値が棒の高さになります。 引数が行列ならば各列が一本の棒となり、列の各要素の値により棒をブロックに分けます。

似たものにヒストグラムを描く hist 関数がある。見かけは似ているが、棒グラフが類別・尺度(カテゴリー化された)データを扱うのにたいし、hist は間隔・比率尺度(本来の数値)データを適当な区間毎に集計したものを棒グラフ状に表示する。

注意。base パッケージ中の barplot 関数 (hist も?) は対数y軸をサポートしていない。また par(ylog=TRUE) による指定も無効にされる。アドオンパッケージ gregmisc 中には両対数軸をサポートする barplot 関数があるらしい。

とりあえず書いてみる

barplot01 <- function(){
  on.exit(par(old.par <- par(no.readonly = TRUE)))
  on.exit(dev.off())
  png("barplot01.png")
  d <- ceiling(runif(5, 1, 10))	# サンプルデータ
  barplot(d)
}
barplot01()
r_case03_barplot01.png

x軸に名前を表示して、棒の色を変更する

barplot03 <- function(){
  on.exit(par(old.par <- par(no.readonly = TRUE)))
  on.exit(dev.off())
  png("barplot03.png")
  d <- ceiling(runif(5, 1, 10))
  d.names <- paste("gene", 1:5)   # x軸に表示される名前を作る
  barplot(d, names.arg=d.names, col=c("blue", "green", "red", "yellow", "cyan"))
}
barplot03()
r_case03_barplot03.png

誤差範囲を表示する

棒グラフの棒の幅は1になっています(barplotのwidth引数)。棒と棒の間隔は標準で0.2になっています(barplotのspace引数)。この状態で左からn番目の棒の中心は(0.2 + 1) * n - 1/2になっています。ここからarrows関数で矢印を引っぱると誤差範囲が表示できます。
arrowsのangleは矢印の傾きを指定します。今回は直角になるように90にしてあります。

barplot04 <- function(){
  on.exit(par(old.par <- par(no.readonly = TRUE)))
  on.exit(dev.off())
  png("barplot04.png")
  d <- ceiling(runif(5, 1, 10))
  d.names <- paste("gene", 1:5)
  d.error <- runif(5, 0, 1)   # 誤差範囲のデータ
  d.error.x <- (0.2 + 1) * 1:5 - 1/2   # エラーバーを表示する位置(x座標)
  barplot(d, names.arg=d.names, col=c("blue", "green", "red", "yellow", "cyan"))
  arrows(d.error.x, d, d.error.x, d + d.error, angle=90)
  arrows(d.error.x, d, d.error.x, d - d.error, angle=90)
}
barplot04()
r_case03_barplot04.png

別の方法:関数barplotは各棒グラフの中点座標の配列を返すので,誤差範囲を表示するためにこれを利用できます.

barplot04b <- function(){
  on.exit(par(old.par <- par(no.readonly = TRUE)))
  on.exit(dev.off())
  png("barplot04b.png")
  d <- ceiling(runif(5, 1, 10))
  d.names <- paste("gene", 1:5)
  d.error <- runif(5, 0, 1)   # 誤差範囲のデータ
  # 各棒グラフの中点座標を取得
  d.error.x <- barplot(d, names.arg=d.names, col=c("blue", "green", "red", "yellow", "cyan"))
  arrows(d.error.x, d, d.error.x, d + d.error, angle=90)
  arrows(d.error.x, d, d.error.x, d - d.error, angle=90)
}
barplot04b()

積み重ねの棒グラフ

まずは書いてみる

barplot05 <- function(){
  on.exit(par(old.par <- par(no.readonly = TRUE)))
  on.exit(dev.off())
  png("barplot05.png")
  dm <- matrix(ceiling(runif(12, 1, 10)), ncol=3)	# サンプルデータ
  barplot(dm)
}
barplot05()
r_case03_barplot05.png

棒グラフの間に線を引く

棒グラフの間の線はsegments関数で引きます。segmentsには線分の始点と終点を与えないといけないのでまずそれを計算します。

barplot06 <- function(){
  on.exit(par(old.par <- par(no.readonly = TRUE)))
  on.exit(dev.off())
  png("barplot06.png")
  dm <- matrix(ceiling(runif(12, 1, 10)), ncol=3)
  d.seg.xs <- rep((0.2 + 1) * 1:(ncol(dm) - 1), each=nrow(dm))   # 線分の始点のx座標
  d.seg.xe <- rep((0.2 + 1) * 2:ncol(dm) - 1, each=nrow(dm))     # 線分の終点のx座標
  d.seg.ys <- apply(dm[,1:(ncol(dm) - 1)], 2, cumsum)            # 線分の始点のy座標
  d.seg.ye <- apply(dm[,2:ncol(dm)], 2, cumsum)                  # 線分の終点のy座標
  barplot(dm)
  segments(d.seg.xs, d.seg.ys, d.seg.xe, d.seg.ye)   # 線分を描く
}
barplot06()
r_case03_barplot06.png

凡例を表示する

barplot07 <- function(){
  on.exit(par(old.par <- par(no.readonly = TRUE)))
  on.exit(dev.off())
  png("barplot07.png")
  dm <- matrix(ceiling(runif(12, 1, 10)), ncol=3)
  d.seg.xs <- rep((0.2 + 1) * 1:(ncol(dm) - 1), each=nrow(dm))
  d.seg.xe <- rep((0.2 + 1) * 2:ncol(dm) - 1, each=nrow(dm))
  d.seg.ys <- apply(dm[,1:(ncol(dm) - 1)], 2, cumsum)
  d.seg.ye <- apply(dm[,2:ncol(dm)], 2, cumsum)
  d.names.r <- paste("exp", 1:nrow(dm))    # 凡例に表示する文字列
  d.names.c<-paste("gene",1:ncol(dm))   # 棒グラフのグループごとの名前
  barplot(dm, names.arg=d.names.c, legend.text=d.names.r)
  segments(d.seg.xs, d.seg.ys, d.seg.xe, d.seg.ye)
}
barplot07()
r_case03_barplot07.png

横に並べた棒グラフ

まずは書いてみる

barplot08 <- function(){
  on.exit(par(old.par <- par(no.readonly = TRUE)))
  on.exit(dev.off())
  png("barplot08.png")
  dm <- matrix(ceiling(runif(12, 1, 10)), ncol=3)	# サンプルデータ
  barplot(dm, beside=T)
}
barplot08()
r_case03_barplot08.png

白黒印刷用に図を書く

barplot09 <- function(){
  on.exit(par(old.par <- par(no.readonly = TRUE)))
  on.exit(dev.off())
  png("barplot09.png")
  dm <- matrix(ceiling(runif(12, 1, 10)), ncol=3)
  d.names.r <- paste("exp", 1:nrow(dm))
  d.names.c<-paste("gene",1:ncol(dm))
  d.angle <- c(20,-20) * 1:nrow(dm)
  barplot(dm, beside=T, angle=d.angle, density=10, col="black",
          names.arg=d.names.c, legend.text=d.names.r)
}
barplot09()
r_case03_barplot09.png

誤差範囲を表示する

標準では棒の幅1、グループ内の棒の間隔0、グループの間隔1で作成されています。このときm番目のグループのn番目の棒(d[n,m]に相当)の中心は(1+1*N)*(m-1)+1*n+1/2になります(ああ、ややこしい)。
arrowsのlengthは矢印の矢じりの部分の長さを指定します。棒の数が多い場合はこの値を小さくしないときれいな図になりません(標準で0.25)。

barplot10 <- function(){
  on.exit(par(old.par <- par(no.readonly = TRUE)))
  on.exit(dev.off())
  png("barplot10.png")
  dm <- matrix(ceiling(runif(12, 1, 10)), ncol=3)
  d.names.r <- paste("exp", 1:nrow(dm))
  d.names.c<-paste("gene",1:ncol(dm))
  dm.error <- runif(length(dm), 0,1)
  dm.error.x <- rep((nrow(dm)+1) * (1:ncol(dm) - 1), each = nrow(dm))	# (1+1*N)*(m-1)まで
  dm.error.x <- dm.error.x + rep(1:nrow(dm) + 1/2, ncol(dm))	# +1*n+1/2 の部分
  barplot(dm, ylim=c(0, max(dm + dm.error)), beside=T, names.arg=d.names.c,
          legend.text=d.names.r)
  arrows(d.error.x, dm, d.error.x, dm + dm.error, angle=90, length=0.1)
  arrows(d.error.x, dm, d.error.x, dm - dm.error, angle=90, length=0.1)
}
barplot10()
r_case03_barplot10.png

別の方法:関数barplotは各棒グラフの中点座標の配列を返すので,誤差範囲を表示するためにこれを利用できます.

barplot10 <- function(){
  on.exit(par(old.par <- par(no.readonly = TRUE)))
  on.exit(dev.off())
  png("barplot10.png")
  dm <- matrix(ceiling(runif(12, 1, 10)), ncol=3)
  d.names.r <- paste("exp", 1:nrow(dm))
  d.names.c<-paste("gene",1:ncol(dm))
  dm.error <- runif(length(dm), 0,1)
 # 各棒グラフの中点座標を取得
  dm.error.x <-   barplot(dm, ylim=c(0, max(dm + dm.error)), beside=T, names.arg=d.names.c,
               legend.text=d.names.r)
  arrows(dm.error.x, dm, dm.error.x, dm + dm.error, angle=90, length=0.1)
  arrows(dm.error.x, dm, dm.error.x, dm - dm.error, angle=90, length=0.1)
}
barplot10()

ヒストグラム

 ヒストグラムにより、データの分布の仕方を大雑把に知ることができます。このグラフは関数histで描きます。引数には数値ベクトルを指定します。他に細かなことを設定する引数がいくつかありますが、基本的にはこの引数を指定するだけでヒストグラムを描くことができます。例えば、

> hist(rnorm(100))

で、ヒストグラムが描かれます。 特に何も指定せずデータのみを与えた場合は、データの範囲を log2n + 1 ( n はデータの個数)個の階級に分割し、各階級に属すデータの数を棒グラフとして作図します。通常は絶対度数を使いますが、probability=Tと指定することによって相対度数で作図することもできます。また、引数nclassで階級数を明示的に指定することもできます。

例1 example(hist.default) 中の例 (2003.12.7)

histmisc1 <- function() {
    data(islands)
    op <- par(mfrow=c(2, 2))
    hist(islands)
    str(hist(islands, col="gray", labels = TRUE))

    hist(sqrt(islands), br = 12, col="lightblue", border="pink")
    ##-- For non-equidistant breaks, counts should NOT be graphed unscaled:
    r <- hist(sqrt(islands), br = c(4*0:5, 10*3:5, 70, 100, 140), col='blue1')
    text(r$mids, r$density, r$counts, adj=c(.5, -.5), col='blue3')
    sapply(r[2:3], sum)
    sum(r$density * diff(r$breaks)) # == 1
    lines(r, lty = 3, border = "purple") # -> lines.histogram(*)
    par(op)
}
 left

例2 ヒストグラムの色々 (2003.12.10)

既定の Sturges の方法は単に伝統があり、有名と言うだけで実際は使わない方が良さそう。 Q&Aコーナーの関連質問参照。

> x <- rnorm(1000)^2
> hist(x)                               
> hist(x, breaks="Sturges")  # 既定の hist(x) と同一 (古典的な Sturges の方法による分割点決定)
> hist(x, breaks="scott")      # Scott の方法による分割点決定
> hist(x, breaks="FD")          # Frieman-Daiconis の方法による分割点決定
 left

棒グラフの枠線を消す(本体色と同じ色の枠線を描く 2004.01.14)

ついでに棒の間の隙間を色々変えてみる。

> par(mfrow=c(2,2))
> barplot(1:5, space=0, col="red", border="red")
> barplot(1:5, space=0.1, col="red", border="red")
> barplot(1:5, space=0.5, col="red", border="red")
> barplot(1:5, space=1, col="red", border="red")
> pp=recordPlot(); png("histnoborder.png"); replayPlot(pp); dev.off()
 left

この例では塗りつぶしと枠を同じ色にすることで解決しているが、 そもそも枠を描きたくないという場合はオプションで「border=NA」を指定する。hist()でも同じ。

MASS ライブラリ中の truehist は基準化相対度数でヒストグラムを描く (2004.3.2)

truehist は総面積が1となるヒストグラム(度数を区間幅で割る)を書く

library(MASS)
data(islands)
par(mfrow=c(1,2))
hist(islands)
truehist(islands)
 left

各棒の面積が等しくなるヒストグラム (from r-help, 2005.01.10)

quantile 関数を用い各棒の面積(標本確率)が等しくなるように分割点を定める

x <- rnorm(400)
nbin <- 10          # 区間の数を10にする
hist(x,breaks=quantile(x,prob=seq(0,1,length=nbin+1)))
 left

添付ファイル: filehistnoborder.png 3520件 [詳細] filehistgram2.png 3499件 [詳細] filehist.equalarea.png 3537件 [詳細] filetruehist.jpg 3513件 [詳細] filer_case03_barplot02.png 1541件 [詳細] filer_case03_barplot08.png 4369件 [詳細] filer_case03_barplot06.png 3609件 [詳細] filer_case03_barplot03.png 6286件 [詳細] filer_case03_barplot04.png 3989件 [詳細] filer_case03_barplot01.png 4815件 [詳細] filer_case03_barplot07.png 4464件 [詳細] filehistmisc1.png 3631件 [詳細] filebad.png 3283件 [詳細] filer_case03_barplot05.png 4117件 [詳細] filer_case03_barplot09.png 4172件 [詳細] filer_case03_barplot10.png 4899件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2023-03-25 (土) 11:19:17