2013-04-06 5 views
7

各バーの中心が共通軸に沿っているヒストグラムを作成するにはどうすればよいですか?これは、ステップ状のエッジを持つバイオリンプロットのように見えます。対称的な、バイオリンのようなプロットのようなヒストグラム?

私はこれをLatticeで行いたいと思いますし、パネル機能のカスタマイズなどは気にしませんが、基盤のRグラフィックスやggplot2を使ってもうれしいです。 (まだ私はggplot2に投げ込まれていませんが、ある時点で急降下します)

(私はこれをしたいのですがなぜですか?データが離散的である場合には、もちろん、私は通常のヒストグラムを生成することができますが、時にはボックスとウィスカーの両方を表示すると便利なことがあると思いますプロットとバイオリンプロットとの間には、一定の間隔で離散データが存在するため、ボックスプロットと同じ向きの対称ヒストグラムでは、バイオリンプロットと同様に、データの詳細構造をボックスプロットと比較することができます。 (私の説明したもののもう一つの選択肢かもしれませんが、実際には私のデータは文字通り離散ではありません - それはちょうどシリーズの近くに収束します定期的な値の。 )

ここでは、一部のデータの30の観測サブセットがあります。このサブセットの一部は、エージェントベースのアプリケーションによって生成されたものですが、ベースのシミュレーション:CVexample.rdata

df30 <- data.frame(crime.v=c(0.2069526, 0.2063516, 0.06919754, 
0.2080366, -0.06975912, 0.206277, 0.3457634, 0.2058985, 0.3428499, 
0.3428159, 0.06746109, -0.07068694, 0.4826098, -0.06910966, 0.06769761, 
0.2098732, 0.3482267, 0.3483602, 0.4829777, 0.06844112, 0.2093492, 
0.4845478, 0.2093505, 0.3482845, 0.3459249, 0.2106339, 0.2098397, 
0.4844956, 0.2108985, 0.2107984), bias=c("beast", "beast", "beast", 
"beast", "beast", "beast", "beast", "beast", "beast", "beast", "beast", 
"beast", "beast", "beast", "beast", "virus", "virus", "virus", "virus", 
"virus", "virus", "virus", "virus", "virus", "virus", "virus", "virus", 
"virus", "virus", "virus")) 

RDATAファイル内の600回の観測のフルセットでdfという名前のデータフレームは、このリンクからダウンロードすることができます。

crime.v値は、私が焦点と呼ぶことにしますこれは、すべて次のいずれかの近くにある:

[1] -0.89115386 -0.75346155 -0.61576924 -0.47807693 -0.34038463 -0.20269232 -0.06500001 
[8] 0.07269230 0.21038460 0.34807691 0.48576922 0.62346153 0.76115383 0.89884614 

crime.v値は、実際の値から-1 1の範囲とすることができる13個の変数の平均値であります9,9付近の13の値の平均は、焦点の近くにある。実際には、焦点の適切な値を決定することによって、データが含まれています)。

バイオリンプロットは、

require(lattice) 
bwplot(crime.v ~ bias, data=df30, ylim=c(-1,1), panel=panel.violin) 

これを大きなデータセットで実行すると、生成されたバイオリンプロットの1つがマルチモーダルであり、もう1つはマルチモーダルではないことがわかります。しかし、これは2つのバイオリンプロットの根底にあるデータの違いを反映していないようです。私が知る限り、プロットに関連してフォーカスの位置に起因するアーティファクトです。私は、panel.violinに渡されたdensityのパラメータを微調整することで違いを滑らかにすることができますが、各クラスタにいくつのポイントがあるのか​​を表すだけで分かります。

ありがとうございます!ここで

+0

あなたのニーズに合わせて操作してみましたか? http://docs.ggplot2.org/0.9.3/geom_violin.html –

+0

いいえ、非常に有益なページに感謝します。私はそれを試みるかもしれない。 (格子の批判ではないggplotのドキュメントは、いくつかの点で格子文書よりも使いやすいと思われます) – Mars

+0

この場合、サンプルデータは本当に便利です。非常に興味深いと思うので。 – Henrik

答えて

7

は、ベースのグラフィックスを使用して一つの可能​​性は次のとおりです。

tmp <- tapply(iris$Petal.Length, iris$Species, function(x) hist(x, plot=FALSE)) 

plot.new() 
tmp.r <- do.call(range, lapply(tmp, `[[`, 'breaks')) 
plot.window(xlim=c(1/2,length(tmp)+1/2), ylim=tmp.r) 
abline(v=seq_along(tmp)) 

for(i in seq_along(tmp)) { 
    h <- tmp[[i]] 
    rf <- h$counts/sum(h$counts) 
    rect(i-rf/2, head(h$breaks, -1), i+rf/2, tail(h$breaks, -1)) 
} 

axis(1, at=seq_along(tmp), labels=names(tmp)) 
axis(2) 
box() 

あなたがあなたの好みと簡単に機能にラップすることができ、全体のことに異なる部分を微調整することができます。

+0

