[Python word_cloud 樣例 標簽云系列(三)]
轉載地址:https://zhuanlan.zhihu.com/p/20436642word_cloud/examples at master · amueller/word_cloud · GitHub
上面是官方樣例。這一篇里的大部分嘗試都基于這些樣例進行修改。前提是你已經完成了安裝,依照上一篇修改了 FONT_PATH 。
還記得 http://zhuanlan.zhihu.com/666666/20432734 里提到的中文分詞方法吧,這次我們就不再贅述對文本的預處理了。有所不同的是,在上次的 pytagcloud 庫中我們要求傳入字典,而這次我們要求傳入數組。所以需要做一點小小的改動。
上一次我們是這么寫的:
wd = {}fp=codecs.open("rsa.txt", "r",'utf-8');alllines=fp.readlines();fp.close();for eachline in alllines: line = eachline.split(' ') #print eachline, wd[line[0]] = int(line[1])print wd
這次我們需要將其中生成字典的部分變為數組:
-- coding: utf-8 --import codecsfp=codecs.open("rs300.txt", "r",'utf-8');wd = []alllines=fp.readlines();fp.close();for eachline in alllines: line = eachline.split('\') line[1]=int(line[1]) wd.append(line) #print eachline,print wd
文本預處理好了以后,我們就可以開始對照樣例依葫蘆畫瓢,嘗試生成詞云了。在此過程中會強調一些比較重要的方法,請自行對照上一篇的文檔理解。
word_cloud 生成詞云有兩個方法。from text 和 from frequencies 。如果我們處理英文文檔的話,就可以直接使用第一個方法,而不需要提前預處理文本,由于我們要做的是中文文本,所以我們必須自己分詞,并處理為數組,使用第二種方法。
讓我們從一個最簡單的例子開始,也就是官方文檔的 simple.py
-- coding: utf-8 --"""Minimal Example===============Generating a square wordcloud from the US constitution using default arguments."""from os import pathfrom wordcloud import WordCloudd = path.dirname(file)# Read the whole text. 此處原為處理英文文本,我們修改為傳入中文數組#text = open(path.join(d, 'constitution.txt')).read()frequencies = [(u'知乎',5),(u'小段同學',4),(u'曲小花',3),(u'中文分詞',2),(u'樣例',1)]# Generate a word cloud image 此處原為 text 方法,我們改用 frequencies #wordcloud = WordCloud().generate(text)wordcloud = WordCloud().fit_words(frequencies)# Display the generated image:# the matplotlib way:import matplotlib.pyplot as pltplt.imshow(wordcloud)plt.axis("off")# take relative word frequencies into account, lower max_font_size#wordcloud = WordCloud(max_font_size=40, relative_scaling=.5).generate(text)wordcloud = WordCloud(max_font_size=40, relative_scaling=.5).fit_words(frequencies)plt.figure()plt.imshow(wordcloud)plt.axis("off")plt.show()# The pil way (if you don't have matplotlib)#image = wordcloud.to_image()#image.show()
運行代碼得到結果:
這一步成功以后起碼說明我們中文環境配好了,可以開始更深層次的嘗試了。
在下面的演示中,我為了節省力氣,會直接使用一些英文的文檔,這樣省去處理中文分詞的步驟。
大家在用的時候只要記得修改 FONT_PATH 、 utf-8 編碼、處理數據為數組格式使用 frequencies 方法這三點就可以了。
接下來我們來到 masked.py
如文件名所示,這一次我們要自定義遮罩形狀來生成真正的詞云了!
根據文檔說明,遮罩圖片的白色部分將被視作透明,只在非白色部分區域作圖。于是我們找到一張黑白素材圖。
-- coding: utf-8 --""""Masked wordcloud================Using a mask you can generate wordclouds in arbitrary shapes."""from os import pathfrom PIL import Imageimport numpy as npimport matplotlib.pyplot as pltfrom wordcloud import WordCloud, STOPWORDSd = path.dirname(file)# Read the whole text.text = open(path.join(d, 'alice.txt')).read()# read the mask image# taken from# http://www.stencilry.org/stencils/movies/alice%20in%20wonderland/255fk.jpgalice_mask = np.array(Image.open(path.join(d, "huge.jpg")))wc = WordCloud(background_color="white", max_words=2000, mask=alice_mask, stopwords=STOPWORDS.add("said"))# generate word cloudwc.generate(text)# store to filewc.to_file(path.join(d, "alice.png"))# showplt.imshow(wc)plt.axis("off")plt.figure()plt.imshow(alice_mask, cmap=plt.cm.gray)plt.axis("off")plt.show()
如下圖:
圖做好了,可是總覺得哪里怪怪的。可能是顏色太過鮮艷吧,配色總感覺不是那么舒服,有沒有更逼格的處理?自然是有的。我們來到 a_new_hope.py
還是上面的圖,直接處理。
"""Using custom colors====================Using the recolor method and custom coloring functions."""import numpy as npfrom PIL import Imagefrom os import pathimport matplotlib.pyplot as pltimport randomfrom wordcloud import WordCloud, STOPWORDSdef grey_color_func(word, font_size, position, orientation, random_state=None, **kwargs): return "hsl(0, 0%%, %d%%)" % random.randint(60, 100)d = path.dirname(file)# read the mask image# taken from# http://www.stencilry.org/stencils/movies/star%20wars/storm-trooper.gifmask = np.array(Image.open(path.join(d, "huge.jpg")))# movie script of "a new hope"# http://www.imsdb.com/scripts/Star-Wars-A-New-Hope.html# May the lawyers deem this fair use.text = open("a_new_hope.txt").read()# preprocessing the text a little bittext = text.replace("HAN", "Han")text = text.replace("LUKE'S", "Luke")# adding movie script specific stopwordsstopwords = STOPWORDS.copy()stopwords.add("int")stopwords.add("ext")wc = WordCloud(max_words=1000, mask=mask, stopwords=stopwords, margin=10, random_state=1).generate(text)# store default colored imagedefault_colors = wc.to_array()plt.title("Custom colors")plt.imshow(wc.recolor(color_func=grey_color_func, random_state=3))wc.to_file("a_new_hope.png")plt.axis("off")plt.figure()plt.title("Default colors")plt.imshow(default_colors)plt.axis("off")plt.show()
這樣的灰調顏色比上面花花綠綠的感覺好多了。可是總不能老用黑白啊,需要色彩的時候怎么辦?最后一站我們來到 colored.py
為了突出我們鮮明且令人舒服的色調,我挑選了一幅小黃人的圖片進行處理。
!/usr/bin/env python2"""Image-colored wordcloud========================You can color a word-cloud by using an image-based coloring strategy implemented inImageColorGenerator. It uses the average color of the region occupied by the wordin a source image. You can combine this with masking - pure-white will be interpretedas 'don't occupy' by the WordCloud object when passed as mask.If you want white as a legal color, you can just pass a different image to "mask",but make sure the image shapes line up."""from os import pathfrom PIL import Imageimport numpy as npimport matplotlib.pyplot as pltfrom wordcloud import WordCloud, STOPWORDS, ImageColorGeneratord = path.dirname(file)# Read the whole text.text = open(path.join(d, 'alice.txt')).read()# read the mask / color image# taken from http://jirkavinse.deviantart.com/art/quot-Real-Life-quot-Alice-282261010alice_coloring = np.array(Image.open(path.join(d, "xhr.jpg")))wc = WordCloud(background_color="white", max_words=2000, mask=alice_coloring, stopwords=STOPWORDS.add("said"), max_font_size=40, random_state=42)# generate word cloudwc.generate(text)# create coloring from imageimage_colors = ImageColorGenerator(alice_coloring)# showplt.imshow(wc)plt.axis("off")plt.figure()# recolor wordcloud and show# we could also give color_func=image_colors directly in the constructorplt.imshow(wc.recolor(color_func=image_colors))plt.axis("off")plt.figure()plt.imshow(alice_coloring, cmap=plt.cm.gray)plt.axis("off")plt.show()
效果還可以,但是和我想的…不太一樣…我們嘗試調整一些參數。……當然,最佳效果可能需要很多次的嘗試才會出現。比如我將字號調大以后就會出現一些……奇怪的輸出,難道是因為白色白的不夠純凈嗎。
總體上講這樣的配色已經比上面那種花花綠綠的配色好多了…至于為什么白色區域還會有詞語,我剛看了一下小黃人的原圖,白色區域的確不完全是 255,255,255 ,應該是這個原因。
好了,到這里我們四幅樣例就都做完了。最后我發現缺少一張封面圖,那就再多來一張,順便嘗試一下 scale 參數。
我們嘗試在如下位置加入 scale 參數,設置為 1.5 倍。
wc=WordCloud(background_color="white",max_words=2000,mask=alice_coloring,stopwords=STOPWORDS.add("said"),max_font_size=40,random_state=42,scale =1.5 )
可以看到輸出的圖片的確是原圖的 2 倍。
再次強調使用 word_cloud 的幾個要點吧:
1、FONT_PATH
2、中文要實現分詞,輸出為數組,使用 frequencies 方法
3、scale 的用法,由于程序運行時間較長,如果生成大幅圖片會很慢,可以使用 scale 調節大小,但是會犧牲詞語對形狀的擬合度
到此標簽云這一系列就能告一段落了。我們由中文分詞引入,為了可視化展示,試用了兩個標簽云生成器。下面簡單總結比較一下 pytagcloud 和 word_cloud 的優點:
pytagcloud :
優點:依賴較少;可以同時添加多個字體,在代碼中選擇;提供相對完善的配色方案。
word_cloud:
優點:文字空隙可以嵌套詞語;支持自定義詞云形狀;支持通過圖片上色。
缺點:依賴較