2011-07-23 15 views
6

私は1:1以下の線に拘束されているデータがあります。私は、線の下の領域にビューアの注意を引くために、線の上の領域を軽く陰影付けすることによってプロット上でこれを実証するだろう。ggplot2 - 線の上の陰影領域

私はqplotを使ってグラフを生成しています。すばやく、私は持っている。

qplot(x,y)+geom_abline(slope=1)

が、私の人生のために、どのように別のオブジェクトをプロットすることなく、日陰の上の領域を簡単に把握することはできません。これは簡単に修正できますか?

[OK]を


EDIT、Joranは、ここでの例のデータセットは次のとおりです。

df=data.frame(x=runif(6,-2,2),y=runif(6,-2,2), 
    var1=rep(c("A","B"),3),var2=rep(c("C","D"),3)) 
df_poly=data.frame(x=c(-Inf, Inf, -Inf),y=c(-Inf, Inf, Inf)) 

、ここでは、私はそれをプロットするために使用しているコードです(私はあなたのアドバイスを取りました検索していますggplot()):

ggplot(df,aes(x,y,color=var1))+ 
facet_wrap(~var2)+ 
geom_abline(slope=1,intercept=0,lwd=0.5)+ 
geom_point(size=3)+ 
scale_color_manual(values=c("red","blue"))+ 
geom_polygon(data=df_poly,aes(x,y),fill="blue",alpha=0.2) 

エラーrは戻ってキックバックされます: "オブジェクト 'var1'が見つかりません"何かは、私が間違って引数を実装していると私に伝えます...

+0

着色点及び充填多角形が2つの異なる美観(色、塗りつぶし)によって処理し、競合しないはずさを私はあなたが何か間違ったことをしている可能性があると考えています。もう少しお手伝いしたいと思いますが、プロットしようとしているデータの具体的な再現可能な例がなければ、私はできません。 – joran

+0

完了。私はggplot2がそのようなことをどのように処理しているのか不慣れであることが原因であると考えています。もう一度お世話になりました。とても感謝しています。 – jslefche

+0

'color = var1'を' geom_point'に移動します: 'geom_point(aes(color = var1)、...)'。また、各ファセットに異なる塗りつぶしポリゴンが必要な場合は、ファセットごとに個別のデータフレームを作成し、それらを 'var2'ファクタを含む単一のデータフレームに結合する必要があるので、 'ggplot'は、各ファセットに適用されます。 – joran

答えて

11

は、ほとんどの場合、指定した行の上または下に陰影を処理します(ただし、完全に)、より一般的なソリューションです。

@Andrieがhereを参照した方法を使用しませんでした。なぜなら、ggplotの問題は、エッジの近くにポイントを追加すると自動的にプロットエクステントを拡張する傾向にあったからです。代わりに、必要に応じてInf-Infを使用して手動でポリゴンポイントを作成します。いくつかの注意事項:

  • ggplotポイントが表示される順序でポリゴンを描画するのでポイントは、データフレームに「正しい」順序でなければなりません。したがって、ポリゴンの頂点を取得するだけでは不十分です。それらを順番に(時計回りまたは反時計回りに)並べる必要があります。

  • この解決策では、プロットしているライン自体がプロット範囲を延長することはないと仮定します。ggplot私の例では、データ内の2つの点をランダムに選んで線を引いて線を引くことがわかります。残りの点から線をあまりにも遠くに描画しようとすると、ggplotは自動的にプロットの範囲を変更し、それらがどのようになるかを予測することが難しくなります。

まず、ここではポリゴンデータフレームを構築する機能があります:

