2013-08-21 24 views
4

如何基於數據集中的列覆蓋ggplot2圖例指南的aes大小值?修改色標圖例指南以匹配ggplot2中的行大小

參考該示例(編輯2:加入試驗C,並改變了線路尺寸使用對數標度):

library(data.table) 
set.seed(26798) 

dt<-rbind(data.table(Trial="A",Value=rweibull(1000,1.0,0.5)), 
     data.table(Trial="B",Value=rweibull(100,1.2,0.75)), 
     data.table(Trial="C",Value=rweibull(10,1.3,0.8))) 

# Add a count and something like a cumulative distribution: 
dt2<-dt[order(Trial,Value),list(Value,N=.N),by=Trial][,list(Value,N,y=1-cumsum(N)/sum(N)),by=Trial] 
dt2 
##  Trial  Value N  y 
## 1:  A 0.0003628745 1000 0.999 
## 2:  A 0.0013002615 1000 0.998 
## 3:  A 0.0017002173 1000 0.997 
## 4:  A 0.0022597343 1000 0.996 
## 5:  A 0.0026608082 1000 0.995 
## ---        
##1096:  B 1.6821827814 100 0.040 
##1097:  B 2.2431595707 100 0.030 
##1098:  B 2.5122479833 100 0.020 
##1099:  B 2.5519954416 100 0.010 
##1100:  B 2.6848412995 100 0.000 

ggplot(dt2) + 
    geom_line(aes(x=Value,y=y,group=Trial,color=Trial,size=N)) + 
    scale_size(range=c(0.1, 2), trans="log") + 
    guides(size=F, color=guide_legend(override.aes=list(size=2))) 

Plot of three trials

我想爲每一個線條的粗細指南圖例中的試用值與曲線中的線條相匹配(即「A」應該較厚,「B」應該較薄)。 編輯1: @Arun和@ChelseaE爲手動調整每個厚度提供了很好的建議,但是我的實際數據集有很多因子水平並且不斷變化,所以我需要它是「動態的」。

@DidzisElferts對類似問題(Control ggplot2 legend look without affecting the plot)的回答顯示瞭如何將大小設置爲靜態值。上例中最後一行的size=2部分讓我更改圖例的線條大小,但我希望它與圖中線條的大小相匹配。改用size=N似乎是合乎邏輯的,但它會給出錯誤「找不到對象'N'」。什麼是正確的語法?

所需的輸出:

Plot of three trials with desired legend

+1

我不明白:如果你想讓行大小對應Trial,爲什麼要將它映射到N? – baptiste

+0

嗯,在我的實現中,我可能沒有正確地做一些事情,但是我的意圖是使用線條粗細來顯示每個試驗的觀察次數不同(由N捕獲)。然後我想讓這個傳說與情節相匹配。我的實際數據有5到10行,而不是兩行,並且在圖例匹配時挑出圖中的線條在視覺上很有幫助。 – dnlbrky

回答

7

你應該爲A和B.你僅有1大小都設置相應的大小。試試這個:

p <- ggplot(dt2) + 
geom_line(aes(x=Value,y=y,group=Trial,color=Trial,size=N)) + 
scale_size(range=c(0.1, 2)) + 
guides(size=FALSE, color=guide_legend(override.aes=list(size=c(2, .1)))) 

繼OP的評論:

好了,在這種情況下,你就必須做更多的工作的(也許還有更簡單的方法,我想不出他們,如果有的話)。

scales <- c(0.1, 2) # the range you want: min, max 
vals <- summary(lm(scales ~ c(min(dt2$N), max(dt2$N))))$coefficients[,1] 
sizes <- vals[2] * unique(dt2$N) + vals[1] 

ggplot(dt2) + 
geom_line(aes(x=Value,y=y,group=Trial,color=Trial,size=N)) + 
scale_size(range=scales) + 
guides(size=FALSE, color=guide_legend(override.aes=list(size=sizes))) 

這應該起作用。嘗試一下,讓我知道你是否有問題。

+0

感謝您的好建議,@Arun。然而,在我的實際數據集中,我有很多不斷變化的值,所以我需要這個更「動態」。我已經更新了這個問題來反映這一點。 – dnlbrky

+0

@dnlbrky,檢出編輯以查看它是否適合您的一般情況。讓我知道你是否有麻煩。 – Arun

+0

謝謝,這條路線的工作。根據偏好,我將使用此修改: 'size = rescale(dt2 [,.N,by = list(Trial)] [order(Trial),log(N)],scales)'。 – dnlbrky

1

嘗試添加guide_legend裏面的尺寸範圍:

ggplot(dt2) + geom_line(aes(x = Value, y = y, group = Trial, color = Trial, size = N)) + scale_size(range = c(0.1, 2)) + guides(size = F, color = guide_legend(override.aes = list(size = range(0.1,2))))

編輯:(可能的工作,不知道)

您也可以嘗試創建N個向量(N <- dt2$N),然後使用size = N

希望這會有所幫助。

相關問題