Python數(shù)據(jù)可視化:WordCloud入門
WordCloud是一種很好的展現(xiàn)數(shù)據(jù)的方式,網(wǎng)上也有不少小工具和在線網(wǎng)頁。
但是有些不支持中文,有些安裝復雜,所以決定用Python實現(xiàn)。
主要參考官網(wǎng),通過官網(wǎng)的例子,講一下WordCloud的制作。
主要流程
- 獲取內(nèi)容的路徑
- 如果是一段文字,系統(tǒng)自動算頻次
- 你也可以直接導入統(tǒng)計好的頻次
- 設置字體
- 一般字體路徑在C:\Windows\Fonts,你可以選自己喜歡的中文或者英文字體
- 切割中文字符
- 英文字符就不用切割了
- 輸入WordCloud的參數(shù)
- 背景色
- 字號
- 生成的形狀
- 顏色
- 字體大小
- 字體旋轉(zhuǎn)等等
- 生成WordCloud
- 用matplotlib顯示圖片
效果圖






安裝庫
老規(guī)矩,首先,你要安裝庫。
最基本的兩個:
- pip install wordcloud #這是WordCloud的庫
- pip install matplotlib #顯示圖像
一個單詞構(gòu)造WordCloud
在這個代碼中,我們需要安裝一個numpy庫
(大部分小伙伴應該都裝過,就不用再裝了)
- pip install numpy
這里用這個庫,主要是想用數(shù)學坐標生成一個簡單的背景圖案,比如圓形、方形

基本步驟
- 輸入單詞
- 用numpy 生成一個形狀,下面生成了一個圓形mask
- 輸入WordCloud的參數(shù)(包括背景色、是否重復、圖案形狀)
- 用matplotlib顯示圖片
- import numpy as np
- import matplotlib.pyplot as plt
- from wordcloud import WordCloud
- text = "square" #輸入你要的單詞
- x, y = np.ogrid[:300, :300] #快速產(chǎn)生一對數(shù)組
- # 產(chǎn)生一個以(150,150)為圓心,半徑為130的圓形mask
- mask = (x - 150) ** 2 + (y - 150) ** 2 > 130 ** 2 #此時mask是bool型
- mask = 255 * mask.astype(int) #變量類型轉(zhuǎn)換為int型
- wc = WordCloud(
- background_color="white", #背景顏色為“白色”
- repeat=True, #單詞可以重復
- mask=mask #指定形狀,就是剛剛生成的圓形
- )
- wc.generate(text) #從文本生成wordcloud
- plt.axis("off") #把作圖的坐標軸關掉
- plt.imshow(wc, interpolation="bilinear")
- plt.show()
生成WordCloud
最簡單的生成方式,文本內(nèi)容都是英文,直接用系統(tǒng)默認的形狀(一個長方形)
我這邊是導入了一個商務英語的txt,所以可以看到,出現(xiàn)次數(shù)最多的單詞是company,然后是business、new、work等單詞,我還看到了money,哈哈~

基本步驟
- 獲取內(nèi)容txt的路徑
- 輸入WordCloud的參數(shù)(包括背景色、字號等)
- 生成WordCloud
- 用matplotlib顯示圖片
*WordCloud有很多參數(shù),如果你不寫,都是默認的。比如背景色默認黑色。
- import os
- from os import path
- from wordcloud import WordCloud
- from matplotlib import pyplot as plt
- # 獲取當前文件路徑
- d = path.dirname(__file__) if "__file__" in locals() else os.getcwd()
- # 獲取文本txt的路徑(txt和代碼在一個路徑下面)
- text = open(path.join(d,'BusinessEnglish.txt')).read()
- # 生成詞云
- wc = WordCloud(
- scale=2,
- max_font_size=100, #最大字號
- background_color='white' #設置背景顏色
- )
- wc.generate(text) # 從文本生成wordcloud
- # wc.generate_from_text(text) #用這種表達方式也可以
- # 顯示圖像
- plt.imshow(wc,interpolation='bilinear')
- plt.axis('off')
- plt.tight_layout()
- wc.to_file('標簽云效果圖.png') # 儲存圖像
- #plt.savefig('標簽云效果圖.png',dpi=200) #用這個可以指定像素
- plt.show()
設置WordCloud形狀
都是長方形、圓形、正方形這種,好像不夠炫酷
為了炫酷,我們可以給它設置不同的形狀,比如云朵、愛心等等
下面我們用Alice的小裙子做個實例
這個圖片長這樣

