2017-10-08 2 views
0

これは私が最近尋ねた質問の続きです(Manually assigning colors with scale_fill_manual only works for certain hexagon sizes)。色の手動割り当てのための六角形と凡例の一致

すべての六角形が同じサイズになるようにgeom_hex()をプロットできませんでした。誰かが問題を解決しました。しかし、その解決策は凡例キーを削除しました。今、六角形をすべて同じサイズに保つことができず、凡例も保持できません。

具体的には、私は本当に伝説のラベルをセンセーショナルにしたいと思っています。以下の例では、凡例は16進数のラベル(#08306B、#08519Cなど)ではなく、値(0,2,4,6,8,20)を持っています。

以下は、問題を示すMWEです。最後に、3つのコメントごとに、私は1)六角形のサイズは統一されているが凡例は作成されていないこと、2)凡例は一貫しない六角形のプロットを作成できること、3)一貫性のある六角サイズや伝説を持つプロットが、失敗:伝説を維持しながら、一貫性のあるサイズの六角形を維持する方法について

library(ggplot2) 
library(hexbin) 
library(RColorBrewer) 
library(reshape) 

set.seed(1) 
xbins <- 10 

x <- abs(rnorm(10000)) 
y <- abs(rnorm(10000)) 
minVal <- min(x, y) 
maxVal <- max(x, y) 
maxRange <- c(minVal, maxVal) 
buffer <- (maxRange[2] - maxRange[1])/(xbins/2) 
bindata = data.frame(x=x,y=y,factor=as.factor(1)) 

h <- hexbin(bindata, xbins = xbins, IDs = TRUE, xbnds = maxRange, ybnds = maxRange) 

counts <- hexTapply (h, bindata$factor, table) 
counts <- t (simplify2array (counts)) 
counts <- melt (counts) 
colnames (counts) <- c ("factor", "ID", "counts") 
counts$factor =as.factor(counts$factor) 

hexdf <- data.frame (hcell2xy (h), ID = [email protected]) 
hexdf <- merge (counts, hexdf) 

my_breaks <- c(2, 4, 6, 8, 20, 1000) 
clrs <- brewer.pal(length(my_breaks) + 3, "Blues") 
clrs <- clrs[3:length(clrs)] 
hexdf$countColor <- cut(hexdf$counts, breaks = c(0, my_breaks, Inf), labels = rev(clrs)) 

# Has consistent hexagon sizes, but no legend 
ggplot(hexdf, aes(x=x, y=y, hexID=ID, counts=counts, fill=countColor)) + geom_hex(stat="identity", fill=hexdf$countColor) + scale_fill_manual(labels = as.character(c(0, my_breaks)), values = rev(clrs), name = "Count") + geom_abline(intercept = 0, color = "red", size = 0.25) + labs(x = "A", y = "C") + coord_fixed(xlim = c(-0.5, (maxRange[2]+buffer)), ylim = c(-0.5, (maxRange[2]+buffer))) + theme(aspect.ratio=1) 

# Has legend, but inconsistent hexagon sizes 
ggplot(hexdf, aes(x=x, y=y, hexID=ID, counts=counts, fill=countColor)) + geom_hex(data=hexdf, stat="identity", aes(fill=countColor)) + scale_fill_manual(labels = as.character(c(0, my_breaks)), values = rev(clrs), name = "Count") + geom_abline(intercept = 0, color = "red", size = 0.25) + labs(x = "A", y = "C") + coord_fixed(xlim = c(-0.5, (maxRange[2]+buffer)), ylim = c(-0.5, (maxRange[2]+buffer))) + theme(aspect.ratio=1) 

# One attempt to create consistent hexagon sizes and retain legend 
ggplot(hexdf, aes(x=x, y=y, hexID=ID, counts=counts, fill=countColor)) + geom_hex(data=hexdf, aes(fill=countColor)) + geom_hex(stat="identity", fill=hexdf$countColor) + scale_fill_manual(labels = as.character(c(0, my_breaks)), values = rev(clrs), name = "Count") + geom_abline(intercept = 0, color = "red", size = 0.25) + labs(x = "A", y = "C") + coord_fixed(xlim = c(-0.5, (maxRange[2]+buffer)), ylim = c(-0.5, (maxRange[2]+buffer))) + theme(aspect.ratio=1) 

任意の提案は非常に参考になります!

enter image description here

答えて

2

うわー、これは興味深いものである - geom_hexは本当にカテゴリ変数に埋める/マッピングの色を嫌っているようです。 2次元のヒストグラムであり、継続的な要約統計量を視覚化するように設計されているからだと思いますが、背後で何が起こっているかについて誰かが洞察しているなら、私は知りたいです。

個々の六角形に非線形のグループを割り当てるカテゴリ化された色付けを試みているため、具体的な問題については、実際にレンチがスローされます。概念的には、なぜあなたはそれをやっているのか考えてみてください。正当な理由があるかもしれませんが、基本的に線形の色勾配をとり、それを非線形にデータにマッピングすると、視覚的に誤解を招く恐れがあります。

