2012-08-02 63 views
20

3面色勾配(ヒートマップ)をtriplot(三角プロット)に塗りつぶすにはどうすればよいですか?色はtriplotに並列に実行する必要があります3方向色グラデーションの塗りつぶしr

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) 

enter image description here

。ここで

答えて

22

はそれを行うための一つの方法である - それは作品によって勾配ピースをプロットするポイントを使用して、ハックのビットです:

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

そして出力:

enter image description here

はなかったですこれらの勾配を使用してデータを表現したいですか?もしそうなら、d.red,d.greend.blueに変更することができます。私はまだそれをテストしていません。これはやや役立つと思っていますが、例えばcolorRampを使った適切な解決策がおそらくもっと良いでしょう。

EDIT:バプティストの提案によれば、これは情報をベクターに格納して一度にプロットする方法です。それは、(特に例えば500からsmセットで)かなり速いです:

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

おかげで...私は別のカップルを試してみた – jon

+1

勾配外観は、よりシャープなように、より濃い色(赤、緑、青)で起動する方法がありますグラデーションを鮮明にするためのものですが、グラフの領域を非常に暗く鈍くしない方法を見つけることができませんでした。あなたは、赤、緑、青のコーナーで始まっても大丈夫ですか?もしあなたがそうであれば、最後のコード行を 'points(x、y、col = rgb(d.red、d.green、d。青)、pch = 19) ' - 3つの色のグラデーションは、他の色とあまり混合しないため、より鮮明に見えます。 – Edward

+2

なぜ個々のポイントを個別にプロットするのですか?あなたは色のベクトルを保存し、すべての点を一度にプロットすることができます。 – baptiste

14

ここでラスタライズされた背景画像とのソリューションです。 tricol関数のsharpnessパラメータは、色が黒になるまでの速さを制御します。これを1に設定すると、Edwardの色が2に設定され、下の色が表示されます。何tricol()

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

色(赤、緑、青)を用いて各コーナーiを表しています。コーナーからptの点までのベクトルaとコーナーから反対側の端の中心までのベクトルbを定義します。次にabに投影し、相対的な距離=色の濃さを得るために縮尺を変えます(色を少し調整するためにsharpnessで小さなハックを適用します)。このような問題になると、この単純な代数は魔法を働かせることができます。

エイリアシングのためにエッジの周りにリッジノイズが発生しますが、それを微調整したり、三角形内に少し幅のある線を引くことができます。ここで Gradient triangle

+0

私は同様の考え方を考えていましたが、半径の三つの円盤(R、G、B)が三角形の側面にあり、アルファチャンネルが0にフェーディングしていました。私はRが自動的に色混合を行うと信じています。 – baptiste

+0

並べ替えどのサークルが他のサークルの上に描かれているかを示します。赤色が上、次に緑色、次に青色になるとしましょう。真ん中には50%の赤がありますが、緑色は25%(リマイング50%の50%)、青色は12.5%です。私が見たVennダイアグラムのほとんどは、これに苦しんでいます。一度それを見たら、それに気づくのをやめることはできません。 [これらの例を取る](http://stackoverflow.com/questions/8713994/venn-diagram-in-r-proportional-and-color-shading-possible-semi-transparency-sup) – Backlin

1

あなたがそれにアクセスするために:::演算子を使用する必要がありますのでfillTriangle関数がエクスポートされません...私はphonRパッケージのために後処理実装です。例は、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) 

example graphs of gradient triangle filling

関連する問題