簡體   English   中英

R中的2d顏色梯度圖

[英]2d color gradient plot in R

我想生成一個二維顏色漸變矩形,如右下圖所示。 我怎么能在R中這樣做? 使用colorRampRColorBrewer或其他功能/包我可以生成漂亮的1D dolor ramps。 但是我如何為2D做這個,包括角落里的幾種顏色,比如右上方的矩形?

顏色漸變

我想得到的是例如以下兩種漸變類型:

在此輸入圖像描述在此輸入圖像描述

BTY:我完全忘了提到我在這里找到了上面的圖表(由Luca Fenu制作)。

試試這個:

 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:當函數不可分離時,使用外部,

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)

在此輸入圖像描述

感謝您對我的帖子發表評論 - 我很高興它產生了一些討論。 這里有一個最小的代碼來實現右上角的圖 - 我相信還有其他更有效的方法可以做到這一點......但這不需要其他庫,並且應該很容易遵循...你可以改變通過使用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!

我確信有更優雅的方式來做到這一點。 無論如何,在這里你走了:最后一行是對問題中原始圖像的非常接近的再現。

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

你可以嘗試這個,看看結果圖

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

結果圖 <點擊查看

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM