2012-06-17 65 views
8

Tôi muốn tạo hình chữ nhật có màu 2d giống như hình bên dưới ở phía bên tay phải. Làm thế nào tôi có thể làm điều này trong R? Sử dụng colorRamp hoặc RColorBrewer hoặc các chức năng/gói khác tôi có thể tạo ra đường dốc màu 1D đẹp. Nhưng làm cách nào để làm điều này cho 2D bao gồm một số màu ở các góc, ví dụ: hình chữ nhật phía trên bên phải?Lô màu 2d màu trong R

Color gradients

Điều tôi muốn nhận là ví dụ: hai loại dốc sau:

enter image description here enter image description here

BTY: Tôi hoàn toàn quên đề cập đến mà tôi tìm thấy bảng xếp hạng trên here (sản xuất bởi Luca Fenu).

+0

Đây là một câu hỏi kỹ thuật rất tốt đẹp thực sự, nhưng tôi cũng sẽ đề nghị rằng có thể có cách khác để hiển thị dữ liệu đó sẽ được dễ dàng hơn để giải thích ... một phổ màu 2D sẽ rơi khá xa hạ bậc của Cleveland về đặc điểm đồ họa (mặc dù tôi chắc chắn ông không bao giờ xem xét nó một cách rõ ràng) (Nhìn vào huyền thoại của bạn, có vẻ như bạn thực sự có một không gian màu * 3D *?) –

+0

Hi Ben, hiện tại đây là sự đồng thuận nhóm làm việc của tôi rằng đây là biểu đồ chúng tôi muốn ..mặc dù thực sự có thể có cách tiếp cận trực quan tốt hơn. Trong trường hợp của tôi, biểu diễn màu cơ bản không cần thậm chí là 'chính xác'. Tôi thích sử dụng nó như là một chỉ báo rộng cho khán giả để có được một ý tưởng về vị trí của chiếc máy bay. –

+0

hhm, vâng, bạn nói đúng. Phía trên bên phải xuất hiện để bao gồm các loại gradient khó khăn hơn ... –

Trả lời

6

Cám ơn ý kiến ​​về bài viết của tôi - Tôi rất vui vì nó được tạo ra một số cuộc thảo luận. Đây là một mã tối thiểu để đạt được các ô ở phía trên bên phải - Tôi chắc chắn có những cách hiệu quả hơn để làm điều đó ... Nhưng điều này làm việc mà không cần thư viện khác, và phải dễ dàng làm theo ... bạn có thể thay đổi độ bão hòa và pha trộn alpha bằng cách chơi với các biến max_sat và alpha_default ...

#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! 
+0

tuyệt vời! cảm ơn rất nhiều vì đã cung cấp đoạn mã có liên quan! –

8

Hãy thử điều này:

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) 

Bạn sẽ cần phải tìm mà chức năng mô tả các màu gradient mà bạn muốn (tôi đã sử dụng sóng sin mang tính minh họa).

enter image description here

Edit: suy tuyến tính giữa 4 góc

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) 

enter image description here

Chỉnh sửa 2: Khi chức năng không phải là tách, sử dụng bên ngoài,

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) 

enter image description here

Bạn cũng có thể làm màu sắc pha trộn trực tiếp bên trong hàm thay vì giá trị ánh xạ tới một quy mô màu sau đó,

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) 

enter image description here

+0

Cảm ơn câu trả lời! Điều này giải quyết rõ ràng phần kỹ thuật. Vì vậy, nó đi xuống để te câu hỏi về chức năng nào sẽ làm điều này. Độ dốc 2D trên trong pic ở trên dường như rất đơn giản. Tôi vẫn gặp vấn đề trong việc tìm ra chức năng thích hợp cho việc này. Bất kỳ ý tưởng? –

+0

đó là một chút mơ hồ mà không có bối cảnh. Câu hỏi cơ bản bạn đang cố gắng giải quyết là gì? Bản đồ màu này đại diện cho những gì? – baptiste

+0

Tôi có hai biến A và B. Mỗi biến được chia tỷ lệ giữa 0 và 1. 0 cho biết xấu, 1 hiệu suất tốt. Tôi muốn lót mặt phẳng 2D với một đại diện màu thích hợp. Ví dụ. góc dưới bên trái màu đỏ, phía trên bên trái màu xanh lá cây, phía trên bên phải màu xanh lá cây và phía dưới bên phải màu xanh lục. Các vị trí khác nên được nội suy trên một gradient màu đỏ-vàng-xanh lá cây. Tôi đính kèm một hình ảnh mới như thế nào nó sẽ giống như trên (tạo ra với PPT). Những gì tôi không hiểu là làm thế nào để đúng cách sản xuất các màu sắc nằm ở giữa. Tôi nghĩ rằng ví dụ đơn giản của loại hình này là đủ để tôi tìm ra phần còn lại. –

0

Tôi chắc chắn có cách thanh lịch hơn để thực hiện việc này. Dù sao, ở đây bạn đi: dòng cuối cùng là một giải trí khá gần của hình ảnh ban đầu của bạn trong câu hỏi.

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'))) 
Các vấn đề liên quan