這裏至少有幾個選項。第一個很簡單,一般(因爲它不限於直線段)和精確的,但使用基地plot
而不是ggplot
。第二個使用ggplot
,但稍微複雜一些,並且顏色過渡不會100%精確(但是隻要您指定了適當的分辨率......就可以了)。
基地:
如果你願意使用base
繪圖函數,而不是ggplot
,你可以剪輯的圖形區域爲高於閾值(2.2),然後在您的首選顏色繪製段,並隨後剪切到閾值以下的區域,並再次以紅色繪圖。雖然第一個剪輯是絕對不必要的,但它可以防止重疊繪製不同的顏色,這看起來有點不合時宜。
threshold <- 2.2
set.seed(123)
stackOne=data.frame(id=rep(c(1,2,3),each=3),
y=rnorm(9,2,1),
x=rep(c(1,2,3),3))
# create a second df to hold segment data
d <- stackOne
d$y2 <- c(d$y[-1], NA)
d$x2 <- c(d$x[-1], NA)
d <- d[-findInterval(unique(d$id), d$id), ] # remove last row for each group
plot(stackOne[, 3:2], pch=20)
# clip to region above the threshold
clip(min(stackOne$x), max(stackOne$x), threshold, max(stackOne$y))
segments(d$x, d$y, d$x2, d$y2, lwd=2)
# clip to region below the threshold
clip(min(stackOne$x), max(stackOne$x), min(stackOne$y), threshold)
segments(d$x, d$y, d$x2, d$y2, lwd=2, col='red')
points(stackOne[, 3:2], pch=20) # plot points again so they lie over lines
ggplot:
如果你想要或需要使用ggplot
,您可以考慮以下...
一種解決方案是使用geom_line(aes(group=id, color = y < 2.2))
,然而這將根據每個片段開頭的點的y值來分配顏色。我相信你希望顏色不僅在節點上發生變化,而且在任何一條線越過給定的閾值2.2時。我並不是所有人都熟悉ggplot,但實現此目的的一種方法是通過沿連接現有點的線創建新點來創建數據的更高分辨率版本,然後使用color = y < 2.2
參數來實現所需的影響。
例如:
threshold <- 2.2 # set colour-transition threshold
yres <- 0.01 # y-resolution (accuracy of colour change location)
d <- stackOne # for code simplification
# new cols for point coordinates of line end
d$y2 <- c(d$y[-1], NA)
d$x2 <- c(d$x[-1], NA)
d <- d[-findInterval(unique(d$id), d$id), ] # remove last row for each group
# new high-resolution y coordinates between each pair within each group
y.new <- apply(d, 1, function(x) {
seq(x['y'], x['y2'], yres*sign(x['y2'] - x['y']))
})
d$len <- sapply(y.new, length) # length of each series of points
# new high-resolution x coordinates corresponding with new y-coords
x.new <- apply(d, 1, function(x) {
seq(x['x'], x['x2'], length.out=x['len'])
})
id <- rep(seq_along(y.new), d$len) # new group id vector
y.new <- unlist(y.new)
x.new <- unlist(x.new)
d.new <- data.frame(id=id, x=x.new, y=y.new)
p <- ggplot(d.new, aes(x=x,y=y)) +
geom_line(aes(group=d.new$id, color=d.new$y < threshold))+
geom_point(data=stackOne)+
scale_color_discrete(sprintf('Below %s', threshold))
p
有可能是一種方法,通過ggplot功能,要做到這一點,但在此期間,我希望這會有所幫助。我無法弄清楚如何將ggplotGrob
繪製成修剪後的viewport
(而似乎只是縮放繪圖)。如果你想要顏色取決於某個x值閾值,這顯然需要一些調整。
謝謝。我聽說融化函數也可能對這些問題有用,但這聽起來像是一個很好的解決方案。 – user1106711 2012-03-03 18:25:45
我已經編輯瞭解決方案,包括一個使用基本圖和'clip'的方法。 – jbaums 2012-03-04 05:22:22
'ggplotGrob'使用內部視口本身,這就是裁剪不起作用的原因。 – baptiste 2012-03-04 07:41:33