How to add WordCloud graph in Streamlit

I want to add the wordcloud to streamlit app to show thw related words in the tweets.

1 Like

Great question and you absolutely can do this with st.pyplot() and wordcloud. Here’s a simple example:

import streamlit as st
from wordcloud import WordCloud
import matplotlib.pyplot as plt

# Create some sample text
text = 'Fun, fun, awesome, awesome, tubular, astounding, superb, great, amazing, amazing, amazing, amazing'

# Create and generate a word cloud image:
wordcloud = WordCloud().generate(text)

# Display the generated image:
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis("off")
plt.show()
st.pyplot()

Let me know if that works for you!

7 Likes

Hi!

I’m trying to plot 3 word cloud (from WordCloud) figures side by side using subplots from matplotlib.

The app only plots the second and third graphs. That also happens if I add a fourth graph – it will not print the first figure.

I’m fairly new to using all of these packages. Can someone point out my mistake? Thanks a lot!

Here’s the code for 3 charts:

# Plot1
plt.title('Topic '+str(first_choice))
plt.axis('off')
plt.tight_layout()
plt.imshow(wordcloud1)
plt.subplot(1,3,1)

# Plot2
plt.title('Topic '+str(second_choice))
plt.axis('off')
plt.tight_layout()
plt.imshow(wordcloud2)
plt.subplot(1,3,2)

# Plot3
plt.title('Topic '+str(third_choice))
plt.axis('off')
plt.tight_layout()
plt.imshow(wordcloud3)
plt.subplot(1,3,3)

st.pyplot()

And the resulting plots – for 3 and 4 charts:

2 Likes

Hi @csbrl, you can use st.beta_columns to display 3 plots side by side, no need for subplots.

col1, col2, col3 = st.beta_columns(3)
with col1:
    st.header("A cat")
    st.image("https://static.streamlit.io/examples/cat.jpg", use_column_width=True)
with col2:
    st.header("A dog")
    st.image("https://static.streamlit.io/examples/dog.jpg", use_column_width=True)
with col3:
    st.header("An owl")
    st.image("https://static.streamlit.io/examples/owl.jpg", use_column_width=True)

For more information, follow this documentation link

Hi, Amanda! I tried to use this code that you shared, but it didn’t work for me, it shows “TypeError: expected string or bytes-like object”. Do you know how to fix it?

I did this and it is working:

comments = df[‘review’].apply(simple_cleaning)
font_path = ‘./chocolatier_artisanal/Chocolatier Artisanal.ttf’
mask = np.array(Image.open(‘brasil.png’))
mask_colors = ImageColorGenerator(mask)
wc = WordCloud(font_path = font_path, mask = mask, background_color = ‘white’,
max_words = 100, max_font_size = 256, random_state = 42, width = mask.shape[1],
height = mask.shape[0], color_func = mask_colors,
collocations = False
#collocation_threshold = 3
)
wc.generate_from_frequencies(common_words(comments))
fig, ax = plt.subplots(figsize = (12, 8))
ax.imshow(wc, interpolation = ‘bilinear’)
plt.axis(‘off’)
st.pyplot(fig)

Hi Amanda, what happens if i have two fields like below and i want to do a wordcloud on text but filter with topic in streamlit. When i click topic1 as an option i want the word cloud to change accordingly.
Topic No Text
topic1 law,contract,fees
topic2 students,school,exams
topic 3 pastor,church,money

Thanks.

Very easy! Just use a selectbox:

import streamlit as st
from wordcloud import WordCloud
import matplotlib.pyplot as plt

# Create text
topic1 = 'law,contract,fees'
topic2 = 'students,school,exams'
topic3 = 'pastor,church,money'

topic = st.selectbox('select topic',['topic1','topic2','topic3'])

# Create and generate a word cloud image:
def create_wordcloud(topic):
    if topic == 'topic1':
        topic = topic1
    elif topic == 'topic2':
        topic = topic2
    else:
        topic = topic3

    wordcloud = WordCloud().generate(topic)
    return wordcloud

wordcloud = create_wordcloud(topic)

# Display the generated image:
fig, ax = plt.subplots(figsize = (12, 8))
ax.imshow(wordcloud)
plt.axis("off")
st.pyplot(fig)
6 Likes

Thanks is working fine

