1. 程式人生 > 其它 >中/英詞雲製作(Python)

中/英詞雲製作(Python)

技術標籤:實踐python

中/英詞雲製作-Python

Author: zhww

Update time:2021.02.07

Description: 中英文詞雲製作主要步驟、個人理解與可執行程式。

小記:終於嘗試了我心念已久的詞雲製作,也紀念我這個寒假終於邁出了找學習狀態的第一步,做出下圖這個牛年祝福效果後,感覺成就感滿滿。在此,感謝提供了許多行之有效的參考內容的博主們,也感謝背景圖片的畫手大大,所有素材來源網路,如介意可聯絡刪除。最後,希望我這篇微不足道的小教程也能帶給各位一點啟發。

ps : 程式碼優美性上本人實在是小白,最後勉強封裝了一下,後續有時間會細化這個工具。

–收集祝福詞做出來的新年效果

(2021-02-07)新年效果

目錄

準備

python3.x版

安裝:

# pip install matplotlib # 繪圖
# pip install jieba # 中文文字分詞
# pip install wordcloud # 詞雲

映象安裝(應對time out 的報錯情況)

# pip install -i https://pypi.tuna.tsinghua.edu.cn/simple matplotlib # 繪圖
# pip install -i https://pypi.tuna.tsinghua.edu.cn/simple jieba # 中文分詞
# pip install wordcloud -i https://mirrors.aliyun.com/pypi/simple/ # 詞雲

參考:第三方庫映象安裝

原理

在生成詞雲時,wordcloud預設會以空格或標點為分隔符對目標文字進行分詞處理。

處理步驟:

  1. 文字分詞處理
    • 讀入txt文字資料
    • jieba分詞處理
    • 形成以空格分隔的字串
  2. 文字轉化為詞雲圖片
    • 建立WordCloud物件,設定引數(如背景圖、停用詞)
    • 產生詞雲
    • 輸出為圖片

英文詞雲

Demo Description: 無需新增字型,無需背景圖片

Code1:

import matplotlib.pyplot as plt
import jieba
from
os import path from PIL import Image import numpy as np from wordcloud import WordCloud # 1.讀入txt文字資料 text = open(r'test.txt', "r").read() #print(text) # 2.結巴中文分詞,生成字串,預設精確模式,如果不通過分詞,無法直接生成正確的中文詞雲 cut_text = jieba.cut(text) # print(type(cut_text)) # 必須給個符號分隔開分詞結果來形成字串,否則不能繪製詞雲 result = " ".join(cut_text) # print(result) # 3.生成詞雲圖,這裡需要注意的是WordCloud預設不支援中文,所以這裡需已下載好的中文字型檔 # 無自定義背景圖:需要指定生成詞雲圖的畫素大小,預設背景顏色為黑色,統一文字顏色:mode='RGBA'和colormap='pink' ###當前檔案路徑 d = path.dirname(__file__) wc = WordCloud( # 設定字型,不指定就會出現亂碼 # 設定背景色 background_color='white', # 設定背景寬 width=600, # 設定背景高 height=350, # 最大字型 max_font_size=50, # 最小字型 min_font_size=10, mode='RGBA', # colormap='pink' ) # 產生詞雲 wc.generate(result) # 儲存圖片 wc.to_file(r"wordcloud.png") # 按照設定的畫素寬高度儲存繪製好的詞雲圖,比下面程式顯示更清晰 # 4.顯示圖片 # 指定所繪圖名稱 plt.figure("jay") # 以圖片的形式顯示詞雲 plt.imshow(wc) # 關閉影象座標系 plt.axis("off") plt.show()

ResultSample(Ewordcloud01.png):
Ewordcloud01.png

測試記錄

Ewordcloud01.png——不加背景圖,設定橫縱大小以及字體範圍,不設停用詞;

Ewordcloud02.png——不加背景圖,設定橫縱大小以及字體範圍,不設停用詞,增加colormap='pink’選項;

Ewordcloud02.png——加背景圖,設定白色背景,官方停用詞;

中文詞雲

Demo Description:wordcloud預設字型是不支援中文,需要新增字型,Code2使用了背景圖片

Code2:

#!/usr/bin/Python
# -*- coding: utf-8 -*-
from os import path
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
import jieba
from wordcloud import WordCloud, STOPWORDS, ImageColorGenerator

# 建立停用詞列表
def stopwordslist():
    stopwords = [line.strip() for line in open('baidu_stopwords.txt', encoding='UTF-8').readlines()]
    return stopwords

###當前檔案路徑
d = path.dirname(__file__)

