R中的2d颜色渐变图

Posted

技术标签:

【中文标题】R中的2d颜色渐变图【英文标题】:2d color gradient plot in R 【发布时间】:2012-06-19 16:05:23 【问题描述】:

我想制作一个 2d 颜色渐变矩形,如下图右侧所示。我怎样才能在 R 中做到这一点?使用colorRampRColorBrewer 或其他功能/包,我可以生成漂亮的一维忧郁斜坡。但是我如何为 2D 执行此操作,包括角落中的几种颜色,例如右上角的矩形?

我想要得到的是例如以下两种渐变类型:

BTY:我完全忘了提到我找到了上面的图表here(Luca Fenu 制作)。

【问题讨论】:

这确实是一个非常好的技术问题,但我也建议可能有其他显示数据的方式更容易解释......二维色谱会下降很多克利夫兰的图形特征层次结构(尽管我确信他从未明确考虑过)(看看你的图例,似乎你实际上有一个 3D 色彩空间?) 嗨,Ben,目前这是我工作组的共识,即这是我们想要的图表。虽然确实可能有更好的视觉方法。在我的情况下,基础颜色表示甚至不需要是“精确的”。我宁愿用它作为一个广泛的指标,让观众了解飞机上的位置意味着什么。 嗯,是的,你是对的。右上角似乎包含了更难的渐变类型... 【参考方案1】:

试试这个:

 m = tcrossprod(sin(seq(0,pi,length=1e2)), cos(seq(0, 3*pi, length=1e2)))
 cols = matrix(hcl(h=scales::rescale(m, c(0, 360))), nrow(m))
 grid::grid.raster(cols)

您需要找到描述所需颜色渐变的函数(我使用正弦波进行说明)。

编辑:4 个角之间的线性插值

library(grid)
library(scales)

m = tcrossprod(seq(1,2,length=1e2), seq(2, 3, length=1e2))
pal <- gradient_n_pal(c("red","green","yellow","blue"), values = c(2, 3, 4, 6), space = "Lab")
cols = matrix(pal(m), nrow(m))
grid.raster(cols)

编辑2:当函数不可分离时,使用outer,

fun_xy <- function(x, y)

  abs(y-x) * abs(y+x)



z <- outer(seq(-1,1,length=100), seq(-1,1,length=100), FUN = fun_xy)

cols = matrix(hcl(h=scales::rescale(z, c(0, 200))), nrow(z))
grid::grid.raster(cols)

您也可以直接在函数内部进行颜色混合,而不是事后将值映射到色标,

fun_xy <- function(x, y)

  R <- (x+1)/2
  G <- (1-x)/2
  B <- (y+1)/2
  A <- 1- 0.5*exp(-(x^2+y^2)/0.2)

  rgb(R, G, B, A)



z <- outer(seq(-1,1,length=100), seq(-1,1,length=100), FUN = fun_xy)

library(grid)
grid.newpage()
grid::grid.raster(z)

【讨论】:

感谢您的回答!这显然解决了技术部分。因此,归结为哪个函数将执行此操作的问题。上图中上部的 2D 渐变看起来是一个非常简单的渐变。我仍然无法确定为此的正确功能。有什么想法吗? 没有上下文就有点模糊了。您要解决的根本问题是什么?这些颜色图代表什么? 我有两个变量 A 和 B。每个变量都在 0 和 1 之间缩放。0 表示不好,1 表示性能好。我想用适当的颜色表示在 2D 平面上。例如。左下角为红色,左上角为绿色,右上角为绿色,右下角为绿色。另一个位置应该在红-黄-绿渐变上插值。我附上了一张新图片,它应该像上面那样(用 PPT 生成)。我不明白的是如何正确地产生介于两者之间的颜色。我认为这种简单的例子足以让我弄清楚其余部分。 嗨@baptiste the author's examples with the X in the middle 的功能是什么?我很难弄清楚..谢谢! @baptiste 感谢您的编辑,但是您是如何完成您所做的并且仍然在四个角上放置四种不同颜色的呢? i tried to answer this as well 但我确信有更好的方法..【参考方案2】:

感谢您对我的帖子发表评论 - 我很高兴它引发了一些讨论。 这是实现右上角图的最小代码-我相信还有其他更有效的方法可以做到这一点...但这无需其他库即可工作,并且应该很容易遵循...您可以更改通过使用 max_sat 和 alpha_default 变量进行饱和度和 alpha 混合...

#define extremes of the color ramps
rampk2r <- colorRampPalette(c(rgb(  0/255,   0/255,   0/255), rgb(218/255,   0/255,   0/255)))
rampk2g <- colorRampPalette(c(rgb(  0/255,   0/255,   0/255), rgb(  0/255, 218/255,   0/255)))

# stupid function to reduce every span of numbers to the 0,1 interval
prop <- function(x, lo=0, hi=100) 
    if (is.na(x)) NA
    else
        min(lo,hi)+x*(max(lo,hi)-min(lo,hi))
    


rangepropCA<-c(0,20)
rangepropCB<-c(0,20)

# define some default variables
if (!exists('alpha_default')) alpha_default<-1 # opaque colors by default
if (!exists('palette_l')) palette_l<-50 # how many steps in the palette
if (!exists('max_sat')) max_sat<-200 # maximum saturation
colorpalette<-0:palette_l*(max_sat/255)/palette_l # her's finally the palette...

