Megan Cytron
Megan Cytron

Reputation: 95

R wordcloud: varying color of a specific frequency

I have a wordcloud where many of the items have a frequency of 1, but it is still important that they be displayed. I would like those "frequency of 1" results to be randomly displayed using the gradient of a color (like tones of gray)--so each individual item with a frequency of 1 is easier to read--while anything over 1 would get a designated color (I will know ahead of time the number of unique frequencies. For example in the data below: 1, 2, 3, 9, 16).

My data frame mentions2 looks something like this:

id  n   mention
1   1   las vísceras
2   1   museo de vivos
3   1   el hormiguero
4   1   las plataformas
5   1   lejos
6   1   madrileña
7   1   madrileñas
8   1   matritenses
9   2   esta ciudad
10  2   la gran ciudad
11  2   madrileño
12  2   sí mismas
13  3   una ciudad
14  9   aquí
15  10  madrid
16  16  la ciudad
17  1   ratonera
18  1   los madriles
19  1   allá
20  1   nuestra ciudad

So far I have this, which does what I want, except all of the items with a frequency of 1 are the same gray color and I am looking to make them easier to read by varying their tonality randomly (by either designating a set of colors manually or using an established gradient or range):


wordcloud(words = mentions2, freq = mentions2$n, min.freq = 1,rot.per=0,colors = c("grey28","firebrick1", "firebrick2","firebrick3","firebrick3", "firebrick4"))

I'm uncertain of how to deal with those with a frequency of one separately from those with higher frequencies. Any thoughts?

Edit: Following the advice here: Customised Word Cloud in two different colors in R, I was able to split my dataframe into two parts: frequency of 1 and frequency of >1. But I still can't figure out how to apply two separate color rules to them:

freq1<-  mentions2[ which(mentions2$n == 1) ,]
freq2<- mentions2[ which(mentions2$n >= 2) ,]
AllWords = rbind(freq1, freq2)
 Colors = c(rep("blue", nrow(freq1)), rep("red", nrow(freq2)))

 wordcloud(words = AllWords$mentions, freq = AllWords$n, min.freq = 1,rot.per=0,colors=Colors, ordered.colors=TRUE)

Edit 2: Thanks to Armando for clueing me in to the fact that wordcloud doesn't have the flexibility I need to assign colors based on a variable other than frequency. I ended up using wordcloud2 adding a "color" column to my data frame and I randomly assign a color to all my "frequency=1" results:

 colors<-c("#666666","#777777","#888888","#222222","#555555","#444444","#333333","#222222","#111111","#000000")

nummentions1<-count(madridmentions2[madridmentions2$n==1,])

mentions2[mentions2$n==1,]$color <-sample(colors,1,size=as.numeric(nummentions1))

mentions2[madridmentions2$n>=2,]$color <- "#db0030"

wordcloud2(data=mentions2, color = mentions2$color, backgroundColor = "white",rotateRatio=0,shape = 'circle',fontFamily = 'Helvetica')

Upvotes: 0

Views: 1306

Answers (1)

What you ask is impossible with wordcloud, because the color option only accepts a vector of colors that the package would automatically set accordinf to frequencies.

I suggest you to use the more flexible package wordcloud2, which allows more flexibility. In the following code I show you how to use a grey sequency for 1 freqs and a yellow-red sequence for other values. Since fontsize already shows frequencies, you can the defalult random colors that are in the info package https://cran.r-project.org/web/packages/wordcloud2/vignettes/wordcloud.html The example:

library(wordcloud2)    
library(scales)

cloud <- demoFreq[1:500,]
freqs <- unique(cloud$freq)[order(unique(cloud$freq))]

cloud$color=""
cloud[cloud$freq==1,]$color <- scales::seq_gradient_pal(low="#F0F0F0", high="#252525",space = "Lab")(seq(0,1,length.out=sum(cloud$freq==1)))

cols <- scales::seq_gradient_pal(low="yellow", high="red",space = "Lab")(seq(
  0,1,
  length.out=(length(freqs)-1)))

for (i in 2:length(freqs)){
  cloud[cloud$freq==freqs[i],]$color <- cols[i-1]
}

wordcloud2(demoFreq, color = cloud$color, backgroundColor = "pink")

Upvotes: 2

Related Questions