ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Python词云7案例:中文分词、蒙版配色与关键词权重实战

Python词云7案例:中文分词、蒙版配色与关键词权重实战

简介:面向文本挖掘与数据可视化初学者及中级 Python 用户的词云实战教程,围绕个性化词云生成流程展开,帮助解决中文文本可视化、关键词呈现与报告演示中的落地问题。压缩包含 1 个 PDF,大小约 2.07MB,内容按概念、库用法、环境配置与 7 个案例组织,从最简调用、中文不分词与分词处理,延伸到蒙版形状、自定义配色、关键词及权重提取等进阶做法,并配有代码示例与运行结果。已有 109 人学习,适合在项目报告、数据分析、社交媒体监控或教学场景中按案例复现,读者可掌握 wordcloud 与 matplotlib 的配合方式,理解文本预处理、权重计算、词云生成及保存展示的完整链路,也能参考教程给出的环境版本快速上手。

1. 需求切入:从一段文本到一张能交作业的词云图

要把一段中文文本变成能放进报告里的词云图,很多人的第一反应是找一份 Python 词云完整教程,最好带 7 个案例,能直接照着跑。作为一份 python 课程资源,这套材料最有价值的地方不是“生成一张图”四个字,而是把最简调用、中文不分词、中文分词、蒙版形状、蒙版颜色、自定义颜色函数、关键词权重七个台阶排成了一条可复现的路线。

词云看着像视觉活,实际是文本预处理和参数控制的活:字体路径错一个字符,中文全变方块;分词少一个空格,词频统计直接失真;蒙版背景不是纯白,形状就变成一块矩形。

这份方案适合需要交课程设计、做数据分析报告、给社团活动做展示的人,也适合想快速摸清 wordcloud 参数的开发者。后面按环境基线、案例递进、关键实现、避坑排查、验收答辩展开。

2. 环境与依赖设计:Python 3.7 与 wordcloud 1.9.3 的复现基线

词云项目的第一个交付物不是图片,而是一套别人能复现的环境。课程资源里最容易省掉的就是版本说明,结果同一段代码在别人机器上跑出方块字、报 PIL 兼容错误,或者 jieba 分词结果跟演示图对不上。这套教程给的是 Python 3.7、wordcloud 1.9.3、matplotlib 3.5.3、PyCharm 编辑器,版本不算新,但组合稳定,适合做课程设计底稿。我一般会把版本写进requirements.txt,再配一个最小冒烟脚本,先确认环境能出图,再谈蒙版和配色。

2.1 版本基线与目录结构

先把目录定下来,后面七个案例都往同一个结构里放,避免代码里到处出现../猜路径。建议按“数据、字体、蒙版、输出、脚本”分开放,路径少一层,调试时少一堆 FileNotFoundError。

目录/文件用途设计说明
data/存放constitution.txt、xyj.txt等文本文本统一 UTF-8,避免 Windows 默认编码干扰
fonts/存放中文字体文件文件名为英文,路径不用中文和空格
masks/存放black_mask.png、color_mask.png形状蒙版和颜色蒙版分开放
output/存放生成的 png每次运行覆盖同名文件,答辩时好找
cases/七个案例脚本一个案例一个文件,方便对照
requirements.txt版本锁定只写直接依赖,不锁死间接依赖

版本基线建议这样理解:Python 3.7 是教程给出的运行环境,不是唯一选择;wordcloud 1.9.3 和 matplotlib 3.5.3 是这套案例验证过的组合。新手最容易踩的坑是只装 wordcloud 不装 pillow 和 numpy,结果蒙版案例一跑就报模块缺失。jieba 负责中文分词和关键词权重,Pillow 负责读蒙版图,numpy 负责把图片转成数组,四个依赖要一起装。

2.2 安装命令与最小冒烟测试

安装不用追求最新版,先按教程版本走。虚拟环境能少污染系统 Python,PyCharm 里新建项目时直接把解释器指到venv就行。

# 在项目根目录创建虚拟环境 python -m venv venv # macOS / Linux 激活 source venv/bin/activate # Windows 激活 # venv\Scripts\activate # 按教程版本安装核心依赖 pip install wordcloud==1.9.3 matplotlib==3.5.3 jieba pillow numpy

