R-область тени между двумя пересекающимися линиями с разными цветами
У меня есть матрица (с именем Ишимоку) с 516 строками и 2 столбцами ,каждый из которых содержит значения, которые нужно построить, цель-воссоздать облака для стратегии Ишимоку . Используя matpot, я могу построить эти две кривые, но то, что я хочу, это затенить область между двумя кривыми. У меня есть две проблемы:
-
Я попытался использовать полигон для затенения области, но это не работает. Я подозреваю, что это потому, что две серии (senkouA и senkouB) пересекаются несколько раз на заговор вместо того, чтобы иметь один всегда больше, чем другой
-
Я хотел бы, чтобы область была затенена зеленым цветом, если сенкоуб>сенкоуб и красным, если сенкоуб>сенкоуб, но из того, что я читал, многоугольник может быть только одного цвета.
Есть ли другая функция этого полигона, которая могла бы помочь мне достичь того, что я ищу, то есть область тени в зеленом цвете между senkouA и senkouB, когда senkouA>senkouB и область тени в красном цвете, когда senkouB>senkouA ?
Ишимоку матрица выглядит так (первый столбец-senkouA, другой-senkouB)
[,1] [,2]
[1,] 23323.62 23320.53
[2,] 23334.67 23328.71
[3,] 23334.11 23323.06
[4,] 23332.94 23323.06
...
Вот моя функция matplot (которая работает):
matplot(ichimoku,lty=1,lwd=1,pch=20,type="l",col=c("red","blue"))
И моя полигональная функция (которая этого не делает):
polygon(c(1:516,516:1),c(senkouA,senkouB),col='green')
2 ответа:
Если вы найдете пересечения между кривыми, то вы можете нарисовать многоугольники между пересечениями. Вот модификация предыдущего поста , где они находят пересечения между кривыми, и функция для рисования полигонов.
## Some sample data set.seed(0) dat <- data.frame(x1=3*sin(3*(x=seq(0,10,len=100)))+rnorm(100), x2=2*cos(x)+rnorm(100)) ## https://stackoverflow.com/questions/20519431/finding-point-of-intersection-in-r intersects <- function(x1, x2) { seg1 <- which(!!diff(x1 > x2)) # location of first point in crossing segments above <- x2[seg1] > x1[seg1] # which curve is above prior to crossing slope1 <- x1[seg1+1] - x1[seg1] slope2 <- x2[seg1+1] - x2[seg1] x <- seg1 + ((x2[seg1] - x1[seg1]) / (slope1 - slope2)) y <- x1[seg1] + slope1*(x - seg1) data.frame(x=x, y=y, pindex=seg1, pabove=(1:2)[above+1L]) # pabove is greater curve prior to crossing } ichimoku <- function(data, addLines=TRUE) { ## Find points of intersections ints <- intersects(data[,1], data[,2]) intervals <- findInterval(1:nrow(data), c(0, ints$x)) ## Make plot matplot(data, type="n", col=2:3, lty=1, lwd=4) legend("topright", c("A", "B"), col=3:2, lty=1, lwd=2) ## Draw the polygons for (i in seq_along(table(intervals))) { xstart <- ifelse(i == 1, 0, ints$x[i-1]) ystart <- ifelse(i == 1, dat[1,ints$pindex[1]], ints$y[i-1]) xend <- ints$x[i] yend <- ints$y[i] x <- seq(nrow(data))[intervals == i] polygon(c(xstart, x, xend, rev(x)), c(ystart, data[x,1], yend, rev(data[x,2])), col=ints$pabove[i]%%2+2) } ## Add lines for curves if (addLines) invisible(lapply(1:2, function(x) lines(seq(nrow(data)), data[,x], col=x%%2+2, lwd=2))) } ## Plot the data ichimoku(dat)
Вот некоторый код, который работает для простой версии вашей проблемы, в которой линии пересекаются только один раз. Однако я не проверял его на повторные переходы.
# Make toy data ichimoku <- data.frame(senkouA = rep(10, 10), senkouB = c(3, 5, 4, 7, 10, 11, 15, 12, 13, 14)) # Make indices for the conditions that define the fill colors. They need to intersect for the polygons to connect. index.green = with(ichimoku, as.logical(senkouA >= senkouB)) index.red = with(ichimoku, as.logical(senkouA <= senkouB)) # Make the line plot matplot(ichimoku, lty=1, lwd=1, pch=20, type="l", col=c("red","blue")) # Now add polygons with fill color based on those conditions by subsetting the task using the indices. with(ichimoku, polygon(x = c(seq(length(senkouA))[index.green], rev(seq(length(senkouA))[index.green])), y = c(senkouB[index.green], senkouA[index.green]), col = "green")) with(ichimoku, polygon(x = c(seq(length(senkouA))[index.red], rev(seq(length(senkouA))[index.red])), y = c(senkouB[index.red], senkouA[index.red]), col = "red"))
Вот мой результат: