深度有趣 | 03 高階又一般的詞雲
詞雲是一種資料呈現方式
- 不會的時候,感覺很厲害、很高大上
- 會用了之後,感覺到哪都看到別人在用
掌握用 Python
實現詞雲的方法
準備
安裝包
pip install wordcloud matplotlib jieba PIL 複製程式碼
準備一些文字,英文或中文皆可
一個簡單的例子
WordCloud()
可選的引數
-
font_path
:可用於指定字型路徑,包括otf
和ttf
-
width
:詞雲的寬度,預設為400 -
height
:詞雲的高度,預設為200 -
mask
:蒙版,可用於定製詞雲的形狀 -
min_font_size
:最小字號,預設為4 -
max_font_size
:最大字號,預設為詞雲的高度 -
max_words
:詞的最大數量,預設為200 -
stopwords
:將被忽略的停用詞,如果不指定則使用預設的停用詞詞庫 -
background_color
:背景顏色,預設為black
-
mode
:預設為RGB
模式,如果為RGBA
模式且background_color
設為None
,則背景將透明
# -*- coding: utf-8 -*- from wordcloud import WordCloud import matplotlib.pyplot as plt # 開啟文字 text = open('constitution.txt').read() # 生成物件 wc = WordCloud().generate(text) # 顯示詞雲 plt.imshow(wc, interpolation='bilinear') plt.axis('off') plt.show() # 儲存到檔案 wc.to_file('wordcloud.png') 複製程式碼

由於英文單詞之間有空格分隔,因此大多不需要額外的處理
中文詞雲
中文一般需要經過分詞處理,先看下不分詞的效果
以《西遊記》為例,可以看到結果中會出現各種雙字、三字和四字等,但很多並不是合理的詞語
# -*- coding: utf-8 -*- from wordcloud import WordCloud import matplotlib.pyplot as plt # 開啟文字 text = open('xyj.txt').read() # 生成物件 wc = WordCloud(font_path='Hiragino.ttf', width=800, height=600, mode='RGBA', background_color=None).generate(text) # 顯示詞雲 plt.imshow(wc, interpolation='bilinear') plt.axis('off') plt.show() # 儲存到檔案 wc.to_file('wordcloud.png') 複製程式碼

這次我們先用 jieba
進行中文分詞,可以看到生成的詞雲裡,基本上都是合理的詞語了
# -*- coding: utf-8 -*- from wordcloud import WordCloud import matplotlib.pyplot as plt import jieba # 開啟文字 text = open('xyj.txt').read() # 中文分詞 text = ' '.join(jieba.cut(text)) print(text[:100]) # 生成物件 wc = WordCloud(font_path='Hiragino.ttf', width=800, height=600, mode='RGBA', background_color=None).generate(text) # 顯示詞雲 plt.imshow(wc, interpolation='bilinear') plt.axis('off') plt.show() # 儲存到檔案 wc.to_file('wordcloud.png') 複製程式碼

使用蒙版
這裡將 mask
翻譯為蒙版,是因為感覺它和Photoshop中蒙版的作用很類似
使用蒙版之後,可以根據提供的蒙版圖片,生成指定形狀的詞雲
# -*- coding: utf-8 -*- from wordcloud import WordCloud from PIL import Image import numpy as np import matplotlib.pyplot as plt import jieba # 開啟文字 text = open('xyj.txt').read() # 中文分詞 text = ' '.join(jieba.cut(text)) print(text[:100]) # 生成物件 mask = np.array(Image.open("black_mask.png")) wc = WordCloud(mask=mask, font_path='Hiragino.ttf', mode='RGBA', background_color=None).generate(text) # 顯示詞雲 plt.imshow(wc, interpolation='bilinear') plt.axis("off") plt.show() # 儲存到檔案 wc.to_file('wordcloud.png') 複製程式碼

顏色
詞雲的顏色可以從蒙版中抽取,使用 ImageColorGenerator()
即可
# -*- coding: utf-8 -*- from wordcloud import WordCloud, ImageColorGenerator from PIL import Image import numpy as np import matplotlib.pyplot as plt import jieba # 開啟文字 text = open('xyj.txt').read() # 中文分詞 text = ' '.join(jieba.cut(text)) print(text[:100]) # 生成物件 mask = np.array(Image.open("color_mask.png")) wc = WordCloud(mask=mask, font_path='Hiragino.ttf', mode='RGBA', background_color=None).generate(text) # 從圖片中生成顏色 image_colors = ImageColorGenerator(mask) wc.recolor(color_func=image_colors) # 顯示詞雲 plt.imshow(wc, interpolation='bilinear') plt.axis("off") plt.show() # 儲存到檔案 wc.to_file('wordcloud.png') 複製程式碼

當然也可以設定為純色,增加一個配色函式即可
# -*- coding: utf-8 -*- from wordcloud import WordCloud from PIL import Image import numpy as np import matplotlib.pyplot as plt import random import jieba # 開啟文字 text = open('xyj.txt').read() # 中文分詞 text = ' '.join(jieba.cut(text)) print(text[:100]) # 顏色函式 def random_color(word, font_size, position, orientation, font_path, random_state): s = 'hsl(0, %d%%, %d%%)' % (random.randint(60, 80), random.randint(60, 80)) print(s) return s # 生成物件 mask = np.array(Image.open("color_mask.png")) wc = WordCloud(color_func=random_color, mask=mask, font_path='Hiragino.ttf', mode='RGBA', background_color=None).generate(text) # 顯示詞雲 plt.imshow(wc, interpolation='bilinear') plt.axis("off") plt.show() # 儲存到檔案 wc.to_file('wordcloud.png') 複製程式碼

關於HSL配色方案可以參考
CSS3%2FColor%2FHSL" rel="nofollow,noindex">www.w3.org/wiki/CSS3/C…
精細控制
如果希望精細地控制詞雲中出現的詞,以及每個詞的大小,可以嘗試 generate_from_frequencies()
,包括兩個引數
-
frequencies
:一個字典,用於指定詞和對應的大小 -
max_font_size
:最大字號,預設為None
generate()
= process_text()
+ generate_from_frequencies()
以下用jieba提取出關鍵詞和權重,再以此繪製詞雲
# -*- coding: utf-8 -*- from wordcloud import WordCloud, ImageColorGenerator from PIL import Image import numpy as np import matplotlib.pyplot as plt import jieba.analyse # 開啟文字 text = open('xyj.txt').read() # 提取關鍵詞和權重 freq = jieba.analyse.extract_tags(text, topK=200, withWeight=True) print(freq[:20]) freq = {i[0]: i[1] for i in freq} # 生成物件 mask = np.array(Image.open("color_mask.png")) wc = WordCloud(mask=mask, font_path='Hiragino.ttf', mode='RGBA', background_color=None).generate_from_frequencies(freq) # 從圖片中生成顏色 image_colors = ImageColorGenerator(mask) wc.recolor(color_func=image_colors) # 顯示詞雲 plt.imshow(wc, interpolation='bilinear') plt.axis("off") plt.show() # 儲存到檔案 wc.to_file('wordcloud.png') 複製程式碼