这段命令的逻辑是先隔离环境,再装词云、绘图、分词、图像读取和数组处理五个依赖。wordcloud==1.9.3固定版本,避免新版参数行为差异;matplotlib==3.5.3跟教程展示代码一致;jieba不锁小版本,中文分词接口稳定;pillow和numpy不写版本,让 pip 按 Python 3.7 选兼容版本。安装完不要急着跑七个案例,先做一个最小冒烟测试。

# smoke_test.py # 最小验证:不读文件、不用中文、不设蒙版,只确认 wordcloud 能出图 from wordcloud import WordCloud wc = WordCloud(width=400, height=200, background_color="white") wc.generate("python word cloud smoke test") wc.to_file("output/smoke.png") print("smoke ok")

这段代码只做一件事:用英文短语生成一张小图。width和height控制画布尺寸,background_color设白色背景,generate接收原始文本,to_file输出 png。跑通后看output/smoke.png是否存在,存在就说明 wordcloud、Pillow、numpy 的链路通了。如果这一步就报错,先别改中文参数,回头查依赖安装顺序和 Python 解释器是不是 PyCharm 当前选中的那个。

提示:PyCharm 里经常出现“终端装好了、运行还是 ModuleNotFoundError”,多半是项目解释器和终端虚拟环境不是同一个,先看右下角解释器路径。

2.3 参数默认值与第一次改参的顺序

wordcloud 的参数很多,第一次改参不要从颜色函数开始,先把“能不能出词、词大不大、中文显不显示”三件事控制住。下面这几个参数是七个案例里复用频率最高的。

参数作用建议起始值注意点
font_path指定中文字体项目内fonts/下的 ttf不设中文变方块
width/height画布宽高800 / 600有 mask 时以蒙版尺寸为主
background_color背景色"white"或None透明背景要配mode="RGBA"
max_words最多显示词数200太多会挤,太少会空
max_font_size最大字号不设或 120设太小会压不住重点词
relative_scaling词频与字号关联度0.5 左右调大更强调高频词
prefer_horizontal水平词比例0.9中文竖排阅读体验差,尽量高
mask形状蒙版数组np.array(Image.open(...))背景要纯白,形状区非白

第一次改参的顺序我一般这样走:先固定font_path,再调width/height,然后加max_words,最后才动relative_scaling和颜色。因为字体错是硬错误,尺寸错是布局问题,词数错是信息密度问题,颜色只是表现层。顺序反过来,出了方块字还以为是配色函数写坏了,排查成本翻倍。

3. 七个案例的递进设计:从最简调用到关键词权重

七个案例不是七个孤立 demo,而是一条从“能出图”到“可控出图”的路线。案例 01 只验证库调用;案例 02 用中文不分词做对照,让人看到不分词的后果;案例 03 引入 jieba,把中文文本切成词;案例 04 到 06 逐层加蒙版形状、蒙版颜色、自定义颜色函数;案例 07 用jieba.analyse.extract_tags提取关键词和权重,再走generate_from_frequencies。这条路线的好处是每一层只增加一个变量,答辩时被问“为什么这个词大”能顺着案例讲清楚。

3.1 案例分组与依赖边界

先看七个案例各自解决什么问题,避免一上来就堆蒙版和颜色,结果连基础词频都没跑通。

案例核心能力新增依赖/参数适用场景
01 最简调用英文文本生成词云WordCloud().generate第一次验证环境
02 中文不分词展示不分词效果font_path、mode、background_color教学对照,不作为生产方案
03 中文分词jieba 切词后生成jieba.cut、" ".join中文报告、课程设计
04 蒙版形状用图片轮廓限制词云形状mask、Pillow、numpy活动海报、品牌图形
05 蒙版颜色从蒙版图取色ImageColorGenerator需要跟主视觉配色一致
06 自定义颜色函数自己控制颜色分布color_func需要固定色系或随机色
07 关键词权重用关键词权重替代纯词频jieba.analyse.extract_tags文本挖掘、主题分析

这张表建议直接放进课程设计的需求说明里。案例 02 容易被误解成“中文也能跑”,其实它只是把不分词的文本丢给 WordCloud,默认按空格和正则切分,中文长句很容易被当成一个大块,词云看着有字,但频率信息已经失真。案例 03 才是中文场景的起点。

