2015-07-19 14 views
5

Sto provando a creare una scala di colori con una transizione di colore nitida in un punto. Quello che sto facendo attualmente è:Come creare una scala di colori con transizione nitida in ggplot2

test <- data.frame(x = c(1:20), y = seq(0.01, 0.2, by = 0.01)) 

cutoff <- 0.10 

ggplot(data = test, 
     aes(x = as.factor(x), y = y, fill = log(y), width = 1, binwidth = 0)) + 
geom_bar(stat = "identity") + 
scale_fill_gradientn(colours = c("red", "red", "yellow", "green"), 
         values = rescale(log(c(0.01, cutoff - 0.0000000000000001, cutoff, 0.2))), 
         breaks = c(log(cutoff)), label = c(cutoff)) 

Sta producendo le trame che voglio. Ma la posizione della pausa in colorbar varia in qualche modo a seconda del limite. A volte sotto il valore, a volte sopra, a volte sulla linea. Qui ci sono alcuni appezzamenti con differenti tagli (0,05, 0,06, 0,1):

cut off at 0.05 cut off at 0.06 cut off at 0.10

Che cosa sto facendo di sbagliato? O in alternativa, c'è un modo migliore per creare una tale scala di colori?

risposta

0

I think è leggermente complicato ottenere un punto di interruzione preciso e discreto nella scala di colori continua utilizzando scale_fill_gradientn. Un'alternativa rapida sarebbe utilizzare scale_fill_gradient, impostare il valore di soglia con limits e impostare il colore dei valori 'fuori limite' con na.value.

Ecco un esempio leggermente più semplice che nella vostra domanda:

# some data 
df <- data.frame(x = factor(1:10), y = 1, z = 1:10) 

# a cutoff point 
lo <- 4 

ggplot(df, aes(x = x, y = y, fill = z)) + 
    geom_bar(stat = "identity") + 
    scale_fill_gradient(low = "yellow", high = "green", 
         limits = c(lo, max(df$z)), na.value = "red") 

enter image description here

Come vedete, non comparirà valori al di sotto tuo punto di divisione nella leggenda, ma si può prendere in considerazione anche un grande pezzo di rosso uno spreco di "larghezza di banda leggenda" comunque. Potresti semplicemente aggiungere una descrizione verbale delle barre rosse nella didascalia della figura.


È inoltre possibile distinguere tra valori inferiori a un punto di divisione inferiore e sopra un punto di divisione superiore. Ad esempio, imposta valori "troppo bassi" su blu e "valori troppo alti" su rossi. Qui uso findInterval per distinguere tra valori bassi, medi e alti.

# some data 
set.seed(2) 
df <- data.frame(x = factor(1:10), y = 1, z = sample(1:10)) 

# lower and upper limits 
lo <- 3 
hi <- 8 

# create a grouping variable based on the the break points 
df$grp <- findInterval(df$z, c(lo, hi), rightmost.closed = TRUE) 

ggplot(df, aes(x = x, y = y, fill = z)) + 
    geom_bar(stat = "identity") + 
    scale_fill_gradient(low = "yellow", high = "green", limits = c(lo, hi), na.value = "red") + 
    geom_bar(data = df[df$grp == 0, ], fill = "blue", stat = "identity") 

enter image description here

+0

@Hengrui Jiang ha fatto la mia risposta risolto il problema? – Henrik

+1

Grazie per i suggerimenti! Questa è davvero una buona alternativa per l'esempio nella domanda. Ma vedo due problemi qui: 1. i valori al di sotto del cutoff non possono essere "ponderati", ad es. 'colors = c (" red4 "," red "," yellow "," green ")' nel mio mini esempio 2. Penso che il fatto che il taglio non sia illustrato nella legenda rende molto più difficile la comprensione –

Problemi correlati