2012-04-02 29 views
4

我有两个显示供给和需求的图表,以及一个从供给中减去需求以显示不对称结果的图表。我想遮蔽x轴和不对称负面部分之间的区域,以显示赤字的程度。阴影geom_line和x轴之间的区域

我目前使用以下代码:

plot.asymmetry <- ggplot(data=df.overview.month, 
         aes(x=Date.Time, y=Asymmetry)) +  
     geom_area(data=subset(df.overview.month, Asymmetry < 0),  
         aes(x=Date.Time, y=Asymmetry)) 

然而 - 如可以预期 - 这不遮挡geom_line和x轴之间的区域,但只有不对称数据,的负值之间,其完全是另一回事,如图所示的结果图:

enter image description here

有什么办法解决这个问题?

/编辑:一些示例数据:

time.initial <- as.POSIXct("2010-12-31 23:00:00", tz="GMT") 
Date.Time<-vector() 
for(i in 1:24) { 
Date.Time[i] <- time.initial + i*3600 
} 

Demand<-vector() 
for(i in 0:23) { 
Demand[i+1] <- 155 + 20*sin((pi/12)*i - (pi/2)) + 10*sin((pi/4380)*i + (pi/2)) 
} 

Supply<-vector() 
for(i in 0:23) { 
Supply[i+1] <- 165 + 5*sin((pi/4380)*i - (pi/2)) + rnorm(1, mean=0, sd=0.20*165) 
} 

df.overview.month <- data.frame(Date.Time, Demand, Supply, Asymmetry=Supply-Demand) 
+0

你能提供运行的代码,即一些示例数据? – ROLO 2012-04-02 09:26:45

+0

我编辑的主要文章这样做。 – 2012-04-02 09:41:21

+1

我想你需要首先计算细分中零的位置。 – baptiste 2012-04-02 10:06:50

回答

3

什么以此为灵感。现在,只需要在非对称性等于零的情况下添加其他数据点(如@baptiste建议的那样)。当非对称性大于零时,我创建了一个新列,即NA,这样就不会在那里绘制geom_ribbon。只是对数据进行子集化将不会导致所需的情节。

df.overview.month$Assym_ribbon = ifelse(df.overview.month$Asymmetry > 0, 
             NA, 
             df.overview.month$Asymmetry) 
ggplot(aes(x = Date.Time, y = Asymmetry), 
     data = df.overview.month) + 
    geom_line() + 
    geom_ribbon(aes(ymin = 0, ymax = Assym_ribbon), 
     data = , fill = "red") 

enter image description here

你构建你的榜样的方式提供了一些说明。最重要的是R是矢量化的。例如:

set.seed(1) 
Supply<-vector() 
for(i in 0:23) { 
    Supply[i+1] <- 165 + 
      5*sin((pi/4380)*i - 
      (pi/2)) + 
      rnorm(1, mean=0, sd=0.20*165) 
} 

等同于:

set.seed(1) 
i = 0:23 
Supply_vec <- 165 + 5*sin((pi/4380)*i - 
       (pi/2)) + 
       rnorm(length(i), mean=0, sd=0.20*165) 

> all.equal(Supply_vec, Supply) 
[1] TRUE 

在这种情况下,代码的减少是适度的,但是在使用矢量会为你节省几十行代码的其它(更现实)的设置。

+1

下面是一些很好的示例代码,用于计算线条之间的交点并为它们之间的区域着色:http://learnr.wordpress.com/2009/10/22/ggplot2-two-color-xy-area-combo-chart/ – ROLO 2012-04-02 10:11:23

+0

@ROLO不确定这是多么强大,当一些段是垂直或水平 – baptiste 2012-04-02 10:27:52

+0

谢谢,保罗。我已经发现了geom_ribbon,但无法弄清楚如何将其用于此目的。我希望更多地使用矢量化表单,谢谢! – 2012-04-02 10:51:08

5