3.2 案例 01 到 03:先跑通,再做中文对照

案例 01 的代码最短,价值在于把“读文本、生成对象、显示、保存”四步拆开。很多教程把显示和保存混在一起,出图失败时分不清是生成失败还是保存失败。

# case01_minimal.py # 最简调用:英文文本,不设字体,不设蒙版 from wordcloud import WordCloud import matplotlib.pyplot as plt # 读取同目录下的文本,确保文件编码为 UTF-8 text = open("data/constitution.txt", encoding="utf-8").read() # 生成词云对象,先用默认参数 wc = WordCloud().generate(text) # 显示:bilinear 让缩放更平滑,axis off 去掉坐标轴 plt.imshow(wc, interpolation="bilinear") plt.axis("off") plt.show() # 保存到 output 目录,方便答辩时直接拿图 wc.to_file("output/case01_wordcloud.png")

这段代码的逻辑是“读、生成、显示、保存”。WordCloud()不传参数时用默认画布和默认字体,适合英文;generate(text)内部会做分词和词频统计;plt.imshow只负责展示,wc.to_file才是落盘。参数上先不用调,跑通后看输出图里单词大小是否跟词频大致对应,如果全是小词,再考虑调max_font_size或relative_scaling。

案例 02 用中文文本,但不做分词,只加字体和透明背景。它的作用是让人直观看到“中文不分词”长什么样,不是让你直接交作业。

# case02_chinese_no_segment.py # 中文不分词:只加字体和透明背景,用来做对照 from wordcloud import WordCloud import matplotlib.pyplot as plt with open("data/xyj.txt", "r", encoding="utf-8") as f: text = f.read() # font_path 必须指向真实存在的中文字体文件 wc = WordCloud( font_path="fonts/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("output/case02_no_segment.png")

这里新增了三个参数:font_path解决中文显示,mode="RGBA"支持透明通道,background_color=None让背景透明。注意font_path是硬路径,文件不存在会直接报错或回退到默认字体,中文就成方块。案例 02 的输出通常会出现大块连续文本或词边界模糊,这正是案例 03 要解决的问题。

案例 03 引入 jieba,把中文长句切成词,再用空格拼回去。WordCloud 默认按空格分词,所以" ".join(jieba.cut(text))这一步不能省。

# case03_chinese_segment.py # 中文分词:jieba 切词后用空格连接,再交给 WordCloud from wordcloud import WordCloud import matplotlib.pyplot as plt import jieba with open("data/xyj.txt", "r", encoding="utf-8") as f: text = f.read() # jieba.cut 返回生成器,必须用空格拼成字符串 text = " ".join(jieba.cut(text)) print(text[:100]) # 打印前 100 个字符,检查分词是否正常 wc = WordCloud( font_path="fonts/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("output/case03_segment.png")

这段代码的关键是jieba.cut(text)返回的是生成器,直接传给 WordCloud 不行,必须" ".join(...)变成空格分隔的字符串。print(text[:100])是调试手段,看一眼前 100 个字符有没有被切成“孙悟空 师徒 取经”这类词块。如果打印出来还是长句,说明 jieba 没装好或文本编码不对。参数上,jieba.cut默认精确模式,课程设计够用;要召回更多长词可以换搜索引擎模式,但词云会更密,建议先精确模式出基线图。

3.3 案例 04 到 06:蒙版形状、蒙版颜色和自定义颜色

蒙版案例是词云从“图”变成“视觉物料”的分水岭,也是最容易翻车的地方。案例 04 只加形状,案例 05 从蒙版图取色,案例 06 自己写颜色函数,三层递进,每层只多一个变量。

# case04_mask_shape.py # 蒙版形状:用黑白蒙版限制词云轮廓 from wordcloud import WordCloud from PIL import Image import numpy as np import matplotlib.pyplot as plt import jieba with open("data/xyj.txt", "r", encoding="utf-8") as f: text = f.read() text = " ".join(jieba.cut(text)) # 蒙版图:形状区域非白,背景纯白;转成 numpy 数组 mask = np.array(Image.open("masks/black_mask.png")) wc = WordCloud( mask=mask, font_path="fonts/Hiragino.ttf", mode="RGBA", background_color=None, ).generate(text) plt.imshow(wc, interpolation="bilinear") plt.axis("off") plt.show() wc.to_file("output/case04_mask_shape.png")