うわー。美しい、グレッグ。パッケージ全体をまとめていただきありがとうございます。 (グレッグの答えを素早く見ている人にとっては、forループの中に長方形を作ることが重要です。 – Mars

+0

同じ基本的な考え方を使って、同様のプロットを 'panel.rect'ラティスで – Mars

+0

私は今まで、系統的な方法でベースグラフィックからいくつかの格子効果を得る方法を知らなかった。有難うございます。 – Mars

5

ここには、ベースグラフィックを使った@ GregSnowの答えに基づく格子パネル関数があります。私はグレッグが確かな出発点を提供していなければそれをすることができなかったので、すべてのクレジットはグレッグに行きます。私のパネル機能はあまり洗練されておらず、単純なものを非常にうまく打ち破ることができますが、水平方向と垂直方向を扱い、ブレークベクトルを供給するか、そのまま放置することができます。空の端のビンも取り除きます。パネル関数は、の代わりにbreakshistのデフォルトの動作を使用します。これはより複雑です。より良い方法についてのコメントは大歓迎です。

ヒストグラムには、わかっている限り、既存の名前がなく、ハノイ塔の塔を連想させるので、おそらく「ハノイ塔のヒストグラムの塔」と呼ぶべきです。したがって、関数はpanel.hanoiと呼ばれます。上記DF30の定義を使用して

簡単な使用例:ここでは

bwplot(crime.v ~ bias, data=df30, panel=panel.hanoi) 

は(答えの終わりにグラフィック)問題のリンクで提供されたデータを使用して、より複雑な例です。

bwplot(crime.v ~ bias, data=df, ylim=c(-1,1), pch="|", coef=0, panel=function(...){panel.hanoi(col="pink", breaks=cv.ints, ...); panel.bwplot(...)}) 

この例は、プロットは-1から1まで行く必要があることを指定するには、ylimを追加し、ハノイプロットの上にbwplotをオーバーレイ。 pchおよびcoefは、bwplotの外観に影響します。例では、私のデータポイントは、(元の質問を参照)にあるように傾向がある場所を中心にハノイプロットの各ボックスを中央に次の定義を使用しています。ここでは

cv.ints <- c(-1.000000000, -0.960000012, -0.822307704, -0.684615396, -0.546923088, -0.409230781, -0.271538473, -0.133846165, 0.003846142, 0.141538450, 0.279230758, 0.416923065, 0.554615373, 0.692307681, 0.829999988, 0.967692296, 1.000000000) 

は、パネル機能である:

panel.hanoi <- function(x, y, horizontal, breaks="Sturges", ...) { # "Sturges" is hist()'s default 

    if (horizontal) { 
    condvar <- y # conditioning ("independent") variable 
    datavar <- x # data ("dependent") variable 
    } else { 
    condvar <- x 
    datavar <- y 
    } 

    conds <- sort(unique(condvar)) 

    # loop through the possible values of the conditioning variable 
    for (i in seq_along(conds)) { 

     h <- hist(datavar[condvar == conds[i]], plot=F, breaks) # use base hist(ogram) function to extract some information 

    # strip outer counts == 0, and corresponding bins 
    brks.cnts <- stripOuterZeros(h$breaks, h$counts) 
    brks <- brks.cnts[[1]] 
    cnts <- brks.cnts[[2]] 

    halfrelfs <- (cnts/sum(cnts))/2 # i.e. half of the relative frequency 
    center <- i 

    # All of the variables passed to panel.rec will usually be vectors, and panel.rect will therefore make multiple rectangles. 
    if (horizontal) { 
     panel.rect(head(brks, -1), center - halfrelfs, tail(brks, -1), center + halfrelfs, ...) 
    } else { 
     panel.rect(center - halfrelfs, head(brks, -1), center + halfrelfs, tail(brks, -1), ...) 
    } 
    } 
} 

# function to strip counts that are all zero on ends of data, along with the corresponding breaks 
stripOuterZeros <- function(brks, cnts) { do.call("stripLeftZeros", stripRightZeros(brks, cnts)) } 

stripLeftZeros <- function(brks, cnts) { 
    if (cnts[1] == 0) { 
    stripLeftZeros(brks[-1], cnts[-1]) 
    } else { 
    list(brks, cnts) 
    } 
} 

stripRightZeros <- function(brks, cnts) { 
    len <- length(cnts) 
    if (cnts[len] ==0) { 
    stripRightZeros(brks[-(len+1)], cnts[-len]) 
    } else { 
    list(brks, cnts) 
    } 
} 

Tower of Hanoi histograms with overlaid bwplots

+0

スクリプトから画像を複製できない場合は、すべてが正しいかどうか再確認できます。図は非常に興味深く見えます。私はいくつかのデータを試してみて、画像がどれほど有用かを見てみたいと思います。スクリプトを修正し、いくつかのステップを追加して有用なものにすることができますか? (上記のデータのスクリプトをコピーすると、パケット1を使用してエラーが "butlast"という関数を見つけられなかったというエラーメッセージが表示されます)。 – bala

+0

これで修正されました。私は別の場所で定義した2つのユーティリティ関数、 '' butlast''と 'butfirst'を' head'と 'tail'の定義で置き換えました。すみません、ごめんなさい。また、最初の例を少し修正し、2番目のより複雑な例がどのように機能するかを明確にするためにコメントを追加しました。 – Mars

+0

これをggplot geomにすることはできますか? – thc

関連する問題