# first of all make an empy plot
plot(NULL, xlim=rangepropCA, ylim=rangepropCB, log='', xaxt='n', yaxt='n', xlab='prop A', ylab='prop B', bty='n', main='color field');
# then fill it up with rectangles each colored differently
for (m in 1:palette_l) 
    for (n in 1:palette_l) 
        rgbcol<-rgb(colorpalette[n],colorpalette[m],0, alpha_default);
        rect(xleft= prop(x=(n-1)/(palette_l),rangepropCA[1],rangepropCA[2]) 
            ,xright= prop(x=(n)/(palette_l),rangepropCA[1],rangepropCA[2])
            ,ytop= prop(x=(m-1)/(palette_l),rangepropCB[1],rangepropCB[2]) 
            ,ybottom= prop(x=(m)/(palette_l),rangepropCB[1],rangepropCB[2])
            ,col=rgbcol
            ,border="transparent"
        )
    

# done!

【讨论】:

【参考方案3】:

我确信有一种更优雅的方法可以做到这一点。无论如何,给你:最后一行是问题中原始图像的非常接近的再现。

library(scales)

four.color.matrix <-
    function( mycols )

        m <- matrix( NA , 100 , 100 )

        m[ 1 , 1 ] <- mycols[ 1 ] 
        m[ 1 , 100 ] <- mycols[ 2 ]
        m[ 100 , 1 ] <- mycols[ 3 ]
        m[ 100 , 100 ] <- mycols[ 4 ]

        m[ 1 , 1:100 ] <- gradient_n_pal( c( mycols[ 1 ] , 'white' , mycols[ 2 ] ) , values = c( 1 , 50 , 100 ) )(1:100)
        m[ 1:100 , 1 ] <- gradient_n_pal( c( mycols[ 1 ] , 'white' , mycols[ 3 ] ) , values = c( 1 , 50 , 100 ) )(1:100)
        m[ 1:100 , 100 ] <- gradient_n_pal( c( mycols[ 2 ] , 'white' , mycols[ 4 ] ) , values = c( 1 , 50 , 100 ) )(1:100)
        m[ 100 , 1:100 ] <- gradient_n_pal( c( mycols[ 3 ] , 'white' , mycols[ 4 ] ) , values = c( 1 , 50 , 100 ) )(1:100)

        a <- gradient_n_pal( c( mycols[ 1 ] , 'white' , mycols[ 4 ] ) , values = c( 1 , 50 , 100 ) )
        diag(m)<-a(1:100)

        b <- gradient_n_pal( c( mycols[ 3 ] , 'white' , mycols[ 2 ] ) , values = c( 1 , 50 , 100 ) )
        for(i in 1:(nrow(m) - 1)) 
          for (j in 1:nrow(m)) if (i + j == nrow( m )+1)
              m[i,j] <- b(j)
            
        

        for ( i in 2:50 )

            m[ i , i:(101-i) ] <- 
                gradient_n_pal( c( mycols[ 1 ] , 'white' , mycols[ 2 ] ) , values = c( 0 , 50 , 100 ) )(  i:(101-i) )

            m[ i:(101-i) , i ] <- 
                gradient_n_pal( c( mycols[ 3 ] , 'white' , mycols[ 1 ] ) , values = c( 0 , 50 , 100 ) )( (101-i):i )

        



        for ( i in 51:99 )

            m[ i , i:(101-i) ] <- 
                gradient_n_pal( c( mycols[ 3 ] , 'white' , mycols[ 4 ] ) , values = c( 0 , 50 , 100 ) )(  i:(101-i) )

            m[ i:(101-i) , i ] <- 
                gradient_n_pal( c( mycols[ 4 ] , 'white' , mycols[ 2 ] ) , values = c( 0 , 50 , 100 ) )( (101-i):i )

        

        m
    


z <- four.color.matrix( c( 'red' , 'yellow' , 'green' , 'blue' ) )
library(grid)
grid.raster( z )

# original question asked for something like this
grid.raster( four.color.matrix( c( 'darkgreen' , 'darkgreen' , 'darkred' , 'darkgreen' ) ) )

【讨论】:

【参考方案4】:

你可以试试看结果图

rotate <- function(x) t(apply(x, 2, rev))
n <- 3
library(grid)
mm <- tcrossprod(seq(1,0,length.out = n))
tmp1 <- sapply(col2rgb("orange")/255, function(x) 1-mm*(1-x))
tmp2 <- sapply(col2rgb("cyan")/255, function(x) 1-rotate(mm)*(1-x))
tmp3 <- sapply(col2rgb("purple")/255, function(x) 1-rotate(rotate(mm))*(1-x))
tmp4 <- sapply(col2rgb("grey")/255, function(x) 1-rotate(rotate(rotate(mm)))*(1-x))

tmp <- (tmp1*tmp2*tmp3*tmp4)
grid.raster(matrix(rgb(tmp), nrow = n))

【讨论】:

以上是关于R中的2d颜色渐变图的主要内容,如果未能解决你的问题,请参考以下文章

如何在R中制作渐变颜色填充时间序列图

R plot3d颜色渐变图例

Java实现颜色渐变效果

echarts颜色渐变

在 pyqtgraph 中为条形图设置渐变颜色

颜色渐变的柱状图