这段代码新增mask参数,PIL.Image.open读图,np.array转数组。蒙版图的规则通常是:要填词的形状区域用黑色或深色,背景用纯白;WordCloud 会把白色区域当成不填词的背景。如果蒙版背景是浅灰或带渐变,形状边缘会糊,甚至整张图变成矩形。参数上,给了mask后width/height不再主导画布,输出尺寸跟蒙版像素相关,蒙版太大跑得慢,建议先缩到 800 到 1200 像素宽再试。

案例 05 在蒙版基础上加ImageColorGenerator,从蒙版图里取颜色,让词的颜色跟原图主色一致。

# case05_mask_color.py # 蒙版颜色:从彩色蒙版图中提取颜色 from wordcloud import WordCloud, ImageColorGenerator from PIL import Image import numpy as np import matplotlib.pyplot as plt import jieba with open("data/xyj.txt", "r", encoding="utf-8") as f: text = f.read() text = " ".join(jieba.cut(text)) mask = np.array(Image.open("masks/color_mask.png")) wc = WordCloud( mask=mask, font_path="fonts/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("output/case05_mask_color.png")

这里的逻辑是先用蒙版生成词云,再用ImageColorGenerator(mask)建颜色生成器,wc.recolor(color_func=image_colors)按蒙版对应位置取色。参数上,mask同时承担形状和颜色来源,所以彩色蒙版不能随便换,换图就等于换配色。recolor要在generate之后调用,顺序反了不生效。案例 05 的输出通常比案例 04 更接近海报,但颜色会受蒙版局部色块影响,出现某些词颜色太浅,这时才需要案例 06 的自定义颜色函数。

案例 06 完全自己控制颜色,适合固定色系或做随机但可控的配色。

# case06_custom_color.py # 自定义颜色函数:返回 hsl 颜色字符串 from wordcloud import WordCloud from PIL import Image import numpy as np import matplotlib.pyplot as plt import random import jieba with open("data/xyj.txt", "r", encoding="utf-8") as f: text = f.read() text = " ".join(jieba.cut(text)) def random_color(word, font_size, position, orientation, font_path, random_state): # 色相固定为 0,饱和度和亮度在 60% 到 80% 之间随机 return "hsl(0, %d%%, %d%%)" % ( random.randint(60, 80), random.randint(60, 80), ) mask = np.array(Image.open("masks/color_mask.png")) wc = WordCloud( color_func=random_color, mask=mask, font_path="fonts/Hiragino.ttf", mode="RGBA", background_color=None, ).generate(text) plt.imshow(wc, interpolation="bilinear") plt.axis("off") plt.show() wc.to_file("output/case06_custom_color.png")

颜色函数的签名必须按word, font_size, position, orientation, font_path, random_state来写,返回值要是 matplotlib 能解析的颜色字符串,比如hsl(...)、#RRGGBB或英文颜色名。这段代码把色相固定在红色系,饱和度和亮度随机,适合做单一主色的活动图。参数上,random.randint(60, 80)的范围控制颜色深浅,调低会更暗,调高会更亮;如果想让颜色跟词频走,可以在函数里用font_size做分支,但别写太复杂,否则每次生成都像开盲盒。

3.4 案例 07:关键词权重与generate_from_frequencies

案例 07 是整套教程里最像“文本挖掘”的一步。前面案例都是把分词后的文本丢给 WordCloud 让它自己算词频,案例 07 先用jieba.analyse.extract_tags提关键词和权重,再用generate_from_frequencies按权重生成。

# case07_keyword_weight.py # 关键词权重:jieba 提词和权重,WordCloud 按权重生成 from wordcloud import WordCloud, ImageColorGenerator from PIL import Image import numpy as np import matplotlib.pyplot as plt import jieba.analyse with open("data/xyj.txt", "r", encoding="utf-8") as f: text = f.read() # topK 控制关键词数量,withWeight=True 返回 (词, 权重) freq = jieba.analyse.extract_tags(text, topK=200, withWeight=True) print(freq[:20]) # 检查前 20 个关键词和权重 # 转成 WordCloud 需要的字典格式 freq = {i[0]: i[1] for i in freq} mask = np.array(Image.open("masks/color_mask.png")) wc = WordCloud( mask=mask, font_path="fonts/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("output/case07_keyword_weight.png")