hello all. i am trying to remove axes from this wordcloud chart. It seems work in Jupyter but st is not using the plt.axes(“off”) setting. How to fix this? Here is the code. I am drawing a wordcloud for every row of the dataframe.

for index,row in word_df.iterrows():
       `
      wordcloud = WordCloud(stopwords=stopwords,background_color="white", width=800, height=400).generate(row[1])`
    plt.axis("off")`
    plt.figure( figsize=(20,20))`
    plt.tight_layout(pad=0)`
    plt.imshow(wordcloud, interpolation='bilinear')`
    st.write(row[0])`
    st.pyplot()`

Here is my output

Figured it out.
plt.axis(“off”) had to be after plt.imshow(wordcloud, interpolation=‘bilinear’)
this removed the axes
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis("off")

2 Likes

I tried doing my WordCloud with the following code that was mentioned above and I got a weird popup.

import streamlit as st
from wordcloud import WordCloud
import matplotlib.pyplot as plt
from matplotlib import font_manager

# Create a WordCloud object
wordcloud = WordCloud(font_path= "C:\\windows\\Fonts\\simsun", background_color="white", max_words=5000, contour_width=3, contour_color='steelblue')

# Generate a word cloud
wordcloud.generate(long_string)
plt.figure(figsize = (15, 10))

plt.imshow(wordcloud, interpolation="bilinear")
plt.axis("off")
plt.show()
st.pyplot

And this is the message that appeared in my streamlit app.

streamlit.pyplot(fig: Optional[ForwardRef(‘Figure’)] = None, clear_figure: Optional[bool] = None, **kwargs: Any) → ‘DeltaGenerator’
Display a matplotlib.pyplot figure.

Parameters

fig : Matplotlib Figure
The figure to plot. When this argument isn’t specified, this
function will render the global figure (but this is deprecated,
as described below)

clear_figure : bool
If True, the figure will be cleared after being rendered.
If False, the figure will not be cleared after being rendered.
If left unspecified, we pick a default based on the value of fig.

* If `fig` is set, defaults to `False`.

* If `fig` is not set, defaults to `True`. This simulates Jupyter's
  approach to matplotlib rendering.

**kwargs : any
Arguments to pass to Matplotlib’s savefig function.

Example

import matplotlib.pyplot as plt
import numpy as np

arr = np.random.normal(1, 1, size=100)
fig, ax = plt.subplots()
ax.hist(arr, bins=20)

st.pyplot(fig)

… output::
https://doc-pyplot.streamlitapp.com/
height: 630px

Notes

… note::
Deprecation warning. After December 1st, 2020, we will remove the ability
to specify no arguments in st.pyplot(), as that requires the use of
Matplotlib’s global figure object, which is not thread-safe. So
please always pass a figure object as shown in the example section
above.

Matplotlib supports several types of “backends”. If you’re getting an
error using Matplotlib with Streamlit, try setting your backend to “TkAgg”::

echo "backend: TkAgg" >> ~/.matplotlib/matplotlibrc

For more information, see https://matplotlib.org/faq/usage_faq.html.

Can anyone help me understand what this means and how to fix it?

You do not user plt.show() with Streamlit. You need to pass the figure to st.pyplot.

Delete your last two lines and replace them with

st.pyplot(plt.gcf())

plt.gcf() is the “Get Current Figure” function.

perfect thank you! Do you by any chance know why I am getting this weird error for this bunch of code?

# LDA Model Training
import gensim
from pprint import pprint
# number of topics
num_topics = 10
# Build LDA model
lda_model = gensim.models.LdaMulticore(corpus=corpus,id2word=id2word,num_topics=num_topics)
# Print the Keyword in the 10 topics
pprint(lda_model.print_topics())
doc_lda = lda_model[corpus]
st.write(pprint(lda_model.print_topics()))
st.write(lda_model[corpus])

I get this error in the command prompt.
raise RuntimeError(‘’’
RuntimeError:
An attempt has been made to start a new process before the
current process has finished its bootstrapping phase.

    This probably means that you are not using fork to start your
    child processes and you have forgotten to use the proper idiom
    in the main module:

        if __name__ == '__main__':
            freeze_support()
            ...

    The "freeze_support()" line can be omitted if the program
    is not going to be frozen to produce an executable.

I do not, sorry. I’ve never used gensim.

Although, note that print statements (including pprint) don’t render in a Streamlit app. You’ll need to use st.write if you intend it for human-user consumption.