2014-10-15 23 views
6

Meine Frage ist, dass ich eine abweichende Farbe für meine Heatmap mit geom_tile möchte und die Farbverläufe an beiden Enden der Skala variieren. Zum Beispiel ist die gesamte Skala (-1,1), ich möchte nur die Werte von -1 bis -0,5 und die Werte von 0,5 bis 1,0 haben Gradienten Farbvariation und die Werte zwischen -0,5 und 0,5 bleiben so weiß. Ich kann jedoch keine Option in scale_fill_gradient finden, um das Ziel zu erreichen. Ein reproduzierbares Beispiel ist als unten und die Daten von ggplot2 heatmaps: using different gradients for categoriesWie man "niedrig" und "hoch" festlegt und zwei Skalen an zwei Enden erhält mit scale_fill_gradient

nba <- read.csv("http://datasets.flowingdata.com/ppg2008.csv") 
nba$Name <- with(nba, reorder(Name, PTS)) 

library("ggplot2") 
library("plyr") 
library("reshape2") 
library("scales") 

nba.m <- melt(nba) 
nba.s <- ddply(nba.m, .(variable), transform, 
       rescale = scale(value)) 

ggplot(nba.s, aes(variable, Name))+geom_tile(aes(fill = rescale), colour = "white") + 
scale_fill_gradient(low = "darkgreen", high = "darkred") 

Antwort

8

Sie können versuchen, einen weißen Mittelpunkt zu scale_fill_gradient2 Zugabe:

gg <- ggplot(nba.s, aes(variable, Name)) 
gg <- gg + geom_tile(aes(fill = rescale), colour = "white") 
gg <- gg + scale_fill_gradient2(low = "darkgreen", mid = "white", high = "darkred") 
gg <- gg + labs(x="", y="") 
gg <- gg + theme_bw() 
gg <- gg + theme(panel.grid=element_blank(), panel.border=element_blank()) 
gg 

enter image description here

Aber, haben Sie die größte Flexibilität Wenn Sie die Antwort in dem SO-Post befolgen, mit dem Sie verbunden sind, und verwenden Sie scale_fill_gradientn.

EDIT

# change the "by" for more granular levels 

green_seq <- seq(-5,-2.000001, by=0.1) 
red_seq <- seq(2.00001, 5, by=0.1) 

nba.s$cuts <- factor(as.numeric(cut(nba.s$rescale, 
          c(green_seq, -2, 2, red_seq), include.lowest=TRUE))) 

# find "white" 
white_level <- as.numeric(as.character(unique(nba.s[nba.s$rescale >= -2 & nba.s$rescale <= 2,]$cuts))) 
all_levels <- sort(as.numeric(as.character(unique(nba.s$cuts)))) 

num_green <- sum(all_levels < white_level) 
num_red <- sum(all_levels > white_level) 

greens <- colorRampPalette(c("#006837", "#a6d96a")) 
reds <- colorRampPalette(c("#fdae61", "#a50026")) 

gg <- ggplot(nba.s, aes(variable, Name)) 
gg <- gg + geom_tile(aes(fill = cuts), colour = "white") 
gg <- gg + scale_fill_manual(values=c(greens(num_green), 
             "white", 
             reds(num_red))) 
gg <- gg + labs(x="", y="") 
gg <- gg + theme_bw() 
gg <- gg + theme(panel.grid=element_blank(), panel.border=element_blank()) 
gg <- gg + theme(legend.position="bottom") 
gg 

enter image description here

Die Legende (ein Beispiel aus dem Kommentar Diskussion zeigen) bei weitem nicht ideal ist, aber Sie können potenziell es oder Arbeit um sie durch andere Mittel auszuschließen.

+0

Danke für die Antwort! Ich möchte jedoch alle Werte, in diesem Fall von -2 bis 2, werden alle weiß ohne Farbverlauf-Effekt ... – MYjx

+0

Wenn dies und die 'Gradienten'-Lösung nicht funktionieren, dann müssen Sie Ihre tun eigene 'cuts' der Werte und manuell die Farbverläufe mit' scale_fill_manual' angeben. – hrbrmstr

+0

yep Ich habe 'scale_fill_manual' versucht, es hat funktioniert, aber ich möchte nicht die Farbe jedes Mal angeben, da ich viele Daten jeden Tag habe. Deshalb möchte ich "Gradienten" verwenden. Ich habe versucht, 'Breaks' zu verwenden, aber es scheint nur für die Legende zu funktionieren, nicht für die Farbe selbst. – MYjx

Verwandte Themen