词云图笔记

相关库安装

1、WordCloud库安装(词云图经典库,一般做词云图基本上用这个库)

1
pip install wordcloud -i https://pypi.tuna.tsinghua.edu.cn/simple

2、StyleCloud库安装(详细作用见后文)

1
pip install stylecloud -i https://pypi.tuna.tsinghua.edu.cn/simple

3、Matplotlib库安装(预览和保存词云图,需要安装这个库)

1
pip install matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple

4、Numpy库安装(如果要以特定图片作为模板输出词云图的话,需要安装这个库)

1
pip install numpy -i https://pypi.tuna.tsinghua.edu.cn/simple

5、Pillow库安装(如果要以特定图片作为模板输出词云图的话,需要安装这个库,用于读取图片)
(注:要安装9.5.0的版本,要不然stylecloud库无法起作用)

1
pip install pillow==9.5.0 -i https://pypi.tuna.tsinghua.edu.cn/simple

基本使用

实现词云图的方式主要有两种,第一种是根据词频(最为常用);第二种是直接根据文本实现

第一种方式(词频字典生成词云图):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import wordcloud
import matplotlib.pyplot as plt

# 词频字典
test = {
'张三': 55,
'李四': 44,
'王五': 44,
'赵六': 44,
'孙七': 44,
}

# 根据词频字典生成词云图(fit_words)
wc = wordcloud.WordCloud(
background_color='white', # 将背景设置为白色
font_path='msyh.ttc' # 设置字体为微软雅黑,这个一定要设置,要不然识别不了中文
).fit_words(test)
# 将词云图保存
wc.to_file('result.png')

# 查看词云图
plt.imshow(wc)
plt.axis('off')
plt.show()

输出:

base-wordcount-wordcloud
第二种方式(文本生成):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import wordcloud
import matplotlib.pyplot as plt

# 这里不能用双引号,双引号指的是字符串,但是文本一般都很长,是远远超过了字符串的长度的。因此需要用三个双引号的形式,这种指的是文本(这种还可以用来当注释,类似于#,当注释内容很长的时候就可以用三个双引号的方式)
# 文本
test = """数字经济是继农业经济、工业经济之后的主要经济形态,是以数据资源为关键要素,以现代信息网络为主要载体,以信息通信技术融合应用、全要素数字化转型为重要推动力,促进公平与效率更加统一的新经济形态。数字经济发展速度之快、辐射范围之广、影响程度之深前所未有,正推动生产方式、生活方式和治理方式深刻变革,成为重组全球要素资源、重塑全球经济结构、改变全球竞争格局的关键力量。“十四五”时期,我国数字经济转向深化应用、规范发展、普惠共享的新阶段。为应对新形势新挑战,把握数字化发展新机遇,拓展经济发展新空间,推动我国数字经济健康发展,依据《中华人民共和国国民经济和社会发展第十四个五年规划和2035年远景目标纲要》,制定本规划。"""

# 根据文本方式建造词云图(generate)
wc = wordcloud.WordCloud(
background_color='white', # 将背景设置为白色
font_path='msyh.ttc' # 设置字体为微软雅黑,这个一定要设置,要不然识别不了中文
).generate(test)
# 将词云图保存
wc.to_file('result.png')

# 查看词云图
plt.imshow(wc)
plt.axis('off')
plt.show()

输出:

base-content-generate

观察代码运行结果可以发现,它是对文本基于标点符号断句后,用每个断句生成的词云图。为什么是这种结果呢?

这里可以联想到英文句式的结构,比如“Python is excellent!”,在这句话里,每个单词之间用空格隔开。类推英文文章,每个单词是用空格或标点符号进行隔开。借此分析,可以知道WordCloud库根据文本制作词云图的这种方式,其实就是先将文本分词,分出每个英文单词后再计算词频从而生成词云图

分析出这个后,再来理解对中文文本的分词,就不难理解为什么会出现上图的这种用每个断句生成词云图的情况了:WordCloud将每个(根据标点符号断开的)断句当成了英文文章中的一个词语