# Read the whole text.
file = open(path.join(d, 'alice.txt')).read()
##進行分詞
#剛開始是分完詞放進txt再開啟卻總是顯示不出中文很奇怪
default_mode =jieba.cut(file)
text = " ".join(default_mode)
alice_mask = np.array(Image.open(path.join(d, "avater.jpg")))
# stopwords = set(STOPWORDS)
# 建立一個停用詞列表
stopwords = set(stopwordslist())
wc = WordCloud(
    #設定字型,不指定就會出現亂碼,這個字型檔案需要下載
    font_path=r'E:\\study_code\\python\\wordcloud\\FZXBSJW.ttf',
    background_color = None,
    mode= 'RGBA',
    scale=2,
    max_words=2000,
    mask=alice_mask,
    stopwords=stopwords)
# generate word cloud
wc.generate(text)

# create coloring from image
image_colors = ImageColorGenerator(alice_mask)
# 通過這種方式詞雲將會按照給定的圖片顏色佈局生成字型顏色策略
plt.imshow(wc.recolor(color_func=image_colors), interpolation="bilinear")
plt.axis("off")
plt.figure()

# store to file
wc.to_file(path.join(d, "result.png"))

# show
plt.imshow(wc, interpolation='bilinear')
plt.axis("off")
plt.figure()
# gray  不影響執行, 顯示mask背景圖
plt.imshow(alice_mask, cmap=plt.cm.gray, interpolation='bilinear')
plt.axis("off")
plt.show()

ResultSample(CResult05.png):
CResult05.png
測試記錄

CResult01.png——官方停用詞(僅含英文),設定白底背景;

CResult02.png——官方停用詞(僅含英文),設定黑底背景;

CResult03.png——官方停用詞(僅含英文),設定透明色背景;

CResult04.png——百度停用詞(中英文),設定透明色背景;

CResult05.png——百度停用詞(中英文),設定透明色背景,按照給定的圖片顏色佈局生成字型顏色;

綜合

Description:按是否有背景圖簡要封裝為兩個函式,執行使用到的檔名稱在函式體第一部分集中修改,支援中文和英文詞彙。

  • wordcloudWithMask()
  • wordcloudWithoutMask()

初始載入import

from os import path
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
import jieba
from wordcloud import WordCloud, STOPWORDS, ImageColorGenerator

WordCloud 涉及詞雲詳細屬性設定;

STOPWORDS 不含中文停用詞;

ImageColorGenerator 實現按圖片顏色佈局字型顏色;

集中配置

 # 函式體內檔案配置部分
    # 當前檔案路徑
    d = path.dirname(__file__)
    # 集中配置,用到的檔案需要和此py檔案在同一目錄
    txtFile = 'test.txt'  # 文字, 支援中文或英文
    maskFile = "avater.jpg"  # 背景圖, 支援白底或透明背景
    fontFile = 'FZXBSJW.ttf'  # windows 'E:\\study_code\\python\\wordcloud\\FZXBSJW.ttf'
    wcFile = "result.png"  # 詞雲圖片名
    stopwordsFile = 'cn_stopwords.txt'  # = 'baidu_stopwords.txt'
    recolorTag = True  # 字型顏色是否與圖片顏色分佈一致

注意:配置的檔案都與程式在同一目錄下

檔案示例:

txtFile: test.txt

Neutral description of production resources’capabilities, interfaces, and other characteristics is required for efficient design or reconfiguration of production systems. In our previous work, we have developed a Resource Description and Capability concepts. An integral part of the Resource Description is an Executable Capability concept, which describes resource’s control interface in a vendor neutral form. In this paper, we show the underlying data model of Executable Capabilities, and how these capabilities can be utilised in the task programming and execution of modular production systems. Finally, a few case examples are shown…

maskFile: avater.jpg
在這裡插入圖片描述

fontFile

  • 如果詞全為英文,選擇性設定字型,可以註釋掉WordCloud引數裡的font_path=fontFile;

  • 如果詞為中文,必須要設定字型,字型選擇為系統記憶體在的,或者最好單獨下載字型放在同目錄下,注意字型檔案的字尾。

wcFile 自定義的詞雲輸出圖名稱及圖片型別,預設儲存在程式同目錄下。

stopwordsFile 停用詞表:

  1. 不設定停用詞,則可以註釋掉WordCloud引數裡的stopwords=stopwords;

  2. 使用wordcloud裡的停用詞表,stopwordsFile = “”;

  3. 使用自定義的停用詞表,如同目錄下百度停用詞表——“baidu_stopwords.txt”,中英文都有;

recolorTag

  • True —— 在有背景圖的前提下,支援文字顏色分佈與圖片一致,效果見中文詞雲ResultSample;
  • False —— 文字顏色按預設色系,見英文詞雲的ResultSample;

文字分詞

