简介这份PDF教程面向对文本挖掘与数据可视化感兴趣的Python初学者和中级用户系统讲解如何用Python生成个性化词云解决从文本预处理到图像输出的完整流程问题。内容围绕wordcloud与matplotlib两大核心库展开涵盖词云的定义、作用、生成原理及环境配置并给出7个由浅入深的案例从最简调用、中文不分词、中文分词到蒙版形状、自定义颜色、关键词与权重提取等进阶技巧每个案例均配有代码示例与运行结果。资源包为单一PDF文件共1个文件大小约2.07MB便于携带与离线查阅。目前已有108人学习适合希望在项目报告、数据分析、社交媒体监控或教育场景中快速应用词云技术的读者可帮助其掌握文本预处理、权重计算、词云生成与保存的完整方法并理解词云在信息压缩与关键词展示上的实际价值。1. 从一份 PDF 说起7 个案例把词云从玩具变成生产力工具很多人第一次接触词云是在某个汇报 PPT 里看到一坨花花绿绿的字觉得好看但没什么用。我一开始也这么想直到有一次需要从几百份用户反馈里快速定位高频抱怨点手动读了两小时眼睛发酸才意识到词云真正的价值不是好看而是把文本里藏着的权重结构一眼摊开。这份《python实现词云完整教程7个案例.pdf》就是围绕这个需求展开的它不讲虚的直接用 7 个递进案例把 wordcloud 和 matplotlib 这两个库的用法串了一遍。从最简调用到中文分词、蒙版形状、蒙版颜色、自定义颜色函数、关键词权重提取基本覆盖了日常做文本可视化会遇到的主要场景。适合已经会写 Python、但没系统用过词云库的人也适合做数据分析、运营报告、舆情监控的从业者拿来当参考手册。下面我按自己的理解把这 7 个案例拆开补上原文没展开的参数细节和踩坑点。2. 环境准备与最简调用先把第一张图跑出来2.1 版本锁定与依赖安装原文给的环境是 Python 3.7 wordcloud 1.9.3 matplotlib 3.5.3编辑器用的 PyCharm。这个组合比较稳但如果你本地是 Python 3.9 以上wordcloud 建议至少升到 1.9.2 以后否则在 Windows 上编译 C 扩展容易报错。安装命令不复杂但要注意 wordcloud 依赖 Pillow 和 numpypip 会自动拉如果网络慢就换国内源。# 建议先建虚拟环境避免和系统包冲突 python -m venv venv source venv/bin/activate # Windows 用 venv\Scripts\activate # 安装核心库指定版本避免兼容问题 pip install wordcloud1.9.3 matplotlib3.5.3 jieba pillow numpy这里 jieba 是后面中文分词要用的原文案例 03 才开始引入但我建议一开始就装上省得来回折腾。numpy 和 Pillow 是 wordcloud 的底层依赖蒙版案例里要直接用 numpy 读图片数组所以必须显式确认它们存在。2.2 案例 01 的最简调用与参数拆解案例 01 的代码只有十几行但它是理解整个 wordcloud 工作流的起点。原文代码是这样的# -*- coding: utf-8 -*- from wordcloud import WordCloud import matplotlib.pyplot as plt # 打开文本 text open(constitution.txt).read() # 生成对象 wc WordCloud().generate(text) # 显示词云 plt.imshow(wc, interpolationbilinear) plt.axis(off) plt.show() # 保存到文件 wc.to_file(wordcloud.png)逻辑很直白读文本、建 WordCloud 对象、调 generate 生成、用 matplotlib 显示、最后存文件。但有几个点原文没展开。第一WordCloud()不传参数时默认宽度 400 高度 200背景白色字体是系统默认的 DroidSansMono这个字体对中文完全不支持所以案例 01 只能用英文文本。第二generate(text)内部做的是分词加词频统计英文按空格切标点会被简单处理但不会自动去停用词所以你会看到 the、and 这种词占很大面积。第三plt.imshow(wc, interpolationbilinear)里的 interpolation 控制显示插值方式bilinear 会让边缘柔和一些但对最终保存的图片没影响保存走的是to_file。如果你跑出来报OSError: cannot open resource八成是字体问题但案例 01 用英文文本一般不会触发。真正要留意的是constitution.txt的编码Windows 下如果文件是 GBKopen()不加 encoding 会乱码建议统一写成open(constitution.txt, encodingutf-8)。2.3 从最简调用能看出什么边界这个案例最大的意义是让你确认环境通了。但它也暴露了 wordcloud 的几个默认行为不处理中文、不去停用词、尺寸偏小、背景不透明。后面六个案例基本都是在补这些短板。我一般会在这个阶段就把width800, height600, background_colorwhite加上省得后面反复改。另外wc.to_file()支持的格式由扩展名决定png 最稳jpg 会有压缩损失svg 需要额外依赖不建议新手碰。3. 中文词云的两条路不分词与 jieba 分词3.1 案例 02 中文不分词的真相案例 02 标题叫“中文不分词”代码里直接读了《西游记》的 txt然后传给 WordCloud 生成。原文代码# -*- coding: utf-8 -*- from wordcloud import WordCloud import matplotlib.pyplot as plt with open(../xyj.txt, r, encodingutf-8) as f: text f.read() wc WordCloud(font_path../Hiragino.ttf, width800, height600, modeRGBA, background_colorNone).generate(text) plt.imshow(wc, interpolationbilinear) plt.axis(off) plt.show() wc.to_file(main_2.png)这里关键变化是加了font_path指向一个支持中文的 ttf否则中文全是方块。modeRGBA和background_colorNone配合使用生成透明背景的 PNG方便叠到其他图上。但“不分词”的意思是wordcloud 默认按空格切词中文句子没有空格所以它会把整段话当成一个“词”或者按字符切结果就是词云里出现大段连续文本或者单字可读性很差。这个案例的价值是让你看到不分词的效果有多离谱从而理解为什么需要 jieba。注意font_path的路径是相对代码运行目录的PyCharm 里默认工作目录是项目根如果你把字体放在别处最好用绝对路径否则换台机器就翻车。3.2 案例 03 jieba 分词与三种模式案例 03 引入 jieba核心就一行text .join(jieba.cut(text))。jieba.cut 默认是精确模式试图把句子最精确地切开适合文本分析。另外两种模式全模式会把所有可能成词的都扫出来速度快但歧义多搜索引擎模式在精确模式基础上对长词再切适合做索引。做词云一般用精确模式就够了如果你发现某些专有名词被切碎可以加载自定义词典。# -*- coding: utf-8 -*- from wordcloud import WordCloud import matplotlib.pyplot as plt import jieba with open(../xyj.txt, r, encodingutf-8) as f: text f.read() # 中文分词精确模式 text .join(jieba.cut(text)) print(text[:100]) # 打印前100字符检查分词效果 wc WordCloud(font_path../Hiragino.ttf, width800, height600, modeRGBA, background_colorNone).generate(text) plt.imshow(wc, interpolationbilinear) plt.axis(off) plt.show() wc.to_file(wordcloud.png) .join()的作用是把 jieba 返回的生成器用空格拼成字符串因为 wordcloud 只认空格分隔的词。打印前 100 字符是个好习惯能快速判断分词有没有把“孙悟空”切成“孙悟”和“空”。如果切错了用jieba.load_userdict(userdict.txt)加载自定义词典每行一个词格式是“词语 词频 词性”词频可省略。3.3 停用词与词频调整的实操原文没提停用词但实际做中文词云不去停用词你会看到“的”“了”“是”占满屏幕。wordcloud 的stopwords参数接受一个集合jieba 也有自己的停用词表。我一般会合并两份一份通用中文停用词一份针对当前文本的比如《西游记》里的“行者”“唐僧”如果做整体分析可以保留但如果只想看妖怪名字就得去掉。# 自定义停用词 stopwords set([的, 了, 是, 在, 和, 与, 就, 都, 而, 及]) wc WordCloud(font_path../Hiragino.ttf, width800, height600, stopwordsstopwords, max_words200, modeRGBA, background_colorNone).generate(text)max_words控制显示多少个词默认 200词太多会挤成一团。collocationsFalse可以关闭二元词组搭配避免出现“孙悟空 行者”这种组合做中文词云建议关掉否则高频词会重复出现。4. 蒙版与颜色让词云贴合形状和配色4.1 案例 04 蒙版形状的原理与图片要求蒙版mask的本质是一张黑白图片wordcloud 会读取它的像素矩阵只在非白色区域绘制词。原文用np.array(Image.open(../black_mask.png))把图片转成 numpy 数组传给mask参数。这里有个硬性要求蒙版必须是白底黑图或者至少背景是纯白RGB 255,255,255因为 wordcloud 判断的是像素值白色区域会被跳过。如果你的蒙版是透明背景读进来 alpha 通道可能干扰建议先用 PIL 转成 RGB 再转数组。# -*- coding: utf-8 -*- from wordcloud import WordCloud from PIL import Image import numpy as np import matplotlib.pyplot as plt import jieba with open(../xyj.txt, r, encodingutf-8) as f: text f.read() text .join(jieba.cut(text)) # 读取蒙版确保是 RGB 模式 mask np.array(Image.open(../black_mask.png).convert(RGB)) wc WordCloud(maskmask, font_path../Hiragino.ttf, modeRGBA, background_colorNone).generate(text) plt.imshow(wc, interpolationbilinear) plt.axis(off) plt.show() wc.to_file(main_4.png)convert(RGB)这步很关键原文没写但如果你拿到的蒙版是 PNG 带透明通道不转直接读会得到四通道数组wordcloud 可能报错或者形状错乱。另外蒙版尺寸决定输出图片尺寸所以别用太小的图否则词挤不下。4.2 案例 05 蒙版颜色与 ImageColorGenerator案例 05 在蒙版基础上加了颜色提取。ImageColorGenerator(mask)会分析蒙版图片的颜色分布然后按词的位置从对应区域取色。原文代码from wordcloud import WordCloud, ImageColorGenerator from PIL import Image import numpy as np import matplotlib.pyplot as plt import jieba with open(../xyj.txt, r, encodingutf-8) as f: text f.read() text .join(jieba.cut(text)) mask np.array(Image.open(../color_mask.png).convert(RGB)) wc WordCloud(maskmask, font_path../Hiragino.ttf, modeRGBA, background_colorNone).generate(text) # 从图片中生成颜色 image_colors ImageColorGenerator(mask) wc.recolor(color_funcimage_colors) plt.imshow(wc, interpolationbilinear) plt.axis(off) plt.show() wc.to_file(main_5.png)recolor必须在generate之后调用顺序反了不生效。ImageColorGenerator取的是蒙版对应位置的颜色均值所以如果你的蒙版是彩色渐变词云颜色也会跟着渐变。但有个坑如果蒙版颜色太杂词的颜色可能和背景对比度不够读起来费劲。我一般会先把蒙版调成高饱和度、低细节的图效果更稳。4.3 案例 06 自定义颜色函数的写法案例 06 完全自定义颜色用color_func传一个函数函数返回 HSL 或 RGB 字符串。原文的 random_color 函数import random def random_color(word, font_size, position, orientation, font_path, random_state): s hsl(0, %d%%, %d%%) % (random.randint(60, 80), random.randint(60, 80)) print(s) return s wc WordCloud(color_funcrandom_color, maskmask, font_path../Hiragino.ttf, modeRGBA, background_colorNone).generate(text)这个函数接收 6 个参数但实际你只用得到 word 和 font_size。hsl(0, 60%, 70%)表示色相 0红色饱和度 60%亮度 70%。原文固定色相为 0只随机饱和度和亮度所以出来的全是红色系。如果你想按词频调色可以用 font_size 做判断高频词用深色低频词用浅色。注意print(s)在词多的时候会刷屏正式跑的时候删掉。提示color_func 的返回值必须是 matplotlib 能识别的颜色格式hsl 字符串在部分版本上兼容性一般稳妥点用rgb(r,g,b)或十六进制#RRGGBB。5. 关键词权重与 generate_from_frequencies 的用法5.1 案例 07 提取关键词和权重的逻辑案例 07 是整份教程里最实用的一节它不再用整段文本让 wordcloud 自己统计词频而是先用 jieba.analyse.extract_tags 提取关键词和权重再用generate_from_frequencies生成词云。这样做的好处是你可以控制词表也能接入 TF-IDF 之外的其他权重算法。# -*- coding: utf-8 -*- from wordcloud import WordCloud, ImageColorGenerator from PIL import Image import numpy as np import matplotlib.pyplot as plt import jieba.analyse with open(../xyj.txt, r, encodingutf-8) as f: text f.read() # 提取关键词和权重topK 控制数量 freq jieba.analyse.extract_tags(text, topK200, withWeightTrue) print(freq[:20]) freq {i[0]: i[1] for i in freq} mask np.array(Image.open(../color_mask.png).convert(RGB)) wc WordCloud(maskmask, font_path../Hiragino.ttf, modeRGBA, background_colorNone).generate_from_frequencies(freq) image_colors ImageColorGenerator(mask) wc.recolor(color_funcimage_colors) plt.imshow(wc, interpolationbilinear) plt.axis(off) plt.show() wc.to_file(main_07.png)extract_tags默认用 TF-IDFtopK200表示取前 200 个词withWeightTrue返回权重值。返回的是列表每个元素是(词, 权重)转成字典后传给generate_from_frequencies。这里有个细节generate_from_frequencies不会再去重或分词它完全按你给的字典来所以字典的 key 必须是字符串value 是数值不能有重复 key。5.2 权重归一化与字体大小映射generate_from_frequencies内部会把权重映射到字体大小默认最大字号由max_font_size控制不设的话根据画布高度自动算。如果你发现所有词大小差不多可能是权重差异太小可以手动做归一化# 权重归一化到 0-1 之间 max_w max(freq.values()) min_w min(freq.values()) freq_norm {k: (v - min_w) / (max_w - min_w) for k, v in freq.items()}但要注意归一化后最小权重变成 0wordcloud 可能会跳过这些词。更稳妥的做法是保留原始权重只调max_font_size和min_font_size。我一般设max_font_size120, min_font_size10这样高频词够突出低频词也能看清。5.3 和直接 generate 的差异对比直接generate(text)是 wordcloud 自己分词加统计适合快速看整体generate_from_frequencies是你完全掌控词表和权重适合做精确分析。两者在性能上也有差别文本量大时jieba 分词加 TF-IDF 计算可能比 wordcloud 内置统计慢但结果更可控。如果你要做情感分析后的词云比如只保留正面情感词就必须走generate_from_frequencies因为 wordcloud 本身不做情感过滤。6. 避坑与排查7 个案例跑下来最容易翻车的 5 个点6.1 中文显示方块或乱码现象词云里中文全是方框或者直接报OSError: cannot open resource。原因font_path没设或者设的字体不支持中文或者路径写错。解决找一个支持中文的 ttf比如思源黑体、文泉驿微米黑用绝对路径传给font_path。Windows 下可以用C:/Windows/Fonts/msyh.ttcMac 下用/System/Library/Fonts/PingFang.ttc。注意 ttc 是字体集合wordcloud 部分版本读 ttc 会报错优先用 ttf。6.2 蒙版不生效或形状错乱现象传了 mask 但词云还是矩形或者形状和蒙版对不上。原因蒙版不是白底黑图或者图片模式不对或者蒙版尺寸和width/height冲突。解决用 PIL 打开蒙版convert(RGB)后转 numpy 数组确认背景是纯白。如果蒙版本身有灰色过渡wordcloud 会把灰色区域也当有效区域导致形状模糊。另外设了 mask 后width和height参数会被忽略输出尺寸由蒙版决定。6.3 停用词没起作用现象词云里“的”“了”“是”还是很大。原因stopwords参数只对generate生效如果你用generate_from_frequencies停用词要在提取关键词之前就过滤掉。解决在 jieba 分词后、统计词频前手动过滤停用词或者用jieba.analyse.set_stop_words(stopwords.txt)设置停用词表再调extract_tags。6.4 保存的图片背景不透明现象background_colorNone设了但保存的 PNG 还是有白底。原因modeRGBA没设或者 matplotlib 显示时背景色干扰。解决确保WordCloud(modeRGBA, background_colorNone)两个参数同时存在保存用to_file(xxx.png)不要用plt.savefig后者会带上 matplotlib 的画布背景。如果还不行检查蒙版图片本身是不是带 alpha 通道。6.5 词云重复词或词组搭配现象同一个词出现两次或者出现“孙悟空 行者”这种组合。原因collocations默认 Truewordcloud 会自动检测二元词组另外generate_from_frequencies如果字典有重复 key 会覆盖。解决设collocationsFalse关闭词组搭配用字典推导式去重确保 key 唯一。如果还是重复检查 jieba 分词结果里有没有同义词没合并。7. 进阶技巧把词云接进自动化报告流水线跑通 7 个案例之后你手里其实已经有了一套可复用的代码模板。我后来把案例 07 改成了一个函数输入文本路径和蒙版路径输出词云图片和关键词列表直接塞进数据分析脚本里。具体做法是先用 jieba 分词加停用词过滤再用extract_tags拿权重然后generate_from_frequencies生成最后用ImageColorGenerator上色。整个流程封装成make_wordcloud(text, mask_path, font_path, output_path)参数全部可配。def make_wordcloud(text, mask_path, font_path, output_path, topK200): import jieba.analyse from wordcloud import WordCloud, ImageColorGenerator from PIL import Image import numpy as np # 提取关键词和权重 freq jieba.analyse.extract_tags(text, topKtopK, withWeightTrue) freq_dict {i[0]: i[1] for i in freq} # 读取蒙版 mask np.array(Image.open(mask_path).convert(RGB)) # 生成词云 wc WordCloud(maskmask, font_pathfont_path, modeRGBA, background_colorNone, max_font_size120, min_font_size10, collocationsFalse) wc.generate_from_frequencies(freq_dict) # 上色 image_colors ImageColorGenerator(mask) wc.recolor(color_funcimage_colors) # 保存 wc.to_file(output_path) return freq_dict这个函数可以直接放进定时任务每天跑一次舆情数据输出词云到指定目录。验证方法也简单拿一份已知关键词的文本跑一遍看输出的词云里这些词是不是够大。如果不够大调topK或者检查 TF-IDF 权重是否被长文本稀释。我一般还会把freq_dict存成 JSON方便后续做趋势对比。从那以后我每次做文本分析都会先跑一遍词云看整体分布再决定要不要深入。这个习惯帮我省了不少瞎读文本的时间。希望帮到你。本文还有配套的精品资源点击获取