buildPoly <- function(xr, yr, slope = 1, intercept = 0, above = TRUE){ 
    #Assumes ggplot default of expand = c(0.05,0) 
    xrTru <- xr + 0.05*diff(xr)*c(-1,1) 
    yrTru <- yr + 0.05*diff(yr)*c(-1,1) 

    #Find where the line crosses the plot edges 
    yCross <- (yrTru - intercept)/slope 
    xCross <- (slope * xrTru) + intercept 

    #Build polygon by cases 
    if (above & (slope >= 0)){ 
     rs <- data.frame(x=-Inf,y=Inf) 
     if (xCross[1] < yrTru[1]){ 
      rs <- rbind(rs,c(-Inf,-Inf),c(yCross[1],-Inf)) 
     } 
     else{ 
      rs <- rbind(rs,c(-Inf,xCross[1])) 
     } 
     if (xCross[2] < yrTru[2]){ 
      rs <- rbind(rs,c(Inf,xCross[2]),c(Inf,Inf)) 
     } 
     else{ 
      rs <- rbind(rs,c(yCross[2],Inf)) 
     } 
    } 
    if (!above & (slope >= 0)){ 
     rs <- data.frame(x= Inf,y= -Inf) 
     if (xCross[1] > yrTru[1]){ 
      rs <- rbind(rs,c(-Inf,-Inf),c(-Inf,xCross[1])) 
     } 
     else{ 
      rs <- rbind(rs,c(yCross[1],-Inf)) 
     } 
     if (xCross[2] > yrTru[2]){ 
      rs <- rbind(rs,c(yCross[2],Inf),c(Inf,Inf)) 
     } 
     else{ 
      rs <- rbind(rs,c(Inf,xCross[2])) 
     } 
    } 
    if (above & (slope < 0)){ 
     rs <- data.frame(x=Inf,y=Inf) 
     if (xCross[1] < yrTru[2]){ 
      rs <- rbind(rs,c(-Inf,Inf),c(-Inf,xCross[1])) 
     } 
     else{ 
      rs <- rbind(rs,c(yCross[2],Inf)) 
     } 
     if (xCross[2] < yrTru[1]){ 
      rs <- rbind(rs,c(yCross[1],-Inf),c(Inf,-Inf)) 
     } 
     else{ 
      rs <- rbind(rs,c(Inf,xCross[2])) 
     } 
    } 
    if (!above & (slope < 0)){ 
     rs <- data.frame(x= -Inf,y= -Inf) 
     if (xCross[1] > yrTru[2]){ 
      rs <- rbind(rs,c(-Inf,Inf),c(yCross[2],Inf)) 
     } 
     else{ 
      rs <- rbind(rs,c(-Inf,xCross[1])) 
     } 
     if (xCross[2] > yrTru[1]){ 
      rs <- rbind(rs,c(Inf,xCross[2]),c(Inf,-Inf)) 
     } 
     else{ 
      rs <- rbind(rs,c(yCross[1],-Inf)) 
     } 
    } 

    return(rs) 
} 

それは(range()のように)あなたのデータのxとyの範囲を見込んで、直線の傾きと切片を使用して、プロットしようとしているかどうか、またラインの上または下にシェードするかどうかを指定します。次の4つの例を生成するために使用したコードは次のとおりです。

#Generate some data 
dat <- data.frame(x=runif(10),y=runif(10)) 

#Select two of the points to define the line 
pts <- dat[sample(1:nrow(dat),size=2,replace=FALSE),] 

#Slope and intercept of line through those points 
sl <- diff(pts$y)/diff(pts$x) 
int <- pts$y[1] - (sl*pts$x[1]) 

#Build the polygon 
datPoly <- buildPoly(range(dat$x),range(dat$y), 
      slope=sl,intercept=int,above=FALSE) 

#Make the plot 
p <- ggplot(dat,aes(x=x,y=y)) + 
     geom_point() + 
     geom_abline(slope=sl,intercept = int) + 
     geom_polygon(data=datPoly,aes(x=x,y=y),alpha=0.2,fill="blue") 
print(p)  

ここにいくつかの例があります。あなたはどんなバグを見つけた場合は、もちろん、

shade_above1

...私はこの答えを更新することができますのでお知らせ

shade_above2

shade_below1

shade_below2

EDIT

set.seed(1) 
dat <- data.frame(x=runif(6,-2,2),y=runif(6,-2,2), 
     var1=rep(c("A","B"),3),var2=rep(c("C","D"),3)) 
#Create polygon data frame 
df_poly <- buildPoly(range(dat$x),range(dat$y)) 

ggplot(data=dat,aes(x,y)) + 
    facet_wrap(~var2) + 
    geom_abline(slope=1,intercept=0,lwd=0.5)+ 
    geom_point(aes(colour=var1),size=3) + 
    scale_color_manual(values=c("red","blue"))+ 
    geom_polygon(data=df_poly,aes(x,y),fill="blue",alpha=0.2) 

これは以下の出力生成:OPの例のデータを用いて溶液を示し、

enter image description here

+0

+1いいね。... – Andrie

+0

私のコメントのために上を参照してください! – jslefche

5

私が知る限り、アルファブレンドでポリゴンを作成する以外の方法はありません塗りつぶす。例えば:ここAndrieの答え@上の建物

df <- data.frame(x=1, y=1) 
df_poly <- data.frame(
    x=c(-Inf, Inf, -Inf), 
    y=c(-Inf, Inf, Inf) 
) 

ggplot(df, aes(x, y)) + 
    geom_blank() + 
    geom_abline(slope=1, intercept=0) + 
    geom_polygon(data=df_poly, aes(x, y), fill="blue", alpha=0.2) + 

enter image description here

+0

行がコーナーからコーナーまで実行されない場合は、線が別のデータセットの上にプロットされた場合に発生する可能性が高い場合は、はるかに複雑になります。私はちょっと手を触れましたが、一般的な解決策は考えられませんでした。 – joran

+0

一般的な解決策は、http://stackoverflow.com/questions/6786982/shaded-area-under-two-curves-using-r/6787479#6787479 – Andrie

+0

に記載されているとおりの線に沿っている必要があります。私はAndrie'sを試しましたが、第3変数 'qplot(x、y、color = z)'によって色付けされていますが、 'geom_polygon()'ステートメントではうまくいきません。私は理解できない起点よりも歪んでいる。何か案は? – jslefche

関連する問題