# 1. 文字分詞
    # Read the whole text.
    file = open(path.join(d, txtFile)).read()
    # 分詞
    default_mode = jieba.cut(file)
    text = " ".join(default_mode)
    alice_mask = np.array(Image.open(path.join(d, maskFile)))
    if stopwordsFile != None and len(stopwordsFile) > 0:
        # 建立一個停用詞列表
        stopwords = set([line.strip() for line in open(stopwordsFile, encoding='UTF-8').readlines()])
        # 單獨新增停用詞
        # stopwords.add("的")
    else:
        stopwords = set(STOPWORDS)

這部分完成了:

  1. 讀入文字、分詞、組合成字串 text
  2. 匯入背景圖得到畫素值矩陣 alice_mask
  3. 根據需要載入停用詞表 stopwords

生成詞雲圖片

# 2. 生成詞雲圖片,圖片的大部分引數通過WordCloud類來設定
    wc = WordCloud(
        # 設定字型,不指定就會出現中文亂碼,這個字型檔案需要下載,最好同路徑,否則需要寫全絕對路徑
        font_path=fontFile,
        background_color="white",
        mode='RGBA',
        mask=alice_mask,
        stopwords=stopwords)

WordCloud類引數作用可檢視wordcloud.py自行探索,常用的為

  • font_path —— 中文詞雲需設定字型,str型別,字型路徑;
  • background_color —— 輸出詞雲圖片的背景:“white”白底;“black”黑底;None透明色底;
  • mode —— 常用為’RGBA’;
  • mask —— 設定背景圖,必須為白底或透明色背景圖片,否則背景圖僅存在圖片區域大小限制的作用,淺色底可參考附錄轉化為透明底色的背景圖片;
  • stopwords —— 停用詞設定,去掉無意義的詞,如冠詞、介詞;

根據以空格分隔詞的字串text 生成詞雲

    # generate word cloud
    wc.generate(text)

字型顏色佈局並繪圖展示

    if recolorTag == True:
        # create coloring from image
        image_colors = ImageColorGenerator(alice_mask)
        # 通過這種方式詞雲將會按照給定的圖片顏色佈局生成字型顏色策略
        plt.imshow(wc.recolor(color_func=image_colors), interpolation="bilinear")
        plt.axis("off")
        plt.figure()
    else:
        # show
        plt.imshow(wc, interpolation='bilinear')
        plt.axis("off")
        plt.figure()
    # can't find gray的提示  不影響執行, 顯示背景圖
    plt.imshow(alice_mask, cmap=plt.cm.gray, interpolation='bilinear')
    plt.axis("off")
    plt.show()

plt.figure() —— 建立新畫布

plt.show() —— 顯示影象

輸出為圖片,儲存到本地

    # store to file
    wc.to_file(path.join(d, wcFile))

完整Code

#!/usr/bin/Python
# -*- coding: utf-8 -*-
from os import path
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
import jieba
from wordcloud import WordCloud, STOPWORDS, ImageColorGenerator

def wordcloudWithMask():
    """
    support the creation of English or Chinese WordCloud with mask
    """
    # 當前檔案路徑
    d = path.dirname(__file__)
    # 集中配置,用到的檔案需要和此py檔案在同一目錄
    txtFile = 'alice.txt'  # 文字, 支援中文或英文
    maskFile = "muImage.png"  # 背景圖
    fontFile = 'FZXBSJW.ttf'  # windows 'E:\\study_code\\python\\wordcloud\\FZXBSJW.ttf'
    wcFile = "result.png"  # 詞雲圖片名
    stopwordsFile = 'cn_stopwords.txt'  # = 'baidu_stopwords.txt'
    recolorTag = True  # 字型顏色是否與圖片顏色分佈一致

    # 1. 文字分詞
    # Read the whole text.
    file = open(path.join(d, txtFile)).read()
    # 分詞
    default_mode = jieba.cut(file)
    text = " ".join(default_mode)
    alice_mask = np.array(Image.open(path.join(d, maskFile)))
    if stopwordsFile != None and len(stopwordsFile) > 0:
        # 建立一個停用詞列表
        stopwords = set([line.strip() for line in open(stopwordsFile, encoding='UTF-8').readlines()])
        # 單獨新增停用詞
        # stopwords.add("的")
    else:
        stopwords = set(STOPWORDS)

    # 2. 生成詞雲圖片,圖片的大部分引數通過WordCloud類來設定
    wc = WordCloud(
        # 設定字型,不指定就會出現亂碼,這個字型檔案需要下載,最好同路徑,否則需要寫全絕對路徑
        font_path=fontFile,
        background_color="white",
        mode='RGBA',
        scale=2,
        max_words=2000,
        mask=alice_mask,
        # random_state = 42,
        stopwords=stopwords)
    # generate word cloud
    wc.generate(text)

    if recolorTag == True:
        # create coloring from image
        image_colors = ImageColorGenerator(alice_mask)
        # 通過這種方式詞雲將會按照給定的圖片顏色佈局生成字型顏色策略
        plt.imshow(wc.recolor(color_func=image_colors), interpolation="bilinear")
        plt.axis("off")
        plt.figure()
    else:
        # show
        plt.imshow(wc, interpolation='bilinear')
        plt.axis("off")
        plt.figure()

    # store to file
    wc.to_file(path.join(d, wcFile))

    # can't find gray的提示  不影響執行, 顯示背景圖
    plt.imshow(alice_mask, cmap=plt.cm.gray, interpolation='bilinear')
    plt.axis("off")
    plt.show()