那么如何解决呢?

可以参照这个解决思路:先自行将文本分词,将分词后的结果使用空格衔接,使得格式和英文保持一致,变成伪英文句式文本后再使用WordCloud就行了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import jieba

# 文本
test = """数字经济是继农业经济、工业经济之后的主要经济形态,是以数据资源为关键要素,以现代信息网络为主要载体,以信息通信技术融合应用、全要素数字化转型为重要推动力,促进公平与效率更加统一的新经济形态。数字经济发展速度之快、辐射范围之广、影响程度之深前所未有,正推动生产方式、生活方式和治理方式深刻变革,成为重组全球要素资源、重塑全球经济结构、改变全球竞争格局的关键力量。“十四五”时期,我国数字经济转向深化应用、规范发展、普惠共享的新阶段。为应对新形势新挑战,把握数字化发展新机遇,拓展经济发展新空间,推动我国数字经济健康发展,依据《中华人民共和国国民经济和社会发展第十四个五年规划和2035年远景目标纲要》,制定本规划。"""

# 使用jieba精确模式进行分词
seg_lst = jieba.cut(test, cut_all=False)

# 伪英文句式文本
content = ' '.join(i for i in seg_lst)

# 根据文本方式生成词云图(generate)
wc = wordcloud.WordCloud(
background_color='white', # 将背景设置为白色
font_path='msyh.ttc' # 设置字体为微软雅黑,这个一定要设置,要不然识别不了中文
).generate(content)
# 将词云图保存
wc.to_file('result.png')

# 查看词云图
plt.imshow(wc)
plt.axis('off')
plt.show()

输出:

base-content-generate-mod

上述两种方式可以按自己喜好自行选择使用

写者建议使用第一种,因为第二种方式主要是针对英文文章的使用,用在中文文章上有种画蛇添足的感觉(既然对文章分词了就没必要再将其变成英文文章的格式,直接计算词频并生成词云图就行了)

常规使用

1、默认矩形词云图

了解完基础使用后,可以处理下稍微复杂的场景:先用Jieba库将上述文本分词(直接分词,不使用停用词),然后生成词频字典,最后再生成词云图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import wordcloud
import matplotlib.pyplot as plt
import jieba
from collections import Counter

# 文本
test = """数字经济是继农业经济、工业经济之后的主要经济形态,是以数据资源为关键要素,以现代信息网络为主要载体,以信息通信技术融合应用、全要素数字化转型为重要推动力,促进公平与效率更加统一的新经济形态。数字经济发展速度之快、辐射范围之广、影响程度之深前所未有,正推动生产方式、生活方式和治理方式深刻变革,成为重组全球要素资源、重塑全球经济结构、改变全球竞争格局的关键力量。“十四五”时期,我国数字经济转向深化应用、规范发展、普惠共享的新阶段。为应对新形势新挑战,把握数字化发展新机遇,拓展经济发展新空间,推动我国数字经济健康发展,依据《中华人民共和国国民经济和社会发展第十四个五年规划和2035年远景目标纲要》,制定本规划。"""

# 使用jieba精确模式进行分词
seg_lst = jieba.cut(test, cut_all=False)

# 计算词频,生成词频字典
word_count = dict(Counter(seg_lst))

# 根据词频字典生成词云图(fit_words)
wc = wordcloud.WordCloud(
background_color='white', # 将背景设置为白色
font_path='msyh.ttc' # 设置字体为微软雅黑,这个一定要设置,要不然识别不了中文
).fit_words(word_count)
# 将词云图保存
wc.to_file('result.png')

# 查看词云图
plt.imshow(wc)
plt.axis('off')
plt.show()

输出:

default-shape

(可以发现标点符号也被做进词云图了)

2、自定义形状词云图

借由上述代码,可以发现制作词云图并不难。上面这些词云图,都是矩形形状。在网上查词云图的时候会搜到很多各种自定义形状的词云图

对此,依旧可以用WordCloud实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import wordcloud
import matplotlib.pyplot as plt
import jieba
from collections import Counter
import numpy as np
from PIL import Image