这段代码的关键是extract_tags(text, topK=200, withWeight=True)返回列表,元素是(词, 权重),必须转成{词: 权重}字典再传给generate_from_frequencies。topK控制关键词数量,200 是教程给的起点;调小会让图更聚焦,调大权重会扁平,重点词不突出。withWeight=True不能省,否则只有词没有权重,generate_from_frequencies拿不到大小依据。案例 07 适合做主题分析页,答辩时能解释“这个词大不是因为出现次数多,而是因为 TF-IDF 权重高”,比单纯说词频更有说服力。

4. 关键实现拆解:分词、蒙版、配色与输出参数

七个案例跑通后,真正决定交付质量的是四个实现点:分词和停用词、蒙版和尺寸、颜色函数、输出和展示。这四个点每个都有参数可调,也都有失败表现。我的习惯是每个点单独写一个小脚本,改一个参数看一次输出,不在一张图上同时改五个变量,否则出了问题连后悔药都没地方买。

4.1 分词与停用词:让词云里的词像“词”

中文词云最常见的问题不是图不好看,而是图上飘着“的、了、在、是”这些高频虚词,真正的主角被挤到角落。jieba 只负责切词,不负责去停用词,停用词表要自己加。

# segment_with_stopwords.py # 分词后过滤停用词,再拼成空格分隔字符串 import jieba with open("data/xyj.txt", "r", encoding="utf-8") as f: text = f.read() # 停用词按行放,实际项目可换成更完整的表 stopwords = set() with open("data/stopwords.txt", "r", encoding="utf-8") as f: for line in f: stopwords.add(line.strip()) words = [] for word in jieba.cut(text): word = word.strip() # 过滤空串、单字和停用词;单字是否保留看场景 if len(word) > 1 and word not in stopwords: words.append(word) text = " ".join(words) print(text[:200])

这段代码的逻辑是“切词、清洗、拼接”。stopwords用集合,查找比列表快;len(word) > 1过滤单字,中文里“的”“了”大多是单字,但人名地名也可能是单字,课程设计里先过滤单字能明显提升可读性;word not in stopwords去掉停用词。参数上,停用词表不要用英文表直接套中文,也不要把“不”“无”这类否定词随便删掉,做情感分析时会改变语义。停用词表建议单独放data/stopwords.txt,答辩时能说明“这张图去掉了 30 个停用词”,比说“调了参数”更具体。

4.2 蒙版与尺寸:形状由蒙版决定,清晰度由画布决定

蒙版不是随便找一张图就能用。WordCloud 把蒙版里白色区域当背景,非白区域填词,所以蒙版图要先处理成“形状区域深色、背景纯白”。如果原图是透明背景 png,读进来 alpha 通道可能让数组变成四通道,形状判断会出问题。

# prepare_mask.py # 把蒙版统一处理成 RGB 白底图,避免透明通道干扰 from PIL import Image import numpy as np img = Image.open("masks/source_mask.png").convert("RGB") # 如果背景不是纯白,可以按阈值二值化:浅色变白,深色保留 arr = np.array(img) # 亮度大于 240 的像素视为背景,统一刷白 brightness = arr.mean(axis=2) arr[brightness > 240] = [255, 255, 255] Image.fromarray(arr).save("masks/black_mask.png") print(arr.shape)

这段代码先convert("RGB")去掉 alpha 通道,再按亮度阈值把浅色背景刷白。arr.mean(axis=2)算每个像素三通道平均值,brightness > 240是经验阈值,背景偏灰时调到 220 或 230;arr[brightness > 240] = [255, 255, 255]把背景统一成纯白。输出arr.shape能看到(高, 宽, 3),高宽就是蒙版尺寸。蒙版太大时词云跑得慢,建议先缩到 1000 像素宽以内;蒙版太小词会挤,max_words要相应调低。注意width/height和mask同时给时,以蒙版尺寸为主,别再手动设画布,否则容易出白边。