def wordcloudWithoutMask():
    """
    support the creation of English or Chinese WordCloud without mask
    :return:
    """
    # 當前檔案路徑
    d = path.dirname(__file__)
    # 集中配置,用到的檔案需要和此py檔案在同一目錄
    txtFile = 'test.txt'  # 文字, 支援中文或英文
    fontFile = 'simsun.ttf'  # windows 絕對路徑如'E:\\study_code\\python\\wordcloud\\FZXBSJW.ttf'
    wcFile = "wordcloud.png"  # 詞雲圖片名
    stopwordsFile = ""  # = 'baidu_stopwords.txt'

    # 1. 文字分詞
    # Read the whole text.
    file = open(path.join(d, txtFile)).read()
    # 分詞
    default_mode = jieba.cut(file)
    text = " ".join(default_mode)
    if stopwordsFile != None and len(stopwordsFile) > 0:
        # 建立一個停用詞列表
        stopwords = set([line.strip() for line in open(stopwordsFile, encoding='UTF-8').readlines()])
        # 單獨新增停用詞
        # stopwords.add("的")
    else:
        stopwords = set(STOPWORDS)


    # 2. 生成詞雲圖片,圖片的大部分引數通過WordCloud類來設定
    wc = WordCloud(
        # 設定字型,不指定就會出現亂碼,這個字型檔案需要下載,最好同路徑,否則需要寫全絕對路徑
        font_path=fontFile,
        # 設定背景色
        background_color='white',
        # 設定背景寬
        width=500,
        # 設定背景高
        height=350,
        # 最大字型
        max_font_size=50,
        # 最小字型
        min_font_size=10,
        # colormap='pink'
        mode='RGBA',
        stopwords=stopwords)
    # generate word cloud
    wc.generate(text)

    # store to file
    wc.to_file(path.join(d, wcFile))
    # 指定所繪圖名稱
    plt.figure("jay")
    # 以圖片的形式顯示詞雲
    plt.imshow(wc)
    # 關閉影象座標系
    plt.axis("off")
    plt.show()
    
# 帶背景圖的詞雲生成
wordcloudWithMask()
# 不帶背景圖的詞雲生成
wordcloudWithoutMask()

參考

【1】3分鐘教你用python製作一個簡單詞雲

【2】Python實現中文詞雲

【3】Windows環境下Python中wordcloud的使用——自己踩過的坑 2017.08.08

【4】Python詞雲 wordcloud 十五分鐘入門與進階

【5】Python將圖片背景透明化

附錄

淺色底圖片背景透明化,主要嘗試了白底以及淺灰色的背景的彩色圖片,重製後圖片保留了大部分彩色區域。

#!/usr/bin/Python
# -*- coding: utf-8 -*-
import os
import numpy
from PIL import Image

def transparent_background(path):
    try:
        img = Image.open(path)
        img = img.convert("RGBA")  # 轉換獲取資訊
        pixdata = img.load()
        color_no = get_convert_middle(path) + 30  # 摳圖的容錯值

        for y in range(img.size[1]):
            for x in range(img.size[0]):
                if pixdata[x, y][0] > color_no and pixdata[x, y][1] > color_no and pixdata[x, y][2] > color_no and \
                        pixdata[x, y][3] > color_no:
                    pixdata[x, y] = (255, 255, 255, 0)

        if not path.endswith('png'):
            os.remove(path)
            replace_path_list = path.split('.')
            replace_path_list = replace_path_list[:-1]
            path = '.'.join(replace_path_list) + '.png'

        img.save(path)
        img.close()
        print("Successful changed to transparent background.")
    except Exception as e:
        print("Error")
        return path

def get_convert_middle(img_path):
    I = Image.open(img_path)
    L = I.convert('L')
    im = numpy.array(L)
    im4 = 255.0 * (im / 255.0) ** 2  # 對影象的畫素值求平方後得到的影象
    middle = (int(im4.min()) + int(im4.max())) / 2
    return middle

# 呼叫 transparent_background, 傳入圖片路徑, 該方法把圖片修改後替換了原始檔
transparent_background('muImage.png')