大家好,今天帶大家了解下常用的兩種繪制詞云圖的方法,也許有你想要的哦。
Python詞云的繪制,今天他來了。
目錄:
1. wordcloud詞云繪制
1.1. 簡單的例子
1.2. 中文詞云制作
1.3. 自定義詞云蒙版圖
1.4. 詞頻信息數據詞云繪制
1.5. 更多參數設置說明
2. stylecloud詞云繪制
2.1. 簡單的例子
2.2. 自帶的配色方案
2.3. 自帶的蒙版方案
2.4. 如何自定義蒙版圖
2.5. 更多參數設置說明
我這邊之前一直是用的jieba+wordcloud,后來看到有朋友在用基于wordcloud的更高顏值的stylecloud,于是最近開始使用jieba+stylecloud了。
1. wordcloud詞云繪制
先安裝相關庫(如果已有則可無視)
pip?install?numpy
pip?install?pillow
pip?install?matplotlib
wordcloud依賴于numpy?and?pillow,同時如果要預覽或保存生成的詞云圖,matplotlib也是必須的。
再安裝worlcloud
pip?install?wordcloud
更多詳情大家可以去github了解:
https://github.com/amueller/word_cloud/
1.1. 簡單的例子
由于英文句子每個單詞之間都會由空格或標點符號分開,不需要做額外的分詞處理,因此對于英文文本來說,直接可用。
fromwordcloudimportWordCloud
#?詞云?文本來源?text
text?="apple?Banana?Blueberry?Cherry?Grape?Peach?Cherry?Cherry?Grape"
wc?=?WordCloud()
wc.generate(text)
#?存為本地圖片
wc.to_file("example.png")
#?matplotlib用于顯示?詞云圖
importmatplotlib.pyplotasplt
plt.imshow(wc)
plt.axis("off")
#?plt方式存為本地圖片
#?plt.savefig('詞云例子.png')
plt.show()
example
1.2. 中文詞云制作
由于中文博大精深,一段文本是有句子組成的,句子之間才有標點符號分開。而句子則是由單字或詞組無縫連接而成,所以我們需要對文本進行分詞處理。
這里用到的分詞庫是?jieba(https://github.com/fxsjy/jieba),思路上就是先用jieba進行分詞,然后再調用wor dcloud即可。
importjieba
importjieba.analyse
importmatplotlib.pyplotasplt
fromwordcloudimportWordCloud
#?我們以劉德華的《今天》歌詞為例
text?="""走過歲月我才發現世界多不完美
成功或失敗都有一些錯覺
滄海有多廣?江湖有多深
局中人才了解
生命開始情不情愿總要過完一生
交出一片心不怕被你誤解
誰沒受過傷?誰沒流過淚
何必要躲在黑暗里?自苦又自憐
我不斷失望?不斷希望
苦自己嘗?笑與你分享
如今站在臺上也難免心慌
如果要飛得高?就該把地平線忘掉
等了好久終于等到今天
夢了好久終于把夢實現
前途漫漫任我闖
幸虧還有你在身旁
盼了好久終于盼到今天
忍了好久終于把夢實現
那些不變的風霜早就無所謂
累也不說累"""
#?jieba分詞(精確模式)
text_after_split?=?jieba.cut(str(text),?cut_all=False)
words?='?'.join(text_after_split)
#?詞云參數設置
wc?=?WordCloud(
background_color='white',#?詞云圖背景顏色,默認為白色
font_path='FZZJ-YGYTKJW.TTF',#?詞云圖?字體(中文需要設定為本機有的中文字體)
)
wc.generate(words)
#?matplotlib用于顯示?詞云圖
plt.imshow(wc)
plt.axis("off")
plt.show()
《今天》歌詞詞云圖
注意:關于作圖的中文字體設置,大家可以參考《詳解Matplotlib中文字符顯示問題》
1.3. 自定義詞云蒙版圖
我們經常看到別的做的詞云的文字覆蓋區域剛好可以組成特定的圖形,如蘋果主題的以蘋果為形狀等等。
wordcloud提供參數mask用于我們進行自定義背景區域,由于mask接受的是nd-array類型參數,因此這里我們需要用先打開我們要用到的蒙版圖,然后轉化為nd-array。
關于蒙版圖設置需要注意:除全白(#FFFFFF)的部分將不會繪制,其余部分會用于繪制詞云
importnumpyasnp
fromPILimportImage
#?就下面代碼,即可獲取滿足類型要求的參數
bg=np.array(Image.open("蒙版圖.png"))
mask=bg
我們以 劉德華 形象為蒙版圖,接1.2節內容,用《今天》歌詞繪制詞云如下:
wc?=?WordCloud(width=500,#?詞云圖寬
height=500,#?詞云圖高
mask?=?mask,#?詞云蒙版圖
background_color='white',#?詞云圖背景顏色,默認為白色
font_path='FZZJ-YGYTKJW.TTF',#?詞云圖?字體(中文需要設定為本機有的中文字體)
max_font_size=400,#?最大字體,默認為200
random_state=50,#?為每個單詞返回一個PIL顏色
)
wc.generate(words)
#?matplotlib用于顯示?詞云圖
importmatplotlib.pyplotasplt
plt.imshow(wc)
plt.axis("off")
#?plt方式存為本地圖片
#?plt.savefig('詞云例子.png')
plt.show()
添加蒙版圖形狀后的效果圖
1.4. 詞頻信息數據詞云繪制
有時候我們可能在手上的 數據信息是 帶有詞頻信息的數據,這種情況下也是可以用wordcloud的generate_from_frequencies方法進行處理的,它接受一個包含詞頻信息數據的字典參數,比如下面這個例子:
importmatplotlib.pyplotasplt
fromwordcloudimportWordCloud
#?詞云參數設置
wc?=?WordCloud(
background_color='white',#?詞云圖背景顏色,默認為黑色
font_path='FZZJ-YGYTKJW.TTF',#?詞云圖?字體(中文需要設定為本機有的中文字體)
)
#?詞頻信息數據,用字典形式傳給?generate_from_frequencies
frequencies?=?{
'才哥':18,
'水哥':16,
'航哥':10,
'夢淚':11,
'牛頭':5,
'孫悟空':12,
'諸葛亮':18,
'馬超':7,
'劉備':12,
'黃忠':5,
'魯班8號':1,
}
wc.generate_from_frequencies(frequencies)#?根據詞頻信息數據做詞云圖
#?matplotlib用于顯示?詞云圖
plt.imshow(wc)
plt.axis("off")
plt.show()
詞頻信息數據詞云
1.5. 更多參數設置說明
另外,在進行詞云繪制時,還有很多別的參數大家可以自行摸索,讓你的詞云圖更加有個性。
wordcloud.WordCloud(font_path=None,?width=400,?height=200,?margin=2,?ranks_only=None,?prefer_horizontal=0.9,?mask=None,?scale=1,?color_func=None,?max_words=200,?min_font_size=4,?stopwords=None,?random_state=None,?background_color='black',?max_font_size=None,?font_step=1,?mode='RGB',?relative_scaling='auto',?regexp=None,?collocations=True,?colormap=None,?normalize_plurals=True,?contour_width=0,?contour_color='black',?repeat=False,?include_numbers=False,?min_word_length=0,?collocation_threshold=30)
參數說明:
在以下參數中,停用詞stopwords是我們用的較多的,比如我們對于某些詞不希望參與到詞云制作中,則可以將其添加到停用詞中。
font_path?:?string#字體路徑,需要展現什么字體就把該字體路徑+后綴名寫上,如:font_path =?'黑體.ttf'
width?:?int?(default=400)#輸出的畫布寬度,默認為400像素
height?:?int?(default=200)#輸出的畫布高度,默認為200像素
prefer_horizontal?:?float?(default=0.90)#詞語水平方向排版出現的頻率
mask?:?nd-arrayorNone(default=None)#如果參數為空,則使用二維遮罩繪制詞云。
scale?:?float?(default=1)#按照比例進行放大畫布,如設置為1.5,則長和寬都是原來畫布的1.5倍
min_font_size?:?int?(default=4)#顯示的最小的字體大小
font_step?:?int?(default=1)#字體步長,如果步長大于1,會加快運算但是可能導致結果出現較大的誤差
max_words?:?number?(default=200)#要顯示的詞的最大個數
stopwords?:?set?of?stringsorNone#設置需要屏蔽的詞,如果為空,則使用內置的STOPWORDS
background_color?:?color?value?(default=”black”)#背景顏色,如background_color='white'
max_font_size?:?intorNone(default=None)#顯示的最大的字體大小
mode?:?string?(default=”RGB”)#當參數為“RGBA”并且background_color不為空時,背景為透明
relative_scaling?:?float?(default=.5)#詞頻和字體大小的關聯性
color_func?:?callable,?default=None#生成新顏色的函數,如果為空,則使用?self.color_func
regexp?:?stringorNone(optional)#使用正則表達式分隔輸入的文本
collocations?:?bool,?default=True#是否包括兩個詞的搭配
colormap?:?stringormatplotlib?colormap,?default=”viridis”#給每個單詞隨機分配顏色,若指定color_func,則忽略該方法
random_state?:?intorNone#為每個單詞返回一個PIL顏色
2. stylecloud詞云繪制
stylecloud?是一位數據科學家叫Max Woolf的大神做出來的wordcloud詞云包的升級版,它讓詞云看起來更美觀了。
其核心主要在?配色方案?和?蒙版方案?上,其配色方案是讓詞云圖更美觀優雅的點,只能使用其提供的蒙版方案上我覺得反而讓自由空間變小了,所以今天我們會介紹如何自定義蒙版!
先安裝stylecloud庫
pip?install?stylecloud
更多詳情可以前往github了解:
https://github.com/minimaxir/stylecloud
2.1. 簡單的例子
由于stylecloud是基于wordcloud庫的,關于其他諸如中文分詞的操作這里就不再贅述了。
先看個簡單的列子吧:
importstylecloud
fromPILimportImage
#?詞云?文本來源?text
text?="apple?Banana?Blueberry?Cherry?Grape?Peach?Cherry?Cherry?Grape?AAA?BBB?CCC?DDD?EE?FFFF"
stylecloud.gen_stylecloud(text=text)#?默認會存一張名為stylecloud的png詞云圖
#?打開預覽?詞云圖
Image.open("stylecloud.png")
stylecloud
2.2. 自帶的配色方案
stylecloud配色方案是使用的高級調色板palettable來實現了,所以我們看起來很舒服吧。
大家可以去它的設計網站了解詳情:
https://jiffyclub.github.io/palettable/
調色板們
配置方案
具體調色板預覽
我們選擇某個如palettable.tableau,在頁面可見其效果預覽:
palettable.tableau
代碼里設置該參數
通過設置參數palette為指定配色方案,我們即可完成配色。比如我們拿palettable.tableau里的BlueRed_6,那么只需要加上參數palette='tableau.BlueRed_6'即可。
importstylecloud
fromPILimportImage
text?="apple?Banana?Blueberry?Cherry?Grape?Peach?Cherry?Cherry?Grape?AAA?BBB?CCC?DDD?EE?FFFF"
stylecloud.gen_stylecloud(
text=text,
palette='tableau.BlueRed_6',#?設置配色方案
)
Image.open("stylecloud.png")
tableau.BlueRed_6
2.3. 自帶的蒙版方案
stylecloud蒙版方案是使用的Font Awesome里現成的icon來實現了,由于這里有海量的圖標,大家總能找到自己想要的吧。
大家可以去它的網站了解詳情:
https://fontawesome.dashgame.com/
在stylecloud有一個fontawesome.min.css文件包含了巨量的圖標,你可以定期到官方網站獲取最新的圖標庫來更新。
默認蒙版庫文件
搜尋想要的圖標
大家還可以去以下兩個地址搜索你想要的蒙版圖標(icon)名稱,然后復制圖標名稱如蔬菜水果中的蘋果圖標名稱apple-alt。
https://fa5.dashgame.com/#/%E5%9B%BE%E6%A0%87
https://fontawesome.com/icons?d=gallery
搜索蔬菜水果
代碼里設置該參數
通過設置參數icon_name為指定蒙版圖標,我們即可完成設置蒙版。比如我們拿apple-alt為例,那么只需要加上參數icon_name='fas fa-apple-alt'即可。
importstylecloud
fromPILimportImage
text?="apple?Banana?Blueberry?Cherry?Grape?Peach?Cherry?Cherry?Grape?AAA?BBB?CCC?DDD?EE?FFFF"
stylecloud.gen_stylecloud(
text=text,
palette='tableau.BlueRed_6',#?設置配色方案
icon_name='fas?fa-apple-alt',#?設置蒙版方案
)
Image.open("stylecloud.png")
蘋果
注意:
需要關注的是圖標前綴存在三種:fas(實心)、far(常規)和fab(品牌)。大家在設置的時候一定要注意,比如我搜索apple-alt就是實心fas,大家在網站上是可以找到分類的。
圖標前綴類型
2.4. 如何自定義蒙版圖
通過上面的例子,我們發現stylecloud提供的蒙版功能只能選擇它所固有的,如果我想自定義設置任意的蒙版效果,該如何下手呢?
既然 是基于?wordcloud詞云庫,而且我們已經熟知了wordcloud如何自定義詞云蒙版的,那么我們打開?stylecloud庫的文件一探究竟!
文件路徑
我的路徑
查看代碼
直接查看 詞云圖繪制部分代碼,找到核心 代碼塊,也就是調用wordcloud的部分。
defgen_stylecloud(
text:?str?=?None,
file_path:?str?=?None,
size:?int?=512,
icon_name:?str?="fas?fa-flag",
palette:?str?="cartocolors.qualitative.Bold_5",
colors:?Union[str,?List[str]]?=?None,
background_color:?str?="white",
max_font_size:?int?=200,
max_words:?int?=2000,
stopwords:?bool?=?True,
custom_stopwords:?Union[List[str],?set]?=?STOPWORDS,
add_stopwords:?bool?=?False,
icon_dir:?str?=".temp",
output_name:?str?="stylecloud.png",
gradient:?str?=?None,
font_path:?str?=?os.path.join(STATIC_PATH,"Staatliches-Regular.ttf"),
random_state:?int?=?None,
collocations:?bool?=?True,
invert_mask:?bool?=?False,
pro_icon_path:?str?=?None,
pro_css_path:?str?=?None,
)
:
#...
wc?=?WordCloud(
background_color=background_color,
font_path=font_path,
max_words=max_words,
mask=mask_array,#?快看,這個是?蒙版設置參數
stopwords=custom_stopwordsifstopwordselseNone,
max_font_size=max_font_size,
random_state=random_state,
collocations=collocations,
#...
)
代碼分析及重構
分析以上代碼,我們發現 蒙版設置參數?mask?傳遞的是?mask_array?的值,具體不需要知道這個值怎么來的,我們要做的是如何 傳遞自定義的蒙版背景nd-array值。
為了兼容 他原本的 邏輯,這里我的思路是 :
gen_stylecloud()新增一個參數bg,其默認賦值為空字符串;當bg為空字符串的時候 參數?mask?傳遞的是?mask_array?的值;當bg為我們賦的nd-array值時,參數?mask?傳遞的是?bg的值。
基于上述思路,我們簡單重構代碼如下:
defgen_stylecloud(
*原有參數不變
bg:?str='',#?新增自定義蒙版參數
)
:
#...
wc?=?WordCloud(
background_color=background_color,
font_path=font_path,
max_words=max_words,
mask=mask_arrayiflen(bg)==0elsebg,#?快看,這個是?蒙版設置參數
stopwords=custom_stopwordsifstopwordselseNone,
max_font_size=max_font_size,
random_state=random_state,
collocations=collocations,
#...
)
效果演示
同樣以劉德華的《今天》歌詞為例:
importstylecloud
fromPILimportImage
importjieba
importjieba.analyse
text?="""走過歲月我才發現世界多不完美
成功或失敗都有一些錯覺
滄海有多廣?江湖有多深
局中人才了解
生命開始情不情愿總要過完一生
交出一片心不怕被你誤解
誰沒受過傷?誰沒流過淚
何必要躲在黑暗里?自苦又自憐
我不斷失望?不斷希望
苦自己嘗?笑與你分享
如今站在臺上也難免心慌
如果要飛得高?就該把地平線忘掉
等了好久終于等到今天
夢了好久終于把夢實現
前途漫漫任我闖
幸虧還有你在身旁
盼了好久終于盼到今天
忍了好久終于把夢實現
那些不變的風霜早就無所謂
累也不說累"""
#?jieba分詞(精確模式)
text_after_split?=?jieba.cut(str(text),?cut_all=False)
words?='?'.join(text_after_split)
#?就下面代碼,即可獲取滿足類型要求的參數
bg=np.array(Image.open("背景圖.png"))
stylecloud.gen_stylecloud(
text=words,
palette='tableau.BlueRed_6',#?設置配色方案
#?icon_name='fas?fa-apple-alt',
bg?=?bg,#?劉德華?照片為蒙版啦
font_path='FZZJ-YGYTKJW.TTF',#?詞云圖?字體(中文需要設定為本機有的中文字體)
)
Image.open("stylecloud.png")
效果對比
2.5. 更多參數設置說明
其他如背景色、詞云圖大小、停用詞參數等等,大家自行摸索吧!
text:?str?=None,#?輸入文本,最好在直接調用函數時使用
file_path:?str?=None,#?輸入文本的文件路徑
size:?int?=512,#?詞云圖長寬大小
icon_name:?str?="fas?fa-flag",#stylecloud?形狀的圖標名稱
palette:?str?="cartocolors.qualitative.Bold_5",#?配色方案
colors:?Union[str,?List[str]]?=None,
background_color:?str?="white",#?控制詞云圖底色,可傳入顏色名稱或16進制色彩
max_font_size:?int?=200,#?stylecloud?中的最大字號
max_words:?int?=2000,#?stylecloud?可包含的最大單詞數
stopwords:?bool?=True,#?布爾值,用于篩除常見禁用詞
custom_stopwords:?Union[List[str],?set]?=?STOPWORDS,#?傳入自定義的停用詞List
add_stopwords:?bool?=False,
icon_dir:?str?=".temp",
output_name:?str?="stylecloud.png",#?stylecloud?的輸出文本名
gradient:?str?=None,#?梯度方向
font_path:?str?=?os.path.join(STATIC_PATH,"Staatliches-Regular.ttf"),#?stylecloud?所用字體,若要正確顯示中文字符,需要指定中文字體
random_state:?int?=None,#?控制單詞和顏色的隨機狀態
collocations:?bool?=True,
invert_mask:?bool?=False,
pro_icon_path:?str?=None,
pro_css_path:?str?=None,