three-way color gradient fill in r

前端 未结 3 1573
忘掉有多难
忘掉有多难 2020-12-07 23:33

How can I fill three way color gradient (heatmap) to a triplot (triangle plot), like this.

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


        
3条回答
  •  一生所求
    2020-12-07 23:56

    Here is one way to do it - it's a bit of a hack, using points to plot the gradient piece by piece:

    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)
        }
    }
    

    And the output:

    enter image description here

    Did you want to use these gradients to represent data? If so, it may be possible to alter d.red, d.green, and d.blue to do it - I haven't tested anything like that yet though. I hope this is somewhat helpful, but a proper solution using colorRamp, for example, will probably be better.

    EDIT: As per baptiste's suggestion, this is how you would store the information in vectors and plot it all at once. It is considerably faster (especially with sm set to 500, for example):

    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)
    

提交回复
热议问题