# 文本
test = """数字经济是继农业经济、工业经济之后的主要经济形态,是以数据资源为关键要素,以现代信息网络为主要载体,以信息通信技术融合应用、全要素数字化转型为重要推动力,促进公平与效率更加统一的新经济形态。数字经济发展速度之快、辐射范围之广、影响程度之深前所未有,正推动生产方式、生活方式和治理方式深刻变革,成为重组全球要素资源、重塑全球经济结构、改变全球竞争格局的关键力量。“十四五”时期,我国数字经济转向深化应用、规范发展、普惠共享的新阶段。为应对新形势新挑战,把握数字化发展新机遇,拓展经济发展新空间,推动我国数字经济健康发展,依据《中华人民共和国国民经济和社会发展第十四个五年规划和2035年远景目标纲要》,制定本规划。"""

# 使用jieba精确模式进行分词
seg_lst = jieba.cut(test, cut_all=False)

# 计算词频,生成词频字典
word_count = dict(Counter(seg_lst))

# 加载背景图片,生成遮罩
mask = np.array(Image.open('./背景图片/猫.jpg'))

# 生成带遮罩(自定义图片)的词云图
wc = wordcloud.WordCloud(
background_color='white',
mask=mask,
font_path='msyh.ttc'
).fit_words(word_count)
# 将词云图保存
wc.to_file('result.png')

# 查看词云图
plt.imshow(wc)
plt.axis('off')
plt.show()

遮罩图与输出:

示例1:

cat-mask cat-mask-wordcloud

示例2:

man-mask man-mask-wordcloud

自定义形状的时候,可以使用p图软件,将图片制作成黑白图片,然后就可以当成遮罩用于制作自定义形状词云图了

3、拓展

在前文相关库安装的内容中,有这么个库:StyleCloud,该库也是用来生成词云图的(基于WordCloud,有更多的功能)

注:StyleCloud只能使用文本方式(也就是前面提到过的伪英文文本形式)生成

这里依旧以前面的那段文本为例,生成词云图:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import stylecloud
import matplotlib.pyplot as plt
import jieba

# 文本
test = """数字经济是继农业经济、工业经济之后的主要经济形态,是以数据资源为关键要素,以现代信息网络为主要载体,以信息通信技术融合应用、全要素数字化转型为重要推动力,促进公平与效率更加统一的新经济形态。数字经济发展速度之快、辐射范围之广、影响程度之深前所未有,正推动生产方式、生活方式和治理方式深刻变革,成为重组全球要素资源、重塑全球经济结构、改变全球竞争格局的关键力量。“十四五”时期,我国数字经济转向深化应用、规范发展、普惠共享的新阶段。为应对新形势新挑战,把握数字化发展新机遇,拓展经济发展新空间,推动我国数字经济健康发展,依据《中华人民共和国国民经济和社会发展第十四个五年规划和2035年远景目标纲要》,制定本规划。"""

# 使用jieba精确模式进行分词
seg_lst = jieba.cut(test, cut_all=False)

# 伪英文句式文本
content = ' '.join(i for i in seg_lst)

# 使用stylecloud生成词云图
"""
background_color: 设置背景为白色
icon_name: 设置词云图形状为apple形状,这里设置为apple的时候后面要加上-alt,要不然运行不出来
font_path: 设置字体为微软雅黑,文本中有中文的时候一定要设置中文字体,要不然显示不出来
output_name: 保存词云图
"""
stylecloud.gen_stylecloud(text=content,
background_color='white',
icon_name='fas fa-apple-alt',
font_path='msyh.ttc',
output_name='result.png')

输出:

stylecloud-first-time-use