我們生成的圖片是這樣的,可以看到,完整保留了上圖的輪廓

基本步驟
和之前基本都是一致的,就是多了一步,導入指定圖片,獲取圖片輪廓
- 獲取內(nèi)容txt的路徑
- 輸入WordCloud的參數(shù)(包括背景色、字號等),指定了生成的形狀
- 生成WordCloud
- 用matplotlib顯示圖片
*代碼中增加了一個stopwords,有些你覺得沒意義的單詞,不想顯示在圖片上,你就可以放在這里
- from os import path
- from PIL import Image
- import numpy as np
- import matplotlib.pyplot as plt
- import os
- from wordcloud import WordCloud, STOPWORDS
- # 獲取當前文件路徑
- d = path.dirname(__file__) if "__file__" in locals() else os.getcwd()
- # 獲取文本txt的路徑(txt和代碼在一個路徑下面)
- text = open(path.join(d, 'BusinessEnglish.txt')).read()
- # 讀取mask的圖像(圖像和代碼在一個路徑下面)
- alice_mask = np.array(Image.open(path.join(d, "alice_mask.png")))
- # 設置不顯示單詞,比如said、in、on、is這種單詞
- stopwords = set(STOPWORDS)
- stopwords.add("said")
- # 設置詞云參數(shù)
- wc = WordCloud(background_color="white",
- max_words=2000,
- mask=alice_mask,
- stopwords=stopwords,
- contour_width=3, #設置輪廓寬度
- contour_color='steelblue') #設置輪廓顏色
- # 從文本生成wordcloud
- wc.generate(text)
- # 保存到文件
- wc.to_file(path.join(d, "alice.png"))
- # 顯示圖片
- plt.imshow(wc, interpolation='bilinear')
- plt.axis("off")
- plt.figure() #新建一個圖片,把mask也顯示出來
- plt.imshow(alice_mask, cmap=plt.cm.gray, interpolation='bilinear')
- plt.axis("off")
- plt.show()
根據(jù)圖片調(diào)整顏色
原圖是這樣的

如果我們直接根據(jù)上一步,獲取圖片輪廓,可以得到下圖

我們進一步,根據(jù)原圖,調(diào)整顏色

其實就是獲取了圖片顏色,也是一行代碼
- image_colors = ImageColorGenerator(alice_coloring)
完整代碼
- from os import path
- from PIL import Image
- import numpy as np
- import matplotlib.pyplot as plt
- import os
- from wordcloud import WordCloud, STOPWORDS, ImageColorGenerator
- # 獲取當前文件路徑
- d = path.dirname(__file__) if "__file__" in locals() else os.getcwd()
- # 獲取文本txt的路徑(txt和代碼在一個路徑下面)
- text = open(path.join(d, 'BusinessEnglish.txt')).read()
- # 讀取我要的圖片文件
- alice_coloring = np.array(Image.open(path.join(d, "alice_color.png")))
- # 設置不顯示的單詞
- stopwords = set(STOPWORDS)
- stopwords.add("said")
- # 設置詞云參數(shù)
- wc = WordCloud(background_color="white",
- max_words=2000,
- mask=alice_coloring,
- stopwords=stopwords,
- max_font_size=40,
- random_state=42)
- # 從文本生成wordcloud
- wc.generate(text)
- # 根據(jù)圖片,創(chuàng)建顏色
- image_colors = ImageColorGenerator(alice_coloring)
- # 把圖片分成3份
- fig, axes = plt.subplots(1, 3)
- axes[0].imshow(wc, interpolation="bilinear")
- # recolor wordcloud and show
- # we could also give color_func=image_colors directly in the constructor
- axes[1].imshow(wc.recolor(color_func=image_colors), interpolation="bilinear")
- axes[2].imshow(alice_coloring, cmap=plt.cm.gray, interpolation="bilinear")
- for ax in axes:
- ax.set_axis_off()
- # 單獨顯示圖片
- # plt.figure()
- # plt.imshow(wc, interpolation="bilinear")
- # plt.axis("off")
- # plt.figure()
- # plt.imshow(wc.recolor(color_func=image_colors), interpolation="bilinear")
- # plt.axis("off")
- # plt.figure()
- # plt.imshow(alice_coloring, cmap=plt.cm.gray, interpolation="bilinear")
- # plt.axis("off")
- plt.show()
用頻率繪制WordCloud
上面是直接把一個txt輸進去,系統(tǒng)自動給你算出現(xiàn)次數(shù)的
但是實際過程中,我們有時候,是知道單詞出現(xiàn)次數(shù)的,我們就想根據(jù)已知的次數(shù)顯示
這一步,其實就改了一行代碼,
原來是這樣的
- wc.generate(text) # 這里的text是一段文字
現(xiàn)在是這樣的
- wc.generate_from_frequencies(text)
- # 這里的text是一個字典
- # 'ken': 1, 'was': 47, 'hot': 2, 'water': 2
如果你已經(jīng)有一個字典,直接代進去就好了
這里給大家詳細看一下,如果假設我沒有這個字典
我還是一段文字,我想先生成這個字典,再代入進去
這里,你需要安裝一個庫multidict,創(chuàng)建一鍵多值字典
- pip install multidict
用multidict這個庫,我可以把文本變成一個字典