しかし、そうしたい場合は、選択した色に線形にマッピングされた新しい連続変数を作成し、それらを使用してカラーグラデーションを作成することをお勧めします。あなたが私の思考過程を歩いてみましょう。

本質的に、色にマップする連続変数(counts)があります。簡単な色のグラデーションでは簡単ですが、これは連続変数のggplot2のデフォルトです。あなたのデータを使用:

ggplot(hexdf, aes(x=x, y=y)) + 
    geom_hex(stat="identity", aes(fill=counts)) 

何かが近づく。

First try

しかし、本当に高いカウントを持つビンがはるかに低いカウントのポイントの勾配を洗い流すので、我々は勾配が値に色をマップする方法を変更する必要があります。あなたは既にclrs変数で使用する色を宣言しました。スムーズなグラデーションを作成するために、これらのカラーと組み合わせて使用​​するためにデータフレームにカラムを追加するだけです。

all_breaks <- c(0, my_breaks) 
breaks_n <- 1:length(all_breaks) 
get_break_n <- function(n) { 
    break_idx <- max(which((all_breaks - n) < 0)) 
    breaks_n[break_idx] 
} 
hexdf$bin <- sapply(hexdf$counts, get_break_n) 

を私たちはそれを超えることなく、カウント変数最も近いブレークの指標としてbin変数を作成します。私は次のようにすることをしませんでした。さて、あなたはそれに気づくでしょう:

ggplot(hexdf, aes(x=x, y=y)) + 
    geom_hex(stat="identity", aes(fill=bin)) 

は目標にもっと近づいています。

Added bin variable

次のステップでは、我々はscale_fill_gradientnへの呼び出しを追加することによって行うことができますbin変数、上にどのように色のグラデーションマップを変更することです:

ggplot(hexdf, aes(x=x, y=y)) + 
    geom_hex(stat="identity", aes(fill=bin)) + 
    scale_fill_gradientn(colors=rev(clrs[-1])) # odd color reversal to 
              # match OP's color mapping 

これは間の色のベクトルを取りますあなたはグラデーションを補間します。補間に沿ったポイントは、bin変数の一意の値と完全に一致します。これは、各値が指定された色の1つを取得することを意味します。

Custom color gradient for bin variable

今、私たちはガスで調理していて、唯一のことはやって左に元のグラフから、様々な添えものを追加することです。最も重要なのは、伝説を私たちが望むように見せる必要があるということです。これには、(1)デフォルトカラーバーから離散凡例に変更する、(2)独自のカスタムラベルを指定する、(3)有益なタイトルを付ける、の3つが必要です。

# create the custom labels for the legend 
all_break_labs <- as.character(all_breaks[1:(length(allb)-1)]) 

ggplot(hexdf, aes(x=x, y=y)) + 
    geom_hex(stat="identity", aes(fill=bin)) + 
    scale_fill_gradientn(colors=rev(clrs[-1]), 
         guide="legend",  # (1) make legend discrete 
         labels=all_break_labs, # (2) specify labels 
         name="Count") +  # (3) legend title 
    # All the other prettification from the OP 
    geom_abline(intercept = 0, color = "red", size = 0.25) + 
    labs(x = "A", y = "C") + 
    coord_fixed(xlim = c(-0.5, (maxRange[2]+buffer)), 
       ylim = c(-0.5, (maxRange[2]+buffer))) + 
    theme(aspect.ratio=1) 

このすべてが次のグラフで私たちを残します:

Final hex plot

うまくいけば、あなたを助けます。完全なコードは次のとおりです。

# ... the rest of your code before the plots 
clrs <- clrs[3:length(clrs)] 
hexdf$countColor <- cut(hexdf$counts, 
         breaks = c(0, my_breaks, Inf), 
         labels = rev(clrs)) 

### START OF NEW CODE ### 

# create new bin variable 
all_breaks <- c(0, my_breaks) 
breaks_n <- 1:length(all_breaks) 
get_break_n <- function(n) { 
    break_idx <- max(which((all_breaks - n) < 0)) 
    breaks_n[break_idx] 
} 
hexdf$bin <- sapply(hexdf$counts, get_break_n) 

# create legend labels 
all_break_labs <- as.character(all_breaks[1:(length(all_breaks)-1)]) 

# create final plot 
ggplot(hexdf, aes(x=x, y=y)) + 
    geom_hex(stat="identity", aes(fill=bin)) + 
    scale_fill_gradientn(colors=rev(clrs[-1]), 
         guide="legend", 
         labels=all_break_labs, 
         name="Count") + 
    geom_abline(intercept = 0, color = "red", size = 0.25) + 
    labs(x = "A", y = "C") + 
    coord_fixed(xlim = c(-0.5, (maxRange[2]+buffer)), 
       ylim = c(-0.5, (maxRange[2]+buffer))) + 
    theme(aspect.ratio=1) 
+0

幻想的で詳細なソリューションをありがとう!はい、あなたは正しいです。私は実際に連続性を示すために伝説のラベルを変更しています。この場合、all_break_labsは実際には "0-2"、 "2-4"、 "4-6"、 "6-8"、 "8-20"、 "20+" –

関連する問題