24

如何将三向颜色渐变(热图)填充到三图(三角形图),像这样。

plot(NA,NA,xlim=c(0,1),ylim=c(0,sqrt(3)/2),asp=1,bty="n",axes=F,xlab="",ylab="")
segments(0,0,0.5,sqrt(3)/2)
segments(0.5,sqrt(3)/2,1,0)
segments(1,0,0,0)

在此处输入图像描述

颜色应该与三图平行运行。

4

3 回答 3

24

这是一种方法 - 它有点像黑客,使用点来逐个绘制渐变:

plot(NA,NA,xlim=c(0,1),ylim=c(0,1),asp=1,bty="n",axes=F,xlab="",ylab="")
segments(0,0,0.5,sqrt(3)/2)
segments(0.5,sqrt(3)/2,1,0)
segments(1,0,0,0)
# sm - how smooth the plot is. Higher values will plot very slowly
sm <- 500
for (y in 1:(sm*sqrt(3)/2)/sm){
    for (x in (y*sm/sqrt(3)):(sm-y*sm/sqrt(3))/sm){
        ## distance from base line:
        d.red = y
        ## distance from line y = sqrt(3) * x:
        d.green = abs(sqrt(3) * x - y) / sqrt(3 + 1)
        ## distance from line y = - sqrt(3) * x + sqrt(3):
        d.blue = abs(- sqrt(3) * x - y + sqrt(3)) / sqrt(3 + 1)
        points(x, y, col=rgb(1-d.red,1 - d.green,1 - d.blue), pch=19)
    }
}

和输出:

在此处输入图像描述

您想使用这些渐变来表示数据吗?如果是这样,可能会改变d.red,d.greend.blue这样做 - 不过我还没有测试过类似的东西。我希望这会有所帮助,但是colorRamp例如,使用 的适当解决方案可能会更好。

编辑:根据 baptiste 的建议,这就是您将信息存储在向量中并一次性绘制出来的方式。它要快得多(sm例如,尤其是设置为 500 时):

plot(NA,NA,xlim=c(0,1),ylim=c(0,1),asp=1,bty="n",axes=F,xlab="",ylab="")
sm <- 500
x <- do.call(c, sapply(1:(sm*sqrt(3)/2)/sm, 
                       function(i) (i*sm/sqrt(3)):(sm-i*sm/sqrt(3))/sm))
y <- do.call(c, sapply(1:(sm*sqrt(3)/2)/sm, 
                       function(i) rep(i, length((i*sm/sqrt(3)):(sm-i*sm/sqrt(3))))))
d.red = y
d.green = abs(sqrt(3) * x - y) / sqrt(3 + 1)
d.blue = abs(- sqrt(3) * x - y + sqrt(3)) / sqrt(3 + 1)
points(x, y, col=rgb(1-d.red,1 - d.green,1 - d.blue), pch=19)
于 2012-08-04T17:44:34.317 回答
17

这是一个带有光栅化背景图像的解决方案。该函数的sharpness参数tricol控制颜色变黑的速度。将其设置为 1 为您提供 Edward 的颜色,将其设置为 2 为您提供以下颜色。

# Coordinates of the triangle
tri <- rbind(sin(0:2*2/3*pi), cos(0:2*2/3*pi))

# Function for calculating the color of a set of points `pt`
# in relation to the triangle
tricol <- function(pt, sharpness=2){
    require(splancs)
    RGB <- sapply(1:3, function(i){
        a <- sweep(pt, 2, tri[,i])
        b <- apply(tri[,-i], 1, mean) - tri[,i]
        sharpness*((a %*% b) / sum(b^2))-sharpness+1
    })
    RGB[-inpip(pt,t(tri)),] <- 1    # Color points outside the triangle white
    do.call(rgb, unname(as.data.frame(pmin(pmax(RGB, 0), 1))))
}

# Plot
res <- 1000                         # Resolution
xi <- seq(-1, 1, length=res)        # Axis points
yi <- seq(-.8, 1.2, length=res)
x <- xi[1] + cumsum(diff(xi))       # Midpoints between axis points
y <- yi[1] + cumsum(diff(yi))
xy <- matrix(1:(length(x)*length(y)), length(x))
image(xi, yi, xy, col=tricol(as.matrix(expand.grid(x,y))), useRaster=TRUE)
lines(tri[1,c(1:3,1)], tri[2,c(1:3,1)], type="l")

什么是用颜色(红色,绿色,蓝色)tricol()表示每个角落。i它定义了一个从角到点a的向量矩阵pt和一个b从角到对边中心的向量。然后它a投影b并缩放以获得相对距离=颜色强度(并应用一个小技巧sharpness来稍微调整颜色)。当涉及到像这个简单的代数这样的问题时,它可以发挥神奇的作用。

由于混叠,您会在边缘周围得到一点噪音,但您可能可以将其调整掉,或者在三角形中画出稍宽的线条。 渐变三角形

于 2012-08-06T15:21:13.787 回答
1

这是我为phonR包设计的一个实现...该fillTriangle函数未导出,因此您必须使用:::运算符来访问它。示例显示了基于 pch 和基于光栅的方法。

# set up color scale
colmap <- plotrix::color.scale(x=0:100, cs1=c(0, 180), cs2=100, cs3=c(25, 100),
                               alpha=1, color.spec='hcl')
# specify triangle vertices and corner colors
vertices <- matrix(c(1, 4, 2, 1, 3, 4, length(colmap), 1, 30), nrow=3,
                   dimnames=list(NULL, c("x", "y", "z")))
# edit next line to change density / resolution
xseq <- yseq <- seq(0, 5, 0.01)
grid <- expand.grid(x=xseq, y=yseq)
grid$z <- NA
grid.indices <- splancs::inpip(grid, vertices[,1:2], bound=FALSE)
grid$z[grid.indices] <- with(grid[grid.indices,], 
                             phonR:::fillTriangle(x, y, vertices))
# plot it
par(mfrow=c(1,2))
# using pch
with(grid, plot(x, y, col=colmap[round(z)], pch=16))
# overplot original triangle
segments(vertices[,1], vertices[,2], vertices[c(2,3,1),1], 
         vertices[c(2,3,1),2])
points(vertices[,1:2], pch=21, bg=colmap[vertices[,3]], cex=2)

# using raster
image(xseq, yseq, matrix(grid$z, nrow=length(xseq)), col=colmap)
# overplot original triangle
segments(vertices[,1], vertices[,2], vertices[c(2,3,1),1], 
         vertices[c(2,3,1),2])
points(vertices[,1:2], pch=21, bg=colmap[vertices[,3]], cex=2)

渐变三角形填充的示例图

于 2016-02-28T20:08:47.567 回答