通過上圖就可以看到,這個字典有1105個組合,每一個單詞,都統(tǒng)計了出現(xiàn)次數(shù)
- import multidict as multidict
- import numpy as np
- import os
- import re
- from PIL import Image
- from os import path
- from wordcloud import WordCloud
- import matplotlib.pyplot as plt
- def getFrequencyDictForText(sentence):
- fullTermsDict = multidict.MultiDict()
- tmpDict = {}
- # making dict for counting frequencies
- for text in sentence.split(" "):
- if re.match("a|the|an|the|to|in|for|of|or|by|with|is|on|that|be", text):
- continue
- val = tmpDict.get(text, 0)
- tmpDict[text.lower()] = val + 1
- for key in tmpDict:
- fullTermsDict.add(key, tmpDict[key])
- return fullTermsDict
- def makeImage(text):
- alice_mask = np.array(Image.open("alice_mask.png"))
- wc = WordCloud(
- background_color="white",
- max_words=1000,
- mask=alice_mask
- )
- # generate word cloud
- wc.generate_from_frequencies(text)
- # show
- plt.imshow(wc, interpolation="bilinear")
- plt.axis("off")
- wc.to_file('frequency.png') # 儲存圖像
- plt.show()
- # 獲取當前文件路徑
- d = path.dirname(__file__) if "__file__" in locals() else os.getcwd()
- # 獲取文本txt的路徑(txt和代碼在一個路徑下面)
- text = open(path.join(d, 'BusinessEnglish.txt'), encoding='utf-8')
- text = text.read()
- makeImage(getFrequencyDictForText(text))
生成中英文WordCloud
生成一個中英文混搭的WordCloud
如果你的txt全是中文,那就是全中文的

基本步驟
和之前基本也都一樣,就是中文字符,需要增加一個中文詞語切割
這就需要添加一個庫
- pip install jieba # 中文切割
- 獲取內(nèi)容txt的路徑
- 設置字體
- 切割中文字符
- 輸入WordCloud的參數(shù)(包括背景色、字號等),指定了生成的形狀
- 生成WordCloud
- 用matplotlib顯示圖片
- import os
- from os import path
- from wordcloud import WordCloud
- from matplotlib import pyplot as plt
- import jieba
- # 獲取當前文件路徑
- d = path.dirname(__file__) if "__file__" in locals() else os.getcwd()
- # 獲取文本txt
- text = open(path.join(d,'商務英語.txt'),encoding='utf-8').read()
- # 設置中文字體
- font_path = 'C:\Windows\Fonts\\simfang.ttf' # 字體路徑
- # 精確切割中文字符
- text = ' '.join(jieba.cut(text, cut_all = False))
- # 生成詞云
- wc = WordCloud(
- font_path = font_path, #字體路徑
- scale=2,
- max_words = 100, #最多詞個數(shù)
- max_font_size=100, #最大字號
- background_color='white' #背景色
- )
- wc.generate(text)
- # 顯示圖像
- plt.imshow(wc,interpolation='bilinear')
- plt.axis('off')
- plt.tight_layout()
- # 儲存圖像
- #wc.to_file('標簽云效果圖.png')
- #plt.savefig('標簽云效果圖.png',dpi=200)
- plt.show()