基于Y值的R中的多色线图

时间:2017-05-15 21:06:51

标签: r plotly

我想在R中创建一个Plotly图表,当它为正时为绿色,为负时为红色。

我试图用两条独立的痕迹做到这一点,产生下面的第一块图是不连续的。然后,我尝试使用由下面的代码创建的颜色列创建彩色迹线。这些是我能想到的唯一使用当前版本的plotly的实现。

> str(results)
'data.frame':   804 obs. of  7 variables:
 $ date  : Date, format: "2014-03-06" "2014-03-07" "2014-03-10" ...
 $ 5yr   : num  32.9 32.5 32.9 32.8 32.8 ...
 $ 3y5   : num  32.4 32.1 32.5 32.4 32.4 ...
 $ spread: num  -0.488 -0.431 -0.438 -0.388 -0.452 ...
 $ pos   : num  NA NA NA NA NA NA NA NA NA NA ...
 $ neg   : num  -0.488 -0.431 -0.438 -0.388 -0.452 ...
 $ color : chr  "red" "red" "red" "red" ...

results$spread <- results[,3] - results[,2]
results$neg <- ifelse(results$spread < 0 , results$spread, NA)
results$pos <- ifelse(results$spread >= 0 , results$spread, NA)

plot_ly(results,
    x = ~dates,
    y = ~pos,
    type = 'scatter',
    mode = 'lines',
    line = list(color = 'green')) %>%
  add_trace(results,
            x = ~dates,
            y = ~neg,
            type = 'scatter',
            mode = 'lines',
            line = list(color = 'red')) %>%
  layout(xaxis = list(title = 'Date'),
         yaxis = list(title = 'Price'))

plotly graph produced with traces

plot_ly(results,
    x = ~dates,
    y = ~spread,
    type = 'scatter',
    mode = 'lines',
    color = ~color) %>%
  layout(xaxis = list(title = 'Date'),
         yaxis = list(title = 'Price'))

plotly graph produced with color

2 个答案:

答案 0 :(得分:2)

这是一个有趣的。但过了一会儿,我意识到你可以通过在你的情节的每个过零点插入一个零值来得到你想要的东西:

我认为代码是不言自明的(带注释)

这是代码 - (带有一些伪造的数据):

library(plotly)

#fake up some data
set.seed(123)
n <- 100
sdate <- as.Date("2014-03-06")
dt <- seq.Date(sdate,by="days",length.out=n)
results <- data.frame(dates=dt,v1=rnorm(n,32.6,0.2),v2=rnorm(n,32.6,0.2))
results$spread <- results[,3] - results[,2]


# find all the zero crossings
spd <- results$spread
lagspd <- c(spd[1],spd[1:(length(spd)-1)])
crs <- sign(spd)!=sign(lagspd)
results$crs <- crs

# now insert a zero row where there is a crossing
insertZeroRow <- function(df,i){ 
  n <- nrow(df)
  ndf1 <- df[1:i,] # note these overlap by 1
  ndf2 <- df[i:n,] # that is the row we insert
  ndf1$spread[i] <- 0
  ndf <- rbind(ndf1,ndf2)
}


i <- 1
while(i<nrow(results)){
  if (results$crs[i]){
    results <- insertZeroRow(results,i)
    i <- i+1
  }
  i <- i+1
}

# plot it now

results$neg <- ifelse(results$spread <= 0 , results$spread, NA)
results$pos <- ifelse(results$spread >= 0 , results$spread, NA)

plot_ly(results,
        x = ~dates,
        y = ~pos,
        type = 'scatter',
        mode = 'lines',
        line = list(color = 'green')) %>%
  add_trace(results,
            x = ~dates,
            y = ~neg,
            type = 'scatter',
            mode = 'lines',
            line = list(color = 'red')) %>%
  layout(xaxis = list(title = 'Date'),
         yaxis = list(title = 'Price'))

结果如下:

enter image description here

请注意,通过插入datesspread值来获得正确的x轴交叉点可以使其更好,但我认为在大多数情况下它不会产生巨大的差异。如果你这样做,你需要一个可以代表一天中几小时的日期类型(如as.POSIXct),以便能够指定正确的x轴值。

更新

为了解决任何困惑,添加零行是必要的。如果您注释掉insertZeroRow来电,则会收到:enter image description here

答案 1 :(得分:0)

基本上你可以在这部分代码中改变你的第一个实现:

results$spread <- results[,3] - results[,2]
results$neg <- ifelse(results$spread < 0 , results$spread, NA)
results$pos <- ifelse(results$spread >= 0 , results$spread, NA)

在第二行代码中添加=:

results$spread <- results[,3] - results[,2]
results$neg <- ifelse(results$spread <= 0 , results$spread, NA)
results$pos <- ifelse(results$spread >= 0 , results$spread, NA)

尝试,它应该有效去除不连续性