早安各位,今天是還債日。之前在講斷詞斷句的時候有提到要出一個文字雲教學,但是因為時間安排的關係就被移到今天了。廢話不多說,大家應該都看過文字雲吧?就是下面那個把詞聚在一起變成塊狀物的東西,通常越重要(詞頻越高)的詞就會越中間越大,可以用來讓其他人一眼看出重點。其實有滿多網站提供線上生成文字雲的工具跟服務,但那是外行人在用的東西啦。既然你各位現在都有程式基礎也會自己斷詞了,畫個文字雲根本難不倒,甚至你對它的形狀或顏色有甚麼期待都可以靠python的套件跟簡單的幾行程式碼解決。自己動手,豐衣足食。相信我,看完這篇文章,你再也不會想去用那些線上工具了(怎麼突然有點像在賣藥)
今天要請出的厲害套件就是wordcloud
,為什麼要說他厲害呢?後面你就會知道了,他根本就是披著python套件皮的修圖軟體。在體驗它的酷炫功能之前,我們先試著做出一個最default的文字雲吧。wordcloud
真的非常之貼心,我們直接把字串放進去他就會幫我們斷好詞了,所以我們只要把它跟用來畫圖的套件matplotlib
引進python就可以了。(我這次用的是這篇新聞)
!pip install matplotlib
import matplotlib.pyplot as plt
from wordcloud import WordCloud
eng_news = open("/content/eng_news.txt").read()
接下來使用WordCloud
裡面的generate()
函式就可以初步生成文字雲了。文字雲生成之後再用matplotlib
裡面的imshow()
讓圖片顯現出來就完成最簡易的文字雲啦~
wordcloud = WordCloud().generate(eng_news)
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis("off")
imshow()
的第二個參數是為了讓圖片印出來畫素比較好的必需品,所以雖然你可能不懂它的意思,還是記得要加上去。然後axis指的是橫軸座標跟縱軸座標。因為我們不是在畫統計圖表,所以不需要它。這些東西都設定好之後就可以印出下面這張圖。
怎麼說呢?上面確實是一個合格的文字雲,就是看起來有點無聊。啊哈!我們放著WordCloud()
裡面那麼多可以調的參數不管,也難怪這個文字雲這麼無聊了。下面介紹幾個你可能會想用到的參數:
參數 | 作用 | 格式 |
---|---|---|
width |
設定圖片長度 | 預設值是400 |
height |
設定圖片高度 | 預設值是200 |
scale |
設定圖片要放大的倍數 | 預設值是1 |
stopwords |
設定停止詞 | 可以用set(STOPWORDS) 叫出default字典 |
fontfile |
更換字型 | 輸入字型檔案的路徑 |
margin |
調整文字之間的間隔 | 預設值是2 |
background_color |
更換背景顏色 | 十六進位色碼 |
colormap |
更換字顏色的主題 | 主題名稱 |
max_words |
設定文字雲容納字數的上限 | 預設值是200 |
min_font_size |
設定最小的字體大小 | 預設值是4 |
max_font_size |
設定最大的字體大小 | 數值 |
no_normalize_plurals |
要不要把複數跟單數詞看成同一個 | 預設值是True |
這些都是比較基礎,大家可以視自己需求調整的參數(完整列表),下面我稍微示範一下怎麼做:
from wordcloud import STOPWORDS, ImageColorGenerator
stopword = set(STOPWORDS)
wordcloud = WordCloud(width = 4000, height = 3000, stopwords = STOPWORDS, margin = 3, background_color = "white", colormap = "Set3", max_words = 25, min_font_size = 8).generate(eng_news)
嗯嗯這樣看起來賞心悅目多了(至少對我來說啦 XDD)
什麼?!你說為什麼文字雲不是雲的形狀?因為文字雲本來就只是一個隱喻的說法啊。不過既然你都這麼說了,我們就來介紹一下wordcloud
提供的遮罩功能吧。給大家看一下官方demo的遮罩功能產物:
都可以做成這樣了,雲根本是一塊蛋糕好嗎。如果想要一朵雲的話,首先要找到一張雲的圖片。不是隨便一張圖喔,是一張雲本身的輪廓跟背景顏色分界明顯的圖片。像是這個:
有了圖之後,我們還需要一個可以把圖片引進來的套件(Pillow
)跟把上面的顏色資料傳換成數值的套件(numpy
)才能開始。Image.open()
是Pillow
裡面用來讀入圖片的函式。我們把圖片讀進來以後再用array()
幫圖片做一維數值轉換,讓它變成電腦可以讀懂的數字。
import numpy as np
from PIL import Image
mask = np.array(Image.open("/content/cloud-cute-cartoon-vector-22728411.jpg"))
有了這個東西之後我們就可以加入遮罩的參數讓WordCloud
幫我們畫出「真正的」文字雲。
real_wordcloud = WordCloud(mask = mask, stopwords = STOPWORDS, margin = 3, contour_color='#023075', contour_width=3, background_color = "white", colormap = "Set3", max_words = 25, min_font_size = 8).generate(eng_news)
plt.imshow(real_wordcloud, interpolation='bilinear')
plt.axis("off")
好啦你現在可能在想說為什麼這個看起來那麼小,畫質那麼差,這是因為matplotlib
預設的imshow()
顯示是800*600,所以不管我們WordCloud()
裡面的參數再怎麼調,它都只會是那個大小。So~我們要在下面加上一個調整imshow
顯示的函式。這次換隻狗來試試好了。
worddog = WordCloud(width = 1000, height =800, mask = mask, stopwords = STOPWORDS, margin = 3, scale = 10, background_color = "white", colormap = "Set3", min_font_size = 8).generate(eng_news)
plt.figure( figsize=(20,10) ) #新加的函式在這裡
plt.imshow(worddog, interpolation='bilinear')
plt.axis("off")
Do rei mi so (づ ̄ 3 ̄)づ 這樣就完美了~
現在覺得上面的功能很酷還太早了,如果你對於要幫文字雲上什麼顏色很煩惱的話,可以考慮用下面這個功能。在我們用WordCloud
初步產出的文字雲裡面,其實藏有一個叫做recolor
的函式,在我們用ImageColorGenerator
擷取圖片的顏色分布之後,可以把它拿來當整個文字雲的上色依據,像是下面這樣:
shin = WordCloud(width = 900, height =1600, mask = mask, stopwords = STOPWORDS, margin = 3, scale = 10, background_color = "white", min_font_size = 8).generate(eng_news)
image_colors = ImageColorGenerator(mask)
plt.figure( figsize=(20,10) )
plt.imshow(shin.recolor(color_func=image_colors), interpolation="bilinear")
plt.axis("off")
看看這個熟悉的配色,上紅下黃,除了小新還能是誰?
說了那麼多,都是用英文當例子也太有損我中文母語者的身分了。因為wordcloud
跟matplotlib
都是外國人設計的,當然沒有考慮其他語言的使用者。除了我們要自己先斷詞之外,為了讓中文可以順利顯示在上面,還要多加幾個步驟。(好啦其實有啦,人家有在官網上面demo怎麼做中文的文字雲)
首先,我們要做的事情就是到google fonts上面下載中文字型,再弄到colab裡面。當然如果你自己電腦裡面有想用的字型也可以把檔案傳到colab上面,總之就是要有一個字型檔就對了。
font_path = '/content/Iansui0.93-Regular.ttf'
ch_news = " ".join(ckip_clean_result) # 把串列裡的字串用空格結合起來
ch_wordcloud = WordCloud(font_path = font_path, width = 900, height =1600, mask = mask, stopwords = STOPWORDS, margin = 3, scale = 10, background_color = "white", min_font_size = 8, prefer_horizontal = 1).generate(ch_news)
上面這個是我已經先用ckiptagger
斷好詞的結果,因為英文斷詞的方式就是找空格的地方,所以我們把串列裡面的字串用空格連接起來就可以丟給WordCloud
內建的斷詞器斷詞了。斷詞器裡面只要多加上font_path
這個參數指定要使用的字型檔案路徑就能讓中文顯現出來。同理,如果你不滿意預設的英文字體當然也可以用這個方式把他換掉。接下來一樣用matplotlib
把圖印出來就可以了。BTW 如果你不喜歡字被轉來轉去,可以跟我一樣加上prefer_horizontal = 1
去固定他的旋轉角度。
plt.figure( figsize=(20,10) )
plt.imshow(ch_wordcloud.recolor(color_func=image_colors), interpolation="bilinear")
plt.axis("off")
想不到吧,光是一個文字雲我竟然可以打這麼多東西。(我自己都沒想到)總是這就是畫出很fancy的文字雲的方法啦~下次不要再用網路上那些簡陋的工具了,按照個人喜好弄個有趣的文字雲來跟朋友炫耀一下吧~明天見!