美文网首页Python学习资料整理
使用wordcloud制作精美词云图

使用wordcloud制作精美词云图

作者: lifanxin | 来源:发表于2019-03-04 21:51 被阅读103次

使用wordcloud制作精美词云图

一个简单的开始

安装库

>>>pip3 install wordcloud
>>>pip3 install matplotlib

  wordcloud用来绘制词云图,是今天的主角。
  matplotlib是python中的2D绘图库,如果看官不熟悉可以先移步了解一下,或者也可以直接看我对使用到的函数的简单注释。

示例

@python 3.6.7

from os import path

import matplotlib.pyplot as plt
from wordcloud import WordCloud

CURRENT_PATH = path.dirname(path.abspath(__file__))


def show():
    # 读取本地test.txt文本,注意使用英文,中文后面会介绍
    file_path = path.join(CURRENT_PATH, 'test.txt')
    with open(file_path, 'r') as f:
        text = f.read()

    # 生成WordCloud对象,调用generate方法
    # windows下请选择要使用的字体路径
    # wordcloud = WordCloud(font_path='your_font_path').generate(text)
    wordcloud = WordCloud().generate(text)
    plt.imshow(wordcloud)  # 绘制传入的wordcloud
    plt.axis('off')  # 传入off,关闭坐标轴
    plt.show()  # 显示图片


if __name__ == '__main__':
    show()

  上面过程很好理解,唯一可能不熟悉的是两个新库的API。
  Wordcloud是一个类,有很多可以初始化的参数,这里全部采用默认的设置,然后调用generate方法。
  imshowshow的区别可以这样理解,imshow将图像绘制到内存,也就是说图像已经绘制了,只是在内存没有传到显示器,然后调用show呈现在显示器上。

test.txt内容

A Lion lay asleep in the forest, his great head resting on his paws. A timid little Mouse came upon him unexpectedly, and in her fright and haste to get away, ran across the Lion's nose.

效果展示

figure1.png

来,深入了解一下

generate的递进层次

  下面是wordcloud模块中generate的调用过程源码分析。


def generate(self, text):
    return self.generate_from_text(text)

  没错,generate方法就一行代码,调用generate_from_text方法然后返回。有种被欺骗的感觉,不过因为是面向对象的设计也情有可原,毕竟方法名变短了O(∩_∩)O哈哈~。


def generate_from_text(self, text):
    words = self.process_text(text)
    self.generate_from_frequencies(words)
    return self

  generate_from_text先调用了process_text对英文单词进行简单分词,返回的数据类型是字典,键是单词,值是频数。作者在这个函数里也说了有更好的方法来进行分词和标记,所以在process_text的实现上也就没有应有尽有。这也是为什么需要了解generate的层次,当你采用其它分词技术后,也就不需要也不应该重头调用generate
  所以generate_from_frequencies应当是你深入了解后常用的方法。generate_from_frequencies接受分词后包含有词汇频数的字典,然后经过一系列转化返回WordCloud对象,之后就能调用matplotlib.pyplot进行处理和显示了。
  当然generate_from_frequencies也被封装在fit_words方法下。不过如果直接调用generate_from_frequencies还有第二个参数max_font_size可选,它用来指定生成的词云图中字体的最大字号,默认为None


def fit_words(self, frequencies):
    return self.generate_from_frequencies(frequencies)

