Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subplot/facets with wordclouds

I'm trying to make subplots/facets of several wordclouds in a way that's pleasing to the eye.

Problems:

  1. I can't get base R to combine wordcloud-outputs properly
  2. making wordclouds with ggplot2 allows for facetting but yields unsatisfactory results (ugly positioning)

I've tried to two ways to create these wordcloud-subplots.

1. I create an example dataset (following here):

library(dplyr)
library(janeaustenr)
library(tidytext)

df <- austen_books() %>%
  unnest_tokens(word, text) %>% 
  anti_join(stop_words, by = "word") %>%
  group_by(book) %>%
  count(word) %>% 
  top_n(100, n)

2. My first try uses the wordcloud package and base R:

library(wordcloud)

par(mfrow = c(2,2))
png("jane_austen_wordclouds.png")

df %>% 
  filter(book == "Sense & Sensibility") %>% 
  with(wordcloud(word, n))

df %>% 
  filter(book == "Pride & Prejudice") %>% 
  with(wordcloud(word, n))

df %>% 
  filter(book == "Mansfield Park") %>% 
  with(wordcloud(word, n))

df %>% 
  filter(book == "Emma") %>% 
  with(wordcloud(word, n))

title( "Jane Austen Word Clouds", outer = TRUE)
dev.off() 

Creating:

enter image description here

So somehow it only saves the last subplot. If I don't use png("jane_austen_wordclouds.png") and dev.off() and just save the figure straight from RStudio, then I get:

enter image description here

That's also not nice, as it somehow truncates the last three subplots at the top and bottom.

3. Second, I use ggplot (inspired by this):

library(ggplot2)
library(ggrepel)

df %>%
  filter(book %in% c("Sense & Sensibility", "Pride & Prejudice",
                     "Mansfield Park", "Emma")) %>%
  ggplot(., aes(x = 1, y = 1, size = n, label = word)) +
  geom_text_repel(segment.size = 0, segment.alpha = 0) +
  scale_size(range = c(2, 15), guide = FALSE) +
  theme_void() +
  theme(panel.border = element_rect(colour = "black", fill=NA, size=1)) +
  facet_wrap(~book) +
  labs(title = "Jane Austen Word Clouds")
ggsave("jane_austen_gg.png", width = 11, height = 11)

Which creates: enter image description here

That looks strangely drawn out along the diagonal. And wordcloud looks better as it also orients some of the words vertically.

Might there not be a way to insert the pretty wordcloud figures into ggplot?

like image 364
ulima2_ Avatar asked Nov 02 '17 16:11

ulima2_


1 Answers

I believe you may find useful using gridGraphics and gridExtra to save the plots as objects than draw them again in an arranged manner. I've tested the following code and it worked. Fist save each graph in different objects, as follows:

toPlot<-df %>% 
  filter(book == "Sense & Sensibility") 
wordcloud(toPlot$word, toPlot$n, max.words=100, random.order=FALSE, scale=c(3,0.5))
grid.echo()
a <- grid.grab()

#wordcloud2
toPlot2 <- df %>% 
  filter(book == "Pride & Prejudice") 
wordcloud(toPlot2$word, toPlot2$n, max.words=100, random.order=FALSE, scale=c(3,0.5))
grid.echo()
b <- grid.grab()

 #wordcloud3
 toPlot3 <- df %>% 
   filter(book == "Mansfield Park") 
 wordcloud(toPlot3$word, toPlot3$n, max.words=100, random.order=FALSE, scale=c(3,0.5))
grid.echo()
c <- grid.grab()

#wordcloud4
toPlot4 <- df %>% 
  filter(book == "Emma") 
wordcloud(toPlot4$word, toPlot4$n, max.words=100, random.order=FALSE, scale=c(3,0.5))
grid.echo()
d <- grid.grab()

Then, with the 4 objects, you can arrange them according to a given matrix. See this for further information on layouts: https://cran.r-project.org/web/packages/gridExtra/vignettes/arrangeGrob.html. In the following case, the two wordclouds in the second row have a smaller layout than the upper ones:

grid.newpage()
lay <- rbind(c(1,1,1,2,2,2),
             c(1,1,1,2,2,2),
             c(1,1,1,2,2,2),
             c(1,1,1,2,2,2),
             c(3,3,3,4,4,4),
             c(3,3,3,4,4,4))
grid.arrange(a,b,c,d, layout_matrix = lay)

The result should be this image:wordclouds

like image 128
Arthur Netto Avatar answered Nov 13 '22 05:11

Arthur Netto