2016-05-19 6 views
4

ggplot2で点の密度に基づいて変化するアルファベットを持つgeom_ribbon(または他の領域ベースのgeom)を生成する方法はありますか?ggplot2:各xのy軸に沿ったデータ密度に依存するalphaを持つgeom_ribbon

次のコードは、各サンプルに対してランダムなx値を持つ50のノイズの多い正弦波を生成します。私は何千ものリサイズが必要なので、すべての点を描きたくないので、これらの点をすべて要約したいと思います。

簡単な方法は、95%分位数をカバーするgeom_ribbonを描画することです。しかし、最初に、各リサンプルについてx値が同じでない場合には、これを計算するのは簡単ではありません。通常は、100 xの各点でポイントごとの分位数を計算します。

代わりに、サンプルが配置されている領域全体をカバーするリボンを、連続的なアルファグラデーション、つまりリボンが実際の線の近くで最も暗く、外れ点で非常に明るいようにしたいとします。これはggplot2で可能ですか?

library(ggplot2) 

num_points = 100 
num_samples = 50 

x = seq(0, 4*pi, length.out=num_points) 

sim <- lapply(1:num_samples, function(f) { 
    x = runif(num_points, 0, 4*pi) 
    y = sin(x) + rnorm(num_points, 0, 0.4) 
    data.frame(x=x, y=y) 
}) 

sim.df <- do.call(rbind, sim) 
actual = data.frame(x=x, y=sin(x)) 

ggplot(sim.df, aes(x=x, y=y)) + 
    geom_point(alpha=0.7) + 
    geom_line(data=actual, colour='blue', size=1.5) 

Plot of noisy sinewaves

答えて

8

一つのオプション各x値における各変位値のためのy値を取得し、geom_ribbonを用いたものをプロットする分位回帰を使用することです。密度リボン用

library(splines) 
library(quantreg) 
library(reshape2) 
library(dplyr) 
  1. セット分位:

    nq = 50 # Numbre of quantiles 
    qq = seq(0,1, length.out=nq) 
    
  2. 各分位の分位回帰を実行します。密度分位数をプロットするgeom_ribbonで使用するためのデータフレームを作成します

    m1 = rq(y ~ ns(x,10), data=sim.df, tau=qq) 
    
  3. :私は、正弦関数への良好なフィット感を得るために柔軟なスプライン関数を使用しました。

    predictを用いて回帰分位数予測のデータフレームを作成する:各分位の予測一分位数のためymaxと連続して次の分位数のためymin(と同様に働くよう

    xvals = seq(min(sim.df$x), max(sim.df$x), length.out=100) 
    rqs = data.frame(x=xvals, predict(m1, newdata=data.frame(x=xvals))) 
    names(rqs) = c("x", paste0("p",100*qq)) 
    

    データをリシェイプ最初の分位数が最初のyminとして1回だけ使用され、最後の分位数が最後の1回分としてymaxとして機能するという例外があります。今プロットを

    dat1 = rqs[, -length(rqs)] 
    names(dat1)[-1] = paste0(names(dat1)[-1]) 
    dat2 = rqs[, -2] 
    names(dat2)[-1] = paste0(names(dat1)[-1]) 
    
    dat1 = melt(dat1, id.var="x") 
    names(dat1) = c("x","group","min") 
    dat2 = melt(dat2, id.var="x") 
    names(dat2) = c("x","group1","max") 
    
    dat = bind_cols(dat1, dat2) 
    
  4. 作成します。私たちはggplotにおける分位でグループをできるように、長い形式のデータを入れてください。分位数をalphaにマッピングし、次にscale_alpha_manualを使用して、0に近い分数値のアルファ値を高く設定します。近くに0と1の位数は5と下位:

    sim <- lapply(1:num_samples, function(f) { 
        x = runif(num_points, 0, 4*pi) 
        y = sin(x) + rnorm(num_points, 0, abs(0.7*cos(x))+0.1) 
        data.frame(x=x, y=y) 
    }) 
    
    sim.df <- do.call(rbind, sim) 
    

    今だけ実行します。

    ggplot() + 
        geom_point(data=sim.df, aes(x,y), alpha=0.1, size=0.5, colour="red") + 
        geom_ribbon(data=dat, aes(x=x, ymin=min, ymax=max, group=group, alpha=group), 
          fill="blue", lwd=0, show.legend=FALSE) + 
        theme_bw() + 
        scale_alpha_manual(values=c(seq(0.05,0.9,length.out=floor(0.5*length(qq))), 
               seq(0.9,0.05,length.out=floor(0.5*length(qq))))) 
    

enter image description here

ここでは別の例ですが、様々な標準偏差を持つデータとこのプロットを得るために前に作成したコードのすべて:

enter image description here

+0

完璧、ありがとう。大規模なデータセットを使用している場合は、geom_ribbon呼び出しでalpha = sort(group)を設定する必要があります。それ以外の場合は、グループ59が591から次に分位すると考えられます。 –

関連する問題