2013-03-23 52 views
2

我創建了一個簡單的wordcloud:如何在grob中放置wordcloud?

require(wordcloud)  
words <- c('affectionate', 'ambitious', 'anxious', 'articulate', 'artistic', 'caring', 'contented', 'creative', 'cynical', 'daring', 'dependable', 'easygoing', 'energetic', 'funny', 'generous', 'genuine', 'goodlistener', 'goodtalker', 'happy', 'hardworking', 'humerous', 'impulsive', 'intelligent', 'kind', 'loyal', 'modest', 'optimistic', 'outgoing', 'outrageous', 'passionate', 'perceptive', 'physicallyfit', 'quiet', 'rational', 'respectful', 'romantic', 'shy', 'spiritual', 'spontaneous', 'sweet', 'thoughtful', 'warm') 
freqs <- c(134, 53, 0, 5, 0, 247, 0, 78, 0, 0, 134, 178, 79, 344, 63, 65, 257, 0, 109, 113, 0, 0, 107, 51, 199, 24, 67, 232, 0, 109, 24, 28, 29, 2, 105, 70, 0, 35, 64, 156, 66, 45) 
wordcloud(words, freqs) 

我想放入「GROB」,這樣我可以在gridExtra包使用grid.arrange()其他幾個情節安排吧:

require(ggplot2) 
p1 <- qplot(1:10, rnorm(10), colour = runif(10)) 
require(gridExtra) 
grid.arrange(p1, my.wordcloud) 

我明白我的wordcloud必須是一個「grob」來做到這一點,但我不明白如何做到這一點。我嘗試使用gridExtra包中的grob()函數,但這不起作用。建議?

+2

也許這是有用的:http://stackoverflow.com/questions/14124373/combine-base-and-ggplot-graphics-in-r-figure-window/14125768#14125768 – 2013-03-23 06:44:13

+1

wordcloud的繪圖方法使用base圖形,而不是網格圖形(因此沒有grob可以封裝圖形,或者它必須從頭開始編寫)。你最好的選擇是遵循gridBase包的例子。 – baptiste 2013-03-23 07:51:58

+1

相關:http:// stackoverflow。com/questions/11253765/geom-wordcloud-is-this-a-pipe-dream – Spacedman 2013-03-23 19:25:10

回答

8

要使wordcloud中的代碼適合於構造填充grid.grob格式的數據,應該不是那麼困難。 wordcloud代碼在指定限制爲0,0和1,1的窗口之後,將x,y,文本和rot值發送到基址text函數。

我需要之前添加此for循環:

textmat <- data.frame(x1=rep(NA, length(words)), y1=NA, words=NA_character_, 
         rotWord=NA, cexw=NA, stringsAsFactors=FALSE) 

這在結束for循環:

textmat[i, c(1,2,4,5) ] <- c(x1=x1, y1=y1, rotWord=rotWord*90, cexw = size[i]) 
textmat[i, 3] <- words[i] 

而到了呼叫修改爲.overlap需要的,因爲它顯然沒有輸出:

if (!use.r.layout) 
     return(wordcloud:::.overlap(x1, y1, sw1, sh1, boxes)) 

而且我在循環完成後無形地返回它:

return(invisible(textmat[-1, ])) # to get rid of the NA row at the beginning 

將其命名後wordcloud2:

> tmat <- wordcloud2(c(letters, LETTERS, 0:9), seq(1, 1000, len = 62)) 
> str(tmat) 
'data.frame': 61 obs. of 5 variables: 
$ x1  : num 0.493 0.531 0.538 0.487 ... 
$ y1  : num 0.497 0.479 0.532 0.475 ... 
$ words : chr "b" "O" "M" ... 
$ rotWord: num 0 0 0 0 0 0 0 0 0 ... 
$ cexw : num 0.561 2.796 2.682 1.421 ... 

draw.text <- function(x,y,words,rotW,cexw) { 
    grid.text(words, x=x,y=y, rot=rotW, gp=gpar(fontsize=9*cexw)) } 

for(i in 1:nrow(tmat)) { draw.text(x=tmat[i,"x1"], y=tmat[i,"y1"], 
            words=tmat[i,"words"], rot=tmat[i,"rotWord"], 
            cexw=tmat[i,"cexw"]) } 

至於建議:

with(tmat, grid.text(x=x1, y=y1, label=words, rot=rotWord, 
         gp=gpar(fontsize=9*cexw)) } # untested 
+0

fontsize = 9 * cexw中的幻數「9」來自哪裏? – Spacedman 2013-03-23 09:26:58

+0

我只是從cex轉換爲字體大小。如果您願意,可以選擇不同的尺寸作爲默認尺寸。 – 2013-03-23 09:29:09

+0

參數textGrob被矢量化,所以你可以不用最後的for循環並返回一個單獨的textGrob。 – baptiste 2013-03-23 09:38:25

3

可以使用gridBase包,但一個聰明的視口。這裏我使用vpStack來獲得良好的尺寸。

par(mfrow=c(1, 2)) 
wordcloud(words, freqs) 
plot.new()    
vps <- baseViewports() 
p <- qplot(1:10, rnorm(10), colour = runif(10)) 
print(p,vp = vpStack(vps$figure,vps$plot)) 

enter image description here

編輯使用knitr如果你只想生成PDF。

另一種選擇,如果你只是想創建一個PDF你可以使用Knitr。混合網格和基礎圖形非常簡單。 Latex將爲你完成這項工作。例如,上面的結果可以通過這個塊獲得。

<<mixgridwithggplot, fig.show='hold',out.width='.5\\linewidth'>>= 
wordcloud(words, freqs) 
qplot(1:10, rnorm(10), colour = runif(10)) 
@ 

我敢肯定,knitr可以在後面的代碼的單個PNG創建2個地塊的PNG。