2012-04-28 49 views
4

我有以下情節:爲geom_text圖層顯示單獨的圖例?

library(ggplot2) 

ib<- data.frame(
    category = factor(c("Cat1","Cat2","Cat1", "Cat1", "Cat2","Cat1","Cat1", "Cat2","Cat2")), 
    city =  c("CITY1","CITY1","CITY2","CITY3", "CITY3","CITY4","CITY5", "CITY6","CITY7"), 
    median =  c(1.3560, 2.4830, 0.7230, 0.8100, 3.1480, 1.9640, 0.6185, 1.2205, 2.4000), 
    samplesize = c(851, 1794, 47, 189, 185, 9, 94, 16, 65) 
) 


p<-ggplot(data=ib, aes(x=city, y=category, size=median, colour=category, label=samplesize)) + 
    geom_point(alpha=.6) + 
    scale_area(range=c(1,15)) + 
    scale_colour_hue(guide="none") + 
    geom_text(aes(size = 1), colour="black") 
p 

(我繪製的圓圈比例的中位值和文本標籤覆蓋佔樣本量爲http://imgur.com/T82cF圖像)

有什麼辦法分離這兩個傳說?我希望有一個傳說(標記爲「中位數」)給出圓圈的比例,另一個傳說用單個字母「a」(或者更好的數字)來標註「樣本量」。由於這兩個屬性沒有任何關係,因此將它們捆綁在同一個圖例中是沒有意義的。

我已經試過各種組合,但最好我能想出是完全失去了文字提示:)

感謝您的回答!

+0