全方位认识WordCloud

  WordCloud含有众多的可选参数,认识这些参数可以帮助你更好的创建完美的wordcloud词云图。
  font_path=None
  要使用的字体(OTF或TTF)的字体路径。默认为None即使用Linux机器上的DroidSansMono路径。如果你在另一个操作系统或者没有此字体,您需要调整此路径。这也是为啥最开始windows用户需要自己动手找字体的原因了。

  width=400
  生成的图像宽度,默认400

  height=200
  生成的图像高度,默认200

  margin=2
  词汇之间间距,默认为2。

  ranks_only=None
  已经弃用,没有效果。

  prefer_horizontal=.9
  原文翻译为尝试水平拟合的次数与垂直拟合的次数之比。白话一点就是这个值小于1(默认为0.9),就会尝试旋转那些不适合水平方向的词汇为竖直方向;如果大于等于1的话就没有词汇竖直显示的效果,但即使设置为0也不会让所有词汇都竖直显示。

  mask=None
  当使用自己的图片来制作词云图的时候就需要这个参数,默认为None。这个参数是一个多维数组,需要使用其它库来将自己路径中的图像转化为数组。一旦使用mask后,之前设定的高和宽都将忽略而采用图像的形状。如果想要自己的词汇能够被明确的绘制成图片的图形形状,那么请采用白底图片。因为只有白色的背景(#FF or #FFFFFF)会被忽略,否则如果背景色彩不是纯白的话那么绘制出来的就是一个矩形。

nice

alice_color.png

bad 即使长得很帅也不行哦

pengyuyan.jpg

  scale=1
  计算和绘图之间的缩放,默认为1。也就是说如果你想要更大的词云图,使用这个进行调试比使用更大的图像作为mask更好,这样图形变大,字体会更清晰。不过可能会造成粗糙的词汇匹配。

  color_func=None
  生成颜色的函数,默认为None,使用自带的颜色生成函数。比如可以使用color_func=lambda *args, **kwargs: "white"来使字体变成白色。这个参数用法比较多,有兴趣的看官可以再深入研究。

  max_words=200
  使用词汇的最大数量,默认为200。

  min_font_size=4
  最小的字体号,默认为4,没有空间绘制这号字体时就停止。直白一点,不绘制比这还小的字。

  stopwords=None
  绘制时忽略的词汇,默认为None即使用内置的停用词汇表。如果直接使用generate_from_frequencies方法则会忽略这个参数。(stopwords只在process_text方法中被使用。)

  random_state=None
  用来生成随机对象,默认为None。这个参数主要是为color_func等一些颜色设置方法服务的。

  background_color='black'
  词云图的背景颜色,默认为black

  max_font_size=None
  最大的字体号,如果传入None即默认为图像的高度。

  font_step=1
  字体步长,默认为1。加大这个值会加快计算速度,但会造成粗糙的词汇匹配。

  mode="RGB"
  颜色模型,默认为RGB。如果传入RGBA并且设置background_color=None,那么生成的词云图背景将会变成透明。

  relative_scaling='auto'
  设置字体频率对字体大小的影响。设置为0,那么只考虑词汇顺序;设置为1,那么频率是两倍,大小就是两倍。默认为auto,即设置为0.5,次序和频率两者兼顾。但是如果repeat=True,那么就只会被设置为0。

  regexp=None
  正则匹配,只在process_text方法中被使用,默认为None则使用r"\w[\w']+"来进行正则匹配单词。直接使用generate_from_frequencies则会忽略这个参数。

  collocations=True
  是否包含两个单词的搭配(bigrams),默认为True。同样这个参数只在process_text中被使用。如果直接使用generate_from_frequencies则会忽略这个参数。

  colormap=None
  matplotlib颜色映射,为每个单词随机绘制颜色,默认为None即使用viridis。感兴趣的看官可以到网上搜索更多的colormap种类来挑选自己最喜爱的那一款。另外如果指定了color_func参数值,则会忽略这个参数。

  normalize_plurals=True
  是否从单词中删除尾随的“s”,默认为True。如果出现带有或不带有尾随“s”的单词,则将带有尾随“s”的删除并将其计数添加到没有尾随“s”的单词中——除非单词是以'ss'结尾。当然了这个参数也是只在process_text中使用,如果直接使用generate_from_frequencies则会忽略这个参数。

  contour_width=0
  默认为0,如果采用了mask,并且传递参数大于0,那么就会绘制图形轮廓,数值大小代表厚度。

  contour_color='black'
  绘制图形轮廓使用的颜色,默认为black

  repeat=False
  是否重复使用词汇,直到达到最大的词汇数量或者最小字体号没有空间不能被绘制为止,默认为False。

常用API认识,之前没介绍到的

  to_image(self)
  返回PIL.Image.Image对象。

  recolor(self, random_state=None, color_func=None, colormap=None)
  对图形重新着色。重新上色会比重新生成整个词云图快很多。有三个可选的参数random_state=None, color_func=None, colormap=None,和我们之前介绍的含义一样。它们默认值都是None,意味着会如果不传递参数便使用内部自己定义的初始值。

  to_file(self, filename)
  将生成的图像保存到指定路径,参数为文件路径加上文件名。

  to_array(self)
  内部会调用to_image(self),然后将得到的PIL.Image.Image对象转化为numpy array

动手制作自己的中文词云图

提前准备

再安装两个库

pip3 install jieba

  结巴是现在比较火的中文分词库,用法也比较简单。

pip3 install scipy

  虽然matplotlib.pyplot也有图像读取的API,但是在读取某些图像的时候会使用浮点数进行存储,此时wordcloud就会提示浮点数错误。所以我们在这里再安装另外一个图像读取库。

好,开始写代码

@python 3.6.7
# -*- coding: utf-8 -*-

from os import path

from wordcloud import WordCloud
import matplotlib.pyplot as plt
from scipy.misc import imread
import jieba.analyse

CURRENT_PATH = path.dirname(path.abspath(__file__))
TEXT_FILE = path.join(CURRENT_PATH, 'Chinese.txt')
IMG_FILE = path.join(CURRENT_PATH, 'jiqimao.jpg')
FONT_PATH = path.join(CURRENT_PATH, 'SourceHanSerifK-Light.otf')


def get_frequencies():
    # use jieba to get Chinese frequencies
    # 'topK' is the max words need to return
    # 'withWeight=True' means return frequencies
    with open(TEXT_FILE, 'r') as f:
        text = f.read()
    words = jieba.analyse.extract_tags(text, topK=200, withWeight=True)
    # words is list, change it to dict
    return dict(words)


def make_wordcloud(words):
    # get mask
    my_mask = imread(IMG_FILE)

    # set wordcloud
    my_wordcloud = WordCloud(
        font_path=FONT_PATH,
        background_color='white',
        mask=my_mask,
        max_font_size=68,
        min_font_size=8,
        contour_width=2,
        contour_color='steelblue'
    )
    # words must be dict
    my_wordcloud.generate_from_frequencies(words)

    return my_wordcloud


def show_it(wordcloud):
    # show it
    plt.imshow(wordcloud)
    plt.axis('off')
    plt.show()


def save_it(wordcloud, name):
    # save in current path
    filename = '{}.jpg'.format(name)
    wordcloud.to_file(path.join(CURRENT_PATH, filename))


if __name__ == '__main__':
    words = get_frequencies()
    wordcloud = make_wordcloud(words)
    show_it(wordcloud)
    save_it(wordcloud, 'my_wordcloud')

  整个流程比较直白,我们先将所有的准备文件都放在当前目录下。在get_frequencies函数中使用jieba进行分词,jieba.analyse.extract_tags会从指定文本中提取关键词,topK指定提取的词汇数量,withWeight=True会返回词汇的频数。注意这里最终返回的words是列表,需要使用dict将其转化为字典后才能传递给generate_from_frequencies使用。
  后面的步骤就比较常规了,make_wordcloud函数中使用imread读取图像,然后设置wordcloud参数,并绘制轮廓,最后调用generate_from_frequencies进行生成。
  接下来,show_it函数会展示成果,save_it函数则保存文件到指定位置。

效果展示

my_wordcloud.jpg

相关文章

网友评论

    本文标题:使用wordcloud制作精美词云图

    本文链接:https://www.haomeiwen.com/subject/qfvwuqtx.html