4.3 颜色函数与 ImageColorGenerator:配色要可解释

颜色这块有两个选择:用ImageColorGenerator从蒙版取色,或者写color_func自己控制。前者适合“图里有主视觉”的场景,后者适合“固定品牌色”或“按词频分色”的场景。两条路不要混着调,先选一条跑通。

# color_by_frequency.py # 按词频字号分色:高频词深色,低频词浅色 from wordcloud import WordCloud import matplotlib.pyplot as plt text = "python data text cloud visual analysis report" wc = WordCloud(width=800, height=400, background_color="white").generate(text) def color_by_size(word, font_size, position, orientation, font_path, random_state): # font_size 越大,颜色越深;这里用灰度做演示 gray = max(0, 180 - int(font_size * 2)) return "rgb(%d, %d, %d)" % (gray, gray, gray) wc.recolor(color_func=color_by_size) plt.imshow(wc, interpolation="bilinear") plt.axis("off") plt.show() wc.to_file("output/color_by_frequency.png")

这段代码用font_size反推灰度,字号越大灰度越低,颜色越深。max(0, 180 - int(font_size * 2))防止灰度变负;rgb(...)返回 matplotlib 能解析的字符串。参数上,font_size是 WordCloud 传进来的字号,不是词频,但字号通常跟权重正相关,拿来做分色够用。recolor要在generate之后调用,且color_func签名不能少参数。如果颜色函数返回None或格式不对,词会变黑或直接报错,这是常见翻车点。

4.4 输出与展示:to_file和plt.show各管一段

展示和保存分开写,答辩时少一类“图呢”的问题。plt.show()只在交互环境弹窗,wc.to_file()才是落盘。要控制输出分辨率,优先调width/height或scale,不要指望plt.savefig救场。

# output_control.py # 输出控制:高分辨率保存,展示用低分辨率预览 from wordcloud import WordCloud import matplotlib.pyplot as plt text = "python word cloud output resolution control" wc = WordCloud( width=1600, height=1000, scale=2, # 实际输出像素 = width*scale, height*scale background_color="white", max_words=150, ).generate(text) plt.imshow(wc, interpolation="bilinear") plt.axis("off") plt.show() wc.to_file("output/high_res.png") print(wc.width, wc.height) # 看实际画布尺寸

scale=2会把输出像素放大两倍,适合打印或放 PPT;width/height控制基础画布,max_words控制信息密度。print(wc.width, wc.height)能看到最终尺寸,避免“看着清楚、导出糊了”。参数上,scale太大会吃内存,1600×1000 再乘 2 已经够课程设计用;背景色用"white"比透明背景更稳,透明背景在 Word 里贴图容易变黑底,这是很多人答辩前才发现的坑。

5. 避坑与排查:字体、编码、蒙版和权重的四条高频翻车线

词云项目的错误表现很直观:方块字、整张图空白、形状不对、颜色全黑。每个现象背后通常只有一个原因,按“现象 → 原因 → 解决”排查,比盲目改参数快得多。下面四条是这套七个案例里最容易翻车的地方,每条都建议在交付前跑一遍。

5.1 中文全变方块:font_path没指对或字体不支持

现象:词云能生成,但所有中文都是方框,英文正常。

原因:WordCloud 默认字体不含中文字形,font_path没传、路径写错、字体文件损坏,都会回退到默认字体。路径里带中文或空格时,Windows 上还可能被截断。

解决:把字体文件放进fonts/,用相对路径或绝对路径都行,先确认文件存在。可以在代码里加一行import os; print(os.path.exists(font_path))。字体选择上,教程用Hiragino.ttf,你本机没有就换系统里有的中文字体文件,不要写一个不存在的文件名硬跑。

注意:字体文件不要用中文名,比如“微软雅黑.ttf”改成msyh.ttf,少一层编码问题。

5.2 中文词云像一锅粥:分词后没加空格

现象:中文能显示,但图上是一大段连续文字,或者词边界完全不对,词频统计没有意义。

原因:WordCloud 默认按空格和正则切词,jieba.cut(text)返回的是生成器,直接传给generate不会自动变成空格分隔字符串。案例 02 就是故意展示不分词的效果,不能拿它当生产代码。