我認爲挑戰將是嘗試應用兩種不同大小的映射。請參閱@ joran的評論[這裏](http://stackoverflow.com/questions/10359963/edits-in-a-ggplot2-geom-line)和解決方案(指不同的顏色映射)。但我不明白這種解決方案如何輕鬆應用於您的問題。 – 2012-04-28 22:38:47

+0

根據[kohske的評論](http://stackoverflow.com/questions/10405823/changing-the-symbol-in-the-legend-key-in-ggplot2),我改變了情節,繪製情況「N」而不是小寫「a」。 – 2012-05-02 02:55:19

回答

4

更新scale_area已棄用;改用scale_sizegtable函數gtable_filter()用於提取圖例。修改後的代碼用於替換其中一個圖例中的默認圖例關鍵字。

如果你仍然在尋找你的問題的答案,這裏似乎是你想要的大部分,儘管這是一個地方的黑客。圖例中的符號可以使用kohske's comment here

難度試圖應用兩種不同大小的映射。所以,我在美學聲明中留下了點尺寸映射,但是從美學聲明中刪除了標籤尺寸映射。這意味着標籤大小必須根據samplesize(fsamplesize)的因子版本的離散值進行設置。得到的圖表幾乎是正確的,但標籤大小的圖例(即樣本大小)未繪製。爲了解決這個問題,我繪製了一個圖表,其中包含根據樣本大小因子版本(但忽略點大小映射)的標籤大小映射,以便提取其圖例,然後可以將其插入到第一個圖表中。

## Your data 
ib<- data.frame(
    category = factor(c("Cat1","Cat2","Cat1", "Cat1", "Cat2","Cat1","Cat1", "Cat2","Cat2")), 
    city =  c("CITY1","CITY1","CITY2","CITY3", "CITY3","CITY4","CITY5", "CITY6","CITY7"), 
    median =  c(1.3560, 2.4830, 0.7230, 0.8100, 3.1480, 1.9640, 0.6185, 1.2205, 2.4000), 
    samplesize = c(851, 1794, 47, 189, 185, 9, 94, 16, 65) 
) 

## Load packages 
library(ggplot2) 
library(gridExtra) 
library(gtable) 
library(grid) 

## Obtain the factor version of samplesize. 
ib$fsamplesize = cut(ib$samplesize, breaks = c(0, 100, 1000, Inf)) 

## Obtain plot with dot size mapped to median, the label inside the dot set 
## to samplesize, and the size of the label set to the discrete levels of the factor 
## version of samplesize. Here, I've selected three sizes for the labels (3, 6 and 10) 
## corresponding to samplesizes of 0-100, 100-1000, >1000. The sizes of the labels are 
## set using three call to geom_text - one for each size. 

p <- ggplot(data=ib, aes(x=city, y=category)) + 
    geom_point(aes(size = median, colour = category), alpha = .6) + 
    scale_size("Median", range=c(0, 15)) + 
    scale_colour_hue(guide = "none") + theme_bw() 

p1 <- p + 
    geom_text(aes(label = ifelse(samplesize > 1000, samplesize, "")), 
     size = 10, color = "black", alpha = 0.6) + 
    geom_text(aes(label = ifelse(samplesize < 100, samplesize, "")), 
     size = 3, color = "black", alpha = 0.6) + 
    geom_text(aes(label = ifelse(samplesize > 100 & samplesize < 1000, samplesize, "")), 
     size = 6, color = "black", alpha = 0.6) 


## Extracxt the legend from p1 using functions from the gridExtra package 
g1 = ggplotGrob(p1) 
leg1 = gtable_filter(g1, "guide-box") 


## Keep p1 but dump its legend 
p1 = p1 + theme(legend.position = "none") 


## Get second legend - size of the label. 
## Draw a dummy plot, using fsamplesize as a size aesthetic. Note that the label sizes are 
## set to 3, 6, and 10, matching the sizes of the labels in p1. 

dummy.plot = ggplot(data = ib, aes(x = city, y = category, label = samplesize)) + 
    geom_point(aes(size = fsamplesize), colour = NA) + 
    geom_text(show.legend = FALSE) + theme_bw() + 
    guides(size = guide_legend(override.aes = list(colour = "black", shape = utf8ToInt("N")))) + 
scale_size_manual("Sample Size", values = c(3, 6, 10), 
    breaks = levels(ib$fsamplesize), labels = c("< 100", "100 - 1000", "> 1000")) 

## Get the legend from dummy.plot using functions from the gridExtra package 
g2 = ggplotGrob(dummy.plot) 
leg2 = gtable_filter(g2, "guide-box") 


## Arrange the three components (p1, leg1, leg2) using functions from the gridExtra package 
## The two legends are arranged using the inner arrangeGrob function. The resulting 
## chart is then arranged with p1 in the outer arrrangeGrob function. 
ib.plot = arrangeGrob(p1, arrangeGrob(leg1, leg2, nrow = 2), ncol = 2, 
     widths = unit(c(9, 2), c("null", "null"))) 

## Draw the graph 
grid.newpage() 
grid.draw(ib.plot) 

enter image description here

+0

哇@Sandy,謝謝你的努力!這很棒,非常感謝! – Krizbi 2012-05-01 09:09:01

+0

請參閱[這裏](https://github.com/hadley/ggplot2/wiki/Share-a-legend-between-two-ggplot2-graphs),以更加可靠地處理圖例寬度。 – baptiste 2012-05-01 09:17:06

1

這實際上並不直接解決您的問題,但它我怎麼可能去與一般特性創建圖形你描述:

ib$ss <- paste("n = ",ib$samplesize,sep = "") 

ggplot(data=ib, aes(x=city, y=category, size=median, colour=category, label=ss)) + 
    geom_point(alpha=.6) + 
    geom_text(size = 2, vjust = -1.2,colour="black") + 
    scale_colour_hue(legend = FALSE) 

我刪除了scale_area片,因爲我我不知道它的用途是什麼,它對我造成了錯誤。

所以這裏的基本原理是樣本量信息更像是對我的註釋,而不是一些值得自己的規模和傳說的東西。當然,意見可能會有所不同,但我認爲如果你覺得它有用,我會把它放在那裏。

enter image description here

+0

謝謝@joran,這是可行的,然而,我在最後的情節(大約30個城市和100個類別)中的空間非常狹窄,所以我更願意在情節之外描述這些數字的含義。我同意這不是最好的解決方案,但我無法承受劇情本身的那麼多文字...... – Krizbi 2012-04-28 20:50:30

+0

@Krizbi我想通了。雖然,正在繪製>(30 x 100)個繪圖上的單個數字比每個數字前面都有「n =」更具可讀性? – joran 2012-04-29 00:55:24

+0

你確實有一點 - 當然,我已經在這個情節的「信息超載」區域(即使沒有數字):)。因此,我希望儘可能多地使用額外的文本。一個「n =」爲平均2-3位數的數字增加了4個字符空間,所以我認爲這種影響和視覺混亂是相當可觀的。想想我想要實現的元素週期表中的數據(例如http://www.ptable.com/),每個元素都有幾條信息,我們有一個關於如何閱讀它們(第一行中的第二個框)。 – Krizbi 2012-04-29 06:54:06

0

這也不會回答你的問題。我已經在圈內留下了samplesize。另外,對我而言,samplesize更像是一個註釋而不是傳說。 但我認爲你使用的是舊版本的ggplot2。版本0.9.0在ggplot2中發生了一些變化。我已經做出以下更改。

p<-ggplot(data=ib, aes(x=city, y=category, size=median, colour=category, label=samplesize)) + 
    geom_point(alpha=.6) + 
    scale_area(range = c(1,15)) + # range instead of to 
    scale_colour_hue(guide = "none") + # guide instead of legend 
    geom_text(size = 2.5, colour="black") 
p 

enter image description here

+0

謝謝@Sandy,的確,它似乎我正在使用舊版本 - 我沒有升級,但不知何故忘了重新啓動Rstudio :) – Krizbi 2012-04-28 21:53:47