下面是一些代码ported from Matlab来计算段之间的交集。如果将其应用于x轴(固定)和每对连续点之间,则会得到一个新坐标列表,指示您的geom_line与x轴之间的交点。由此可以很容易地遮蔽相关的多边形。请注意,我没有正确测试移植的Matlab代码。

enter image description here

## Ported from Matlab to R 
## Copyright (c) 2010, U. Murat Erdem 
## All rights reserved. 
## http://www.mathworks.com/matlabcentral/fileexchange/27205 
lineSegmentIntersect <- function(XY1, XY2){ 

    n_rows_1 <- nrow(XY1) 
    n_cols_1 <- ncol(XY1) 
    n_rows_2 <- nrow(XY2) 
    n_cols_2 <- ncol(XY2) 

    stopifnot(n_cols_1 == 4 && n_cols_2 == 4) 

    nc <- n_rows_1 * n_rows_2 
    X1 <- matrix(XY1[,1], nrow=nc, ncol=1) 
    X2 <- matrix(XY1[,3], nrow=nc, ncol=1) 
    Y1 <- matrix(XY1[,2], nrow=nc, ncol=1) 
    Y2 <- matrix(XY1[,4], nrow=nc, ncol=1) 

    XY2 <- t(XY2) 

    X3 <- matrix(XY2[1,], nrow=nc, ncol=1) 
    X4 <- matrix(XY2[3,], nrow=nc, ncol=1) 
    Y3 <- matrix(XY2[2,], nrow=nc, ncol=1) 
    Y4 <- matrix(XY2[4,], nrow=nc, ncol=1) 

    X4_X3 <- X4-X3 
    Y1_Y3 <- Y1-Y3 
    Y4_Y3 <- Y4-Y3 
    X1_X3 <- X1-X3 
    X2_X1 <- X2-X1 
    Y2_Y1 <- Y2-Y1 

    numerator_a <- X4_X3 * Y1_Y3 - Y4_Y3 * X1_X3 
    numerator_b <- X2_X1 * Y1_Y3 - Y2_Y1 * X1_X3 
    denominator <- Y4_Y3 * X2_X1 - X4_X3 * Y2_Y1 

    u_a <- numerator_a/denominator 
    u_b <- numerator_b/denominator 

    INT_X <- X1 + X2_X1 * u_a 
    INT_Y <- Y1 + Y2_Y1 * u_a 
    INT_B <- (u_a >= 0) & (u_a <= 1) & (u_b >= 0) & (u_b <= 1) 
    PAR_B <- denominator == 0 
    COINC_B <- (numerator_a == 0 & numerator_b == 0 & PAR_B) 

    data.frame(x=INT_X[INT_B], y=INT_Y[INT_B]) 

} 


set.seed(123) 
x <- sort(runif(50, -10, 10)) 
y <- jitter(sin(x), a=2) 
n <- length(x) 
xy1 <- matrix(c(-10, 0, 10, 0), ncol=4) 
xy2 <- cbind(x[-n], y[-n], x[-1], y[-1]) 
test <- lineSegmentIntersect(xy1, xy2) 

library(ggplot2) 
d <- data.frame(x=x, y=y) 
d2 <- rbind(d, test) 
d2 <- subset(d2[order(d2$x), ], y <=0) 
p <- qplot(x, y, data=d, geom="path") 

p + geom_ribbon(data=d2, aes(ymin = 0, ymax = y), fill="red") 
+0

我已经想通了,我可能需要做这样的事情,希望用这个作为答案。非常感谢! – 2012-04-02 10:42:30

+0

嗯...还有一个问题:我可以计算出数学来找出线段与x轴相交的点,但是我需要一些方法来操纵x值。在这种情况下,这很难,因为我使用POSIXct类作为x值。是否有任何简单的方法将它们转换为例如秒数,以便我可以进行计算,然后转换回POSIXct(并为x交点找到正确的日期/时间)? – 2012-04-02 12:34:13

+0

抱歉,不了解POSIXct类 – baptiste 2012-04-11 09:54:33