解决:固定写text = " ".join(jieba.cut(text)),并在生成前print(text[:100])检查前 100 个字符。如果打印出来是“孙悟空师徒四人”,说明没空格;是“孙悟空 师徒 四人”,才说明分词结果被正确拼接。停用词过滤放在拼接之前,顺序别反。

5.3 蒙版形状不生效:背景不纯白或透明通道干扰

现象:明明给了蒙版,输出还是矩形,或者形状边缘被啃掉一块。

原因:WordCloud 把蒙版白色区域当背景,非白区域填词。蒙版背景是浅灰、渐变或透明 png 时,数组里没有纯白,形状判断就乱了。四通道 RGBA 图直接转数组,也可能让 WordCloud 读错通道。

解决:先用Image.open(...).convert("RGB")去掉 alpha,再按亮度阈值把浅色背景刷成纯白,参考 4.2 的prepare_mask.py。蒙版尺寸不要太大,先缩到 1000 像素宽以内试跑。形状区域用深色,背景用纯白,别用浅灰背景配深色形状,边缘会毛。

5.4 关键词权重不生效:字典格式或withWeight漏了

现象:案例 07 跑出来跟案例 03 差不多,或者直接报TypeError,说权重不是数字。

原因:jieba.analyse.extract_tags默认返回词列表,不加withWeight=True就没有权重;返回的是(词, 权重)元组列表,不转成{词: 权重}字典,generate_from_frequencies不认。

解决:固定写freq = jieba.analyse.extract_tags(text, topK=200, withWeight=True),然后freq = {i[0]: i[1] for i in freq}。生成时用generate_from_frequencies(freq),不要再用generate(text)。topK先 200,图太密就降到 100,图太空就升到 300,但权重会越来越平,重点词反而不突出。停用词要在提关键词之前过滤,否则“的”可能拿到高权重。

6. 验收与答辩:用三张图和一份参数表讲清方案

词云项目的验收不看“好不好看”这一句主观评价,而看能不能复现、能不能解释、能不能替换数据。我一般准备三张图:一张基础分词图、一张蒙版形状图、一张关键词权重图。三张图分别对应“文本预处理”“视觉控制”“文本挖掘”三个能力点,答辩时按这个顺序讲,老师或评审顺着听就知道你不是只跑了一个 demo。

6.1 验收清单与答辩讲法

验收时先跑一遍环境,再看输出文件是否齐全,最后用参数表解释每个图的差异。下面这张表可以直接当答辩提纲。

验收项检查内容通过标准
环境复现Python 3.7、wordcloud 1.9.3、matplotlib 3.5.3 能装最小冒烟脚本能出smoke.png
中文显示字体路径存在,中文无方块案例 03 图中中文可读
分词效果分词后字符串有空格,停用词已过滤前 100 字符打印可检查
蒙版形状蒙版纯白背景,输出非矩形案例 04 轮廓清晰
颜色控制ImageColorGenerator或color_func生效案例 05/06 颜色可解释
权重生成extract_tags带withWeight,字典格式正确案例 07 重点词明显大于普通词
输出文件output/下 png 齐全,命名清楚答辩时能快速定位

答辩讲法上,不要从“词云是什么”开始,直接从一张图切入:“这张图里‘孙悟空’最大,是因为它在分词后词频最高;这张蒙版图里词沿轮廓分布,是因为mask参数把白色背景排除了;这张关键词图里‘取经’变大,是因为extract_tags给了它更高的 TF-IDF 权重。”三句话分别对应数据、视觉、算法,评审再问也跑不出这个范围。

如果被问“为什么不用最新版本”,就答“教程验证组合是 1.9.3 + 3.5.3,课程设计优先复现稳定,不追新”;被问“蒙版为什么不用彩色图直接上”,就答“彩色图先转 RGB 并刷白背景,避免透明通道干扰形状判断”;被问“词云有什么局限”,就答“它展示频率和权重,不展示语法关系,所以适合做入口图,不适合替代完整文本分析”。这些回答都不需要临场编,提前写进备注即可。

从那以后我每次交词云方案,都强制先跑一遍最小案例,再固定字体路径和输出目录,最后才动蒙版和颜色。希望帮到你。

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进