2017-02-24 69 views
5

我試圖在ggplot2中顯示多個圖層,但是我想爲每個圖層使用不同的scale_fill_配色方案。我似乎無法做到這一點,因爲撥打scale_fill_gradientn這樣的東西只是用第二次覆蓋第一個電話。在`ggplot2`中使用多個`scale_fill_`

library(ggplot2) 
library(reshape2) 
library(RColorBrewer) 
set.seed(123) 

我會先繪製一個tile格(請注意我設置的顏色與scale_fill_gradientn):

foo <- matrix(data = rnorm(100), ncol = 10) 
foo <- melt(foo) 

plot <- ggplot() + 
    geom_tile(data = foo, 
      mapping = aes(x = Var1, y = Var2, fill = value)) + 
    scale_fill_gradientn(
    colours = rev(brewer.pal(7, "BrBG")) 
) 
plot 

enter image description here

現在我想換一種劇情之上那一個,但有一個獨特的配色方案。我可以創建一個不同的情節就好:

bar <- data.frame(x = rnorm(100, 4, 1), 
        y = rnorm(100, 6, 1.5)) 

ggplot() + 
    stat_density_2d(data = bar, 
        mapping = aes(x = x, y = y, fill = ..level..), 
        geom = "polygon") + 
    scale_fill_gradientn(
    colours = rev(brewer.pal(7, "Spectral")) 
) + xlim(0, 10) + ylim(0, 10) 

enter image description here

我想要做的是情節上的第一個頂部的第二曲線,但保持你在上面看到的配色方案。如果我嘗試簡單地在第一層上添加第二層,我將覆蓋原始的scale_fill_gradientn,並強制這兩層共享一種配色方案(在這種情況下,也會「壓縮」第二層完全落入一種顏色:

plot <- plot + 
    stat_density_2d(data = bar, 
        mapping = aes(x = x, y = y, fill = ..level..), 
        geom = "polygon") + 
    scale_fill_gradientn(
    colours = rev(brewer.pal(7, "Spectral")) 
) + xlim(0, 10) + ylim(0, 10) 
plot 

enter image description here

是否有指定每一層單獨的配色方案的方法嗎?我注意到,例如,stat_density_2d理解一個colour審美,但我已經試過指定一個無濟於事(它僅在圖例中添加顏色作爲標籤,並將顏色方案恢復爲默認):

ggplot() + 
    stat_density_2d(data = bar, 
        mapping = aes(x = x, y = y, fill = ..level.., colour = "red"), 
        geom = "polygon") + 
    xlim(0, 10) + ylim(0, 10) 

enter image description here

我覺得必須有一個不同的方法來設置「每個層」的基礎上的配色方案,但我清楚地找錯了地方。

+2

每個圖只能有一個填充比例。 – Roland

+0

謝謝羅蘭,我明白了,那就是我反彈的障礙。我想我正在尋找另一種設置顏色方案的方法,以便我可以解決這個限制? – rosscova

+1

如果您對一個圖例感到滿意,您可以將兩個比例組合成一個比例。如果你想要兩個比例尺,你需要使用'ggplotGrob',然後在'grid'級別進行破解,即從第二個圖中提取需要的庫,並將它們添加到第一個圖中。不過,我相信有兩個填充圖例的情節是一個糟糕的情節。 – Roland

回答

5

解決此限制的一種方法是映射到顏色,而不是(如您已經暗示的那樣)。這就是:

我們保留基礎柵格圖,然後添加:

plot + 
    stat_density_2d(data = bar, 
        mapping = aes(x = x, y = y, col = ..level..), 
        geom = "path", size = 2) + 
    scale_color_gradientn(
    colours = rev(brewer.pal(7, "Spectral")) 
) + xlim(0, 10) + ylim(0, 10) 

這給我們:

enter image description here

這並不完全令人滿意,主要是因爲鱗片有相當多的感知重疊(我認爲)。玩弄不同的尺度,絕對可以爲我們提供了一個更好的結果:

plot <- ggplot() + 
    geom_tile(data = foo, 
      mapping = aes(x = Var1, y = Var2, fill = value)) + 
    viridis::scale_fill_viridis(option = 'A', end = 0.9) 

plot + 
    stat_density_2d(data = bar, 
        mapping = aes(x = x, y = y, col = ..level..), 
        geom = "path", size = 2) + 
    viridis::scale_color_viridis(option = 'D', begin = 0.3) + 
    xlim(0, 10) + ylim(0, 10) 

enter image description here

還沒在我看來偉大的(使用多個色標是混亂的我),但更多的容忍。

+0

謝謝@Axeman,這當然確實給了一個解決方法,這是太棒了。它似乎將「密度」圖限制爲線條而不是填充,是嗎? – rosscova

+1

正確。 「填充」不能有兩個比例。 – Axeman