还在为专栏封面发愁?我用Python写了个词云生成器!

在这里插入图片描述
妈妈再也不用担心我写专栏找不到合适的封面了!B站专栏的封面至少是我一直头疼的问题,每次写完文章却找不到合适的图片作为封面。

词云是一个很不错的选择,既美观,又提纲挈领。网上也有词云生成的工具,但大多收费/只能试用,很多设置也不能调整。于是我最终决定自己动手丰衣足食。

网上有很多关于词云生成的Python代码,但大多结构松散,要调一项设置要在代码里上上下下各个库里进行修改,不方便使用。于是我想把我们常用的设置封装到一个函数里,这样方便我们日常使用。


总的思路是采用Jieba库对中文文章进行词语拆分,使用Matplotlib库进行底层绘图支持,使用WoldCloud库对分词后的文章进行词频统计并画出词云。

原本的WordCloud库是针对英语所开发的,在英文里每个单词都是由空格分开的,所以只需统计一篇文章中单词的频率并画图即可。中文的词语则需要通过Jieba库来进行识别并分词,并再将文中的词语之间插入空格,才算完成对数据的准备工作,可以使用WordCloud库生成词云。WordCloud库默认生成的是充满整个画图区域的词云,效果不够美观。

一般的解决方案是选择一张已有的图片作为mask遮罩,使WordCloud在图形区域进行画图。在本项目中,预设了常用形状的遮罩(圆形、椭圆、矩形、多边形),通过matplotlib.patches模块,进行遮罩的生成,免去了手动上传遮罩图片的麻烦。

代码采用了函数的方式,对每个功能部分进行了封装,便于调用,也便于代码的理解。分成了make_mask生成遮罩图片;jieba_split使用jieba分词并插入空格;以及最后的cloud_generate生成WordCloud对象并调用Matplotlib绘图。

最终只需要调用cloud_generate()函数并填写相应的参数即可:


cloud_generate()中的参数:

text_addr:需要生成词云的文本文档的地址
shape:词云的形状
'circle''c':圆形
'ellipse''e':椭圆
'rectangle''r':矩形
'square''s':正方形
整数n:正n边形
colormap:Matplotlib中的colormap数据对象,是颜色的组合


dpi:生成图片分辨率(默认为200)
output_addr:输出的图片的地址(默认为当前文件夹下wordcloud_output.png
stopwords:列表,停止词(即你不希望出现在图片里的词)

例:

cloud_generate(text_addr = '.\\blog.txt', shape = 'e', colormap = 'Set2', dpi = 400, stopwords = ['进行',  '我们'], output_addr = '.\\output.png')

即在当前目录下打开blog.txt作为要生成词云的文章,词云形状是椭圆,颜色组合是Set2,分辨率是400dpi,停止词是进行我们(因为这两个词在文中出现的频率较高,但对文章内容的提示性不大,所以选择不生成在词云里),最后输出的图片在当前文件夹下,文件名为output.png


最后,上代码~

import matplotlib.pyplot as plt
from wordcloud import WordCloud, ImageColorGenerator
from numpy import array
from jieba import cut
from PIL import Image
from matplotlib import patches
###
def make_mask (shape, dpi) :
    mask_fig = plt.figure(figsize=(6,6),facecolor='w',dpi=dpi)
    mask_ax = mask_fig.add_subplot(111)
    xy_center = (0.5,0.5)
    if (shape == 'circle' or shape == 'c'):
        mask_ax.add_patch(patches.Circle(xy_center, 0.5))
    elif (shape == 'ellipse' or shape == 'e'):
        mask_ax.add_patch(patches.Ellipse(xy_center, 1, 0.75))
    elif (shape == 'rectangle' or shape == 'r'):
        mask_ax.add_patch(patches.Rectangle((0,0.15), 1, 0.7))
    elif (shape == 'square' or shape == 's'):
        mask_ax.add_patch(patches.Rectangle((0,0), 1, 1))
    else :
        shape = int(shape)
        mask_ax.add_patch(patches.RegularPolygon(xy_center, shape, 0.5))
    mask_ax.axis('off')
    mask_fig.savefig('mask.png')
    mask = array(Image.open('mask.png'))
    plt.close()
    return mask
###
def jieba_split (text_addr):
    text = open(text_addr,encoding='utf-8').read()
    text_split = ' '.join(cut(text))
    return text_split
###
def cloud_generate (text_addr, shape = 'e', colormap = 
                    'Set2', dpi = 200, output_addr = 'wordcloud_output.png', 
                    stopwords = None):
    my_wordcloud = WordCloud(height=(6*dpi), width=(6*dpi), mask=make_mask(shape, dpi),
                             font_path='simhei.ttf', stopwords= stopwords,
                             background_color='white').generate(jieba_split(text_addr))
    cloud_fig = plt.figure(figsize=(6,6), dpi=dpi)
    cloud_ax = cloud_fig.add_subplot(111)
    cloud_ax.imshow(my_wordcloud.recolor(colormap = colormap))
    cloud_ax.axis('off')
    cloud_fig.savefig('output_addr')
    return
###
if __name__ == "__main__":
    cloud_generate(text_addr='.\\blog.txt', shape = 'e', colormap='Set2', dpi=400)

注:
1.本项目依赖Jieba库、wordcloud库、matplotlib库。
2.与程序文件同一文件夹下要有字体文件:simhei.ttf
3.由于采用了函数的封装,在同一目录下的py文件可以直接将WordCloudGenerate.py当做库来导入from WordCloudGenerate import cloud_generate,直接使用cloud_generate()函数,也可以将WordCloudGenerate.py添加到python的库中,从任意地方调用此库。


觉得有用的话,不要吝惜评论点赞分享哦,希望大家多多包涵,有任何问题欢迎指正、讨论。
本文基于CC-BY-SA 4.0协议,欢迎转载
(博客看累了?去我的B站瞧一瞧?)

发布了19 篇原创文章 · 获赞 212 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_27133869/article/details/104805215