Как поместить облако слов в гроб?
Я создал простое облако слов:
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)
Я хотел бы поместить это в "гроб", чтобы я мог организовать его с несколькими другими сюжетами, используя grid.arrange()
в пакете gridExtra
:
require(ggplot2)
p1 <- qplot(1:10, rnorm(10), colour = runif(10))
require(gridExtra)
grid.arrange(p1, my.wordcloud)
Я понимаю, что мое wordcloud должно быть "гробом", чтобы сделать это, но я не понимаю, как это сделать. Я попытался использовать функцию grob()
в пакете gridExtra
, но это не сработало. Предложения?2 ответа:
Не должно быть так сложно адаптировать код в
wordcloud
, чтобы построить данные, необходимые для заполнения текста.гроб в сетке. Кодwordcloud
отправляет значения x, y, text и rot в базовую функциюtext
после того, как задано окно с пределами 0,0 и 1, 1.Мне нужно было добавить это перед циклом 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
Вы можете использовать пакет
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))
Редактировать использовать
knitr
Если вы хотите просто создать PDF-файл.Еще один вариант, если вы хотите просто создать pdf, вы можете использовать
Knitr
. Смешивание сетки и базовой графики очень просто. Латекс сделает эту работу за вас. Например, приведенный выше результат может быть получен с помощью этого блока.<<mixgridwithggplot, fig.show='hold',out.width='.5\\linewidth'>>= wordcloud(words, freqs) qplot(1:10, rnorm(10), colour = runif(10)) @
Я почти уверен, что
knitr
может создать png 2 участка в одном png за кодом.