上述代码运行结果便是提StyleCloud这个库的另一个原因:这个库可以使用图标来生成词云图,也就是icon_name这个参数
可以从这个网站(https://fontawesome.dashgame.com/)找到各种各样的图标形式进行使用,非常棒!

部分图标:

stylecloud-icon-list

使用的时候,只需要在图标名称前加上前缀fas fa-即可。比如car,就需要改成fas fa-car;又或者birthday-cake,就需要改成fas fa-birthday-cake。以下是对应示例:

car:

1
2
3
4
5
stylecloud.gen_stylecloud(text=content,
background_color='white',
icon_name='fas fa-car',
font_path='msyh.ttc',
output_name='result.png')
stylecloud-car-icon

birthday-cake:

1
2
3
4
5
stylecloud.gen_stylecloud(text=content,
background_color='white',
icon_name='fas fa-birthday-cake',
font_path='msyh.ttc',
output_name='result.png')
stylecloud-birthday-cake-icon

综合

结合Jieba库,分别使用WordCloud和StyleCloud制作十四五数字经济发展规划文本的词云图:

以下是前置代码。另外,**注意!**一定要注意文件路径部分的代码,确保文件路径与代码内容保持一致,否则无法读取相关文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import jieba
import re

# 添加自定义词典
jieba.load_userdict('./分词部分/自定义分词词典/userDict.txt')

# 读取文本
with open('./分词部分/十四五数字经济发展规划.txt','r',encoding='UTF-8') as file:
content = file.read()

# 首先将文本剔除一些特殊符号,比如换行符、标点符之类的
# 停用词-符号
pattern = u'[\\s\\d,.<>/?:;\'\"[\\]{}()\\|~!\t"@#$%^&*\\-_=+,。\n《》、?:;“”‘’{}【】()…¥!—┄-]+'
# 去除文本中停用词符号
content_ = re.sub(pattern, "", content)

# 读取哈工大停用词列表
with open('./分词部分/中文常用停留词/hit_stopwords.txt', 'r', encoding='utf-8') as f_txt:
lines = f_txt.readlines()
hit_stopWords = [line.strip() for line in lines]


# 使用jieba精确模式进行分词
seg_lst = jieba.cut(content_, cut_all=False)

# 去除停用词并存入res列表中
res = []
for seg in seg_lst:
# len(seg)>=2指词语的长度需要≥2,也就规避了单个字的词语
if seg not in hit_stopWords and len(seg)>=2:
res.append(seg)

1、WordCloud

  • 词频字典方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from collections import Counter
import numpy as np
from PIL import Image
import wordcloud
import matplotlib.pyplot as plt

# 计算词频,生成词频字典
word_count = dict(Counter(res))

# 加载背景图片,生成遮罩
mask = np.array(Image.open('./背景图片/猫.jpg'))

# 生成带遮罩(自定义图片)的词云图
wc = wordcloud.WordCloud(
background_color='white',
mask=mask,
font_path='msyh.ttc'
).fit_words(word_count)
# 将词云图保存
wc.to_file('result.png')

# 查看词云图
plt.imshow(wc)
plt.axis('off')
plt.show()

输出:

practice-wordcount
  • 文本生成方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import numpy as np
from PIL import Image
import wordcloud
import matplotlib.pyplot as plt

# 伪英文句式文本
content = ' '.join(i for i in res)

# 加载背景图片,生成遮罩
mask = np.array(Image.open('./背景图片/猫.jpg'))

# 生成带遮罩(自定义图片)的词云图
wc = wordcloud.WordCloud(
background_color='white',
mask=mask,
font_path='msyh.ttc'
).generate(content)
# 将词云图保存
wc.to_file('result.png')

# 查看词云图
plt.imshow(wc)
plt.axis('off')
plt.show()

输出:

practice-content-generate

2、StyleCloud

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import stylecloud

# 伪英文句式文本
content = ' '.join(i for i in seg_lst)

# 使用stylecloud生成词云图
"""
background_color: 设置背景为白色
icon_name: 设置词云图形状为apple形状,这里设置为apple的时候后面要加上-alt,要不然运行不出来
font_path: 设置字体为微软雅黑,文本中有中文的时候一定要设置中文字体,要不然显示不出来
output_name: 保存词云图
"""
stylecloud.gen_stylecloud(text=content,
background_color='white',
icon_name='fas fa-apple',
font_path='msyh.ttc',
output_name='result.png')

输出:

practice-stylecloud