2011-07-23 67 views
6

陰影區域I具有被限制到低於1的一些數據:1行。我會通過輕微地遮蔽線條上方的區域來在劇情中演示這一點,以將觀衆的注意力吸引到線條下方的區域。GGPLOT2 - 上面的行

我使用qplot生成的圖表。很快,我有;

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

但對我的生活,無法弄清楚如何輕鬆遮陽上述區域無繪製一個單獨的對象。有這個簡單的解決辦法嗎?


編輯

好吧,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

着色點和填充多邊形是由兩個不同的美學處理(顏色和填充)和不應該發生衝突,所以我懷疑你可能在那裏做錯了什麼。我很樂意提供更多的幫助,但是如果沒有您想要繪製的數據的特定重現示例,我不能這麼做...... – joran

+0

完成。我懷疑這起源於我對ggplot2如何處理這些事情的陌生性。再次感謝您的幫助,我非常感謝。 – jslefche

+0

將'color = var1'移動到'geom_point':'geom_point(aes(color = var1),...)'。另外,如果你想在每個方面填充不同的多邊形,你應該知道你必須爲每個方面創建一個單獨的數據框,並將它們組合成一個包含'var2'因子的數據框,所以'ggplot'知道哪一個適用於每個方面。 – joran

回答

11

這裏建立在@ Andrie的回答是處理上面或在多數情況下給定線下方陰影更(但不完全)通用的解決方案。

當您添加邊緣附近點我沒有使用@Andrie引用here,因爲我遇到了與ggplot的傾向自動延長情節程度問題的方法。相反,這種構建多邊形點使用Inf-Inf根據需要手動。有幾個注意事項:

  • 的點必須在數據幀中的「正確」的順序,因爲ggplot地塊,該點出現的順序多邊形。所以獲得多邊形的頂點是不夠的,它們必須被順序排列(順時針或逆時針)。

  • 此解決方案假定您正在繪製行本身並不引起ggplot延伸繪圖範圍。在我的示例中,您會看到我通過在數據中隨機選擇兩個點並通過它們繪製線來選取一條線進行繪製。如果您嘗試畫一條線過於遠離你點的休息,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) 
} 

它預計數據的X和Y範圍(如range()),斜率和截距行的你將要繪製,並且您是否想要遮蔽線條的上方或下方。以下是我用於生成以下四個示例的代碼:

#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

編輯

已更新使用OP的示例性數據說明的解決方案:

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) 

並且這產生以下輸出:

enter image description here

+0

+1不錯的一個.... – Andrie

+0

看到我的意見! – jslefche

5

據我知道有比創建與阿爾法混合多邊形其他沒有別的辦法填。例如:

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,但是我已經指定了點被第三個變量'qplot(x,y,color = z)'着色,這對'geom_polygon()'語句不會很好。這條線也偏低於原點,這是我無法弄清楚的。有任何想法嗎? – jslefche