大数据时代从繁乱冗杂中精准提取核心文本信息 × Python Tkinter 生成词云图

发布于:2023-02-02 ⋅ 阅读:(422) ⋅ 点赞:(0)

背景

人类在数字化浪潮中面临着怎样的抉择?如何把握数字时代的机遇和挑战?科技日新月异,人类生活日益便捷,你是愕然还是亢奋?机器人越来越人性化,你是恐惧焦虑还是心生欢喜?人类是否可以始终制霸选择权中的”最后一英里”?数据可以成为财富吗?大数据、算法、区块链、人工智能、物联网……

面对越来越繁杂的日常生活,每天人都要接受大量的文字信息。伴随着信息流,错综复杂,无休无止。如何准确且快速提取出事物的本质、物质的核心,从而领悟最终含义成了一个关键和问题。一天我灵机一动,于是运用所学知识编写了一款 Python 程序以实现了目标。

简介

这是一款生成词云图的程序。给定一段文章,经过该程序的智能运算,可以自动提取出该文章内的关键词,生成仅仅由文字和颜色组成的图片。图片里文字有大有小,在不同位置表示该词语出现的频率不同。字越大表明出现频率越高,那么也就越重要。 下面是使用该程序创建生成的词云图:
tree

特点

  • 界面简洁
  • 操作简便
  • 使用 Python Tkinter 原生编译而成,性能优良
  • 全过程个性化制定操作
  • 图片丰富多彩,内容充实

使用方法和步骤

程序界面

输入背景颜色

从上面的示例图片可以看出,整个词云图的背景为单一色彩,文字颜色却丰富多彩。你可以在输入框内以十六进制的格式写上你想要的颜色以生成制定颜色背景(详细信息见下文附录)。

选择是否使用遮罩图片

右侧是一个单选选项。遮罩图片的意思是:词云图将依照遮罩图片主体图形的形状大小和颜色来生成相应的文字。比如遮罩图片(除了白色背景)是一朵红色的花:
红花

那么最终图片上的文字颜色就是红色、黄色、绿色的(花瓣、花蕊、叶片上的颜色)。这是使用了《爱莲说》的赏析评价的文章生成的。
结果

禁用遮罩图片

这意味着文字将不会按照图片的形状来生成,也没有那上面的颜色,由程序根据背景颜色自动生成。背景黑则文字白,背景白则文字黑。

启用遮罩图片

定制性更强。图片上的主体是什么,这一串文字就沿着它边缘填满(如上图)。

  • 注意:遮罩图片背景必须是白色,不能是透明的!

读取词云图片

将需要处理的文本保存至 .txt 纯文本文件里。 然后点击按钮读取。

读取遮罩图片

如果禁用了遮罩图片,则不需要点击此按钮,直接点生成。启用才要。程序支持两种图片格式:.jpg 和 .png。再次重申,.png 图片不能为透明背景!

生成

直接点击生成按钮。处理时间较长,请耐心等待。处理完后,弹窗要求保存。找到目标文件夹后保存即可。

源码

import numpy
import math
import jieba
from wordcloud import WordCloud, STOPWORDS, ImageColorGenerator
import webbrowser
from tkinter import *
from tkinter import messagebox, filedialog
from PIL import Image, ImageTk
import tkinter.filedialog

string = ""
img_info = ""
img_color = ""
is_mask_on = False

def open_url_cnblogs(event):
    webbrowser.open("https://www.cnblogs.com/DawnNeon")

def open_url_csdn(event):
    webbrowser.open("https://blog.csdn.net/Dawn_Neon")

def about():
    wd_about = Toplevel()
    wd_about.resizable(False, False)
    wd_about.title("生成词云图")
    wd_about.geometry("450x270")
    Label(wd_about, width=100, font=("黑体", 40),
          text="生成词云图").pack(pady=10)
    Label(wd_about, font=("Times New Roman", 15),
          text="Copyright © 2020-2022 DawnNeon").pack()
    Label(wd_about, font=("Times New Roman", 15),
          text="Version Beta 0.2, Aug 18 2022").pack()
    Label(wd_about, font=("Times New Roman", 13),
          wraplength=450, text="From the bottom of my heart, \
I thank all those who gives me much help like the brightest stars \
even in the darkest time!").pack()
    lb_refrences1 = Label(wd_about,
                          text="帮助 & 支持: https://www.cnblogs.com/DawnNeon",
                          fg="blue",
                          cursor="star",
                          font=("微软雅黑", 9, "underline"))
    lb_refrences2 = Label(wd_about, text="https://blog.csdn.net/Dawn_Neon",
                          fg="blue",
                          cursor="star",
                          font=("微软雅黑", 9, "underline"))
    Label(wd_about, font=("宋体", 13), text="更新内容:\n1. 增加禁用遮罩图片时设定生成的词云图片尺寸", justify="center").pack()
    lb_refrences1.pack()
    lb_refrences2.pack()
    lb_refrences1.bind("<Button-1>", open_url_cnblogs)
    lb_refrences2.bind("<Button-1>", open_url_csdn)

def get_article_content():
    try:
        global string
        file_name = filedialog.askopenfilename(
            title="请选择一个 txt 文本文档",
            filetypes=(("文本文档", "*.txt"),))
        with open(file_name, "r", encoding="utf-8") as f:
            content = f.read()
            string = " ".join(jieba.lcut(content))
    except:
        messagebox.showerror("警告", "文件错误")
        return

def is_mask():
    try:
        dic = {0:False, 1:True}
        global is_mask_on
        is_mask_on = dic.get(var.get())
        if is_mask_on:
            en_width["state"] = "disabled"
            en_height["state"] = "disabled"
        else:
            en_width["state"] = "normal"
            en_height["state"] = "normal"
    except:
        messagebox.showerror("警告", "操作失败")

def get_image():
    try:
        if is_mask_on:
            img_name = filedialog.askopenfilename(
                    title="请选择一张遮罩图片",
                    filetypes=(("PNG图片,不透明", "*.png"), ("JPG图片", "*.jpg")))
            img = Image.open(img_name)
            global img_info, img_color
            img_info = numpy.array(img)
            img_color = ImageColorGenerator(img_info)
        else:
            messagebox.showinfo("提示", "无需读取遮罩图片!")
            return
    except:
        messagebox.showerror("警告", "读取遮罩图片出错!")
        return

def create_pic():
    try:
        with open("all_stopwords.txt", "r", encoding="utf-8") as f_all_sw:
            raw_sw = f_all_sw.readlines()
    except:
        messagebox.showerror("警告", "读取停用词时出错!")
        return
    sw = set()
    for i in raw_sw:
        sw.add(i.strip())

    bg_color = en_bg_color.get()
    messagebox.showinfo("提示", "图片生成过程中可能有卡顿或假死,请稍等片刻!\n点击确定开始生成")
    if is_mask_on:
        obj_pic = WordCloud(
                background_color=bg_color,
                repeat=True,
                max_words=500,
                stopwords=sw,
                font_path="msyh.ttc",
                color_func=img_color,
                mask=img_info)
    else:
        pic_width = int(en_width.get())
        pic_height = int(en_height.get())
        obj_pic = WordCloud(
            width=pic_width,
            height=pic_height,
            background_color=bg_color,
            repeat=True,
            max_words=500,
            stopwords=sw,
            font_path="msyh.ttc")
    obj_pic.generate(string)

    # 选择词云图保存路径
    try:
        result_path = filedialog.asksaveasfilename(
            title="请选择保存路径",
            filetypes=(("PNG图片", "*.png"),))
        result_name = result_path.split("/")
        obj_pic.to_file(result_path + ".png")
    except:
        messagebox.showerror("警告", "保存词云图时出错!")
        return
    messagebox.showinfo("提示", "词云图大功告成!")

root = Tk()
root.title("生成词云图")
fm_1 = Frame()
fm_2 = Frame()
fm_3 = Frame()
fm_4 = Frame()
fm_5 = Frame()
fm_1.pack(fill="both", expand=True)
fm_2.pack(fill="both", expand=True)
fm_3.pack(fill="both", expand=True)
fm_5.pack(fill="both", expand=True)

Label(fm_1, text="背景颜色", font=("微软雅黑", 14)).pack(
    fill="both",
    expand=True,
    side="left",
    padx=5,
    pady=5)
en_bg_color = Entry(fm_1, font=("微软雅黑", 14))
en_bg_color.pack(
    fill="both",
    expand=True,
    side="left",
    padx=5,
    pady=5)
var = IntVar()
Radiobutton(fm_1, text="禁用遮罩图片", variable=var, value=0, command=is_mask).pack(fill="both",
    expand=True,
    side="left",
    padx=5,
    pady=5)
Radiobutton(fm_1, text="启用遮罩图片", variable=var, value=1, command=is_mask).pack(fill="both",
    expand=True,
    side="left",
    padx=5,
    pady=5)

Label(fm_2, text="图片尺寸(长×宽)", font=("微软雅黑", 14)).pack(
    fill="both",
    expand=True,
    side="left",
    padx=5,
    pady=5)
en_width = Entry(fm_2, font=("微软雅黑", 14), width=5)
en_width.pack(
    fill="both",
    expand=True,
    side="left",
    padx=5,
    pady=5)
Label(fm_2, text="×", font=("微软雅黑", 14)).pack(
    fill="both",
    expand=True,
    side="left",
    padx=5,
    pady=5)
en_height = Entry(fm_2, font=("微软雅黑", 14), width=5)
en_height.pack(
    fill="both",
    expand=True,
    side="left",
    padx=5,
    pady=5)

Button(fm_3, text="读取词云文章", font=("微软雅黑", 16), command=get_article_content).pack(
    fill="both",
    expand=True,
    side="left",
    padx=5,
    pady=5)
Button(fm_3, text="读取遮罩图片", font=("微软雅黑", 16), command=get_image).pack(
    fill="both",
    expand=True,
    side="left",
    padx=5,
    pady=5)
Button(fm_5, text="生成", font=("微软雅黑", 18), command=create_pic).pack(
    fill="both",
    expand=True,
    side="left",
    padx=5,
    pady=5)
menubar = Menu(root)
menubar.add_command(label="关于", command=about)
root.config(menu=menubar)
root.mainloop()

附录:十六进制颜色码对照表

英文代码 颜色描述 十六进制
LightPink 浅粉红 #FFB6C1
Pink 粉红 #FFC0CB
Crimson 猩红 #DC143C
LavenderBlush 脸红的淡紫色 #FFF0F5
PaleVioletRed 苍白的紫罗兰红色 #DB7093
HotPink 热情的粉红 #FF69B4
DeepPink 深粉色 #FF1493
MediumVioletRed 适中的紫罗兰红色 #C71585
Orchid 兰花的紫色 #DA70D6
Thistle #D8BFD8
plum 李子 #DDA0DD
Violet 紫罗兰 #EE82EE
Magenta 洋红 #FF00FF
Fuchsia 灯笼海棠(紫红色) #FF00FF
DarkMagenta 深洋红色 #8B008B
Purple 紫色 #800080
MediumOrchid 适中的兰花紫 #BA55D3
DarkVoilet 深紫罗兰色 #9400D3
DarkOrchid 深兰花紫 #9932CC
Indigo 靛青 #4B0082
BlueViolet 深紫罗兰的蓝色 #8A2BE2
MediumPurple 适中的紫色 #9370DB
MediumSlateBlue 适中的板岩暗蓝灰色 #7B68EE
SlateBlue 板岩暗蓝灰色 #6A5ACD
DarkSlateBlue 深岩暗蓝灰色 #483D8B
Lavender 熏衣草花的淡紫色 #E6E6FA
GhostWhite 幽灵的白色 #F8F8FF
Blue 纯蓝 #0000FF
MediumBlue 适中的蓝色 #0000CD
MidnightBlue 午夜的蓝色 #191970
DarkBlue 深蓝色 #00008B
Navy 海军蓝 #000080
RoyalBlue 皇家蓝 #4169E1
CornflowerBlue 矢车菊的蓝色 #6495ED
LightSteelBlue 淡钢蓝 #B0C4DE
LightSlateGray 浅石板灰 #778899
SlateGray 石板灰 #708090
DoderBlue 道奇蓝 #1E90FF
AliceBlue 爱丽丝蓝 #F0F8FF
SteelBlue 钢蓝 #4682B4
LightSkyBlue 淡蓝色 #87CEFA
SkyBlue 天蓝色 #87CEEB
DeepSkyBlue 深天蓝 #00BFFF
LightBLue 淡蓝 #ADD8E6
PowDerBlue 火药蓝 #B0E0E6
CadetBlue 军校蓝 #5F9EA0
Azure 蔚蓝色 #F0FFFF
LightCyan 淡青色 #E1FFFF
PaleTurquoise 苍白的绿宝石 #AFEEEE
Cyan 青色 #00FFFF
Aqua 水绿色 #D4F2E7
DarkTurquoise 深绿宝石 #00CED1
DarkSlateGray 深石板灰 #2F4F4F
DarkCyan 深青色 #008B8B
Teal 水鸭色 #008080
MediumTurquoise 适中的绿宝石 #48D1CC
LightSeaGreen 浅海洋绿 #20B2AA
Turquoise 绿宝石 #40E0D0
Auqamarin 绿玉\碧绿色 #7FFFAA
MediumAquamarine 适中的碧绿色 #00FA9A
MediumSpringGreen 适中的春天的绿色 #00FF7F
MintCream 薄荷奶油 #F5FFFA
SpringGreen 春天的绿色 #3CB371
SeaGreen 海洋绿 #2E8B57
Honeydew 蜂蜜 #F0FFF0
LightGreen 淡绿色 #90EE90
PaleGreen 苍白的绿色 #98FB98
DarkSeaGreen 深海洋绿 #8FBC8F
LimeGreen 酸橙绿 #32CD32
Lime 酸橙色 #00FF00
ForestGreen 森林绿 #228B22
Green 纯绿 #008000
DarkGreen 深绿色 #006400
Chartreuse 查特酒绿 #7FFF00
LawnGreen 草坪绿 #7CFC00
GreenYellow 绿黄色 #ADFF2F
OliveDrab 橄榄土褐色 #556B2F
Beige 米色(浅褐色) #F5F5DC
LightGoldenrodYellow 浅秋麒麟黄 #FAFAD2
Ivory 象牙 #FFFFF0
LightYellow 浅黄色 #FFFFE0
Yellow 纯黄 #FFFF00
Olive 橄榄 #808000
DarkKhaki 深卡其布 #BDB76B
LemonChiffon 柠檬薄纱 #FFFACD
PaleGodenrod 灰秋麒麟 #EEE8AA
Khaki 卡其布 #F0E68C
Gold #FFD700
Cornislk 玉米色 #FFF8DC
GoldEnrod 秋麒麟 #DAA520
FloralWhite 花的白色 #FFFAF0
OldLace 老饰带 #FDF5E6
Wheat 小麦色 #F5DEB3
Moccasin 鹿皮鞋 #FFE4B5
Orange 橙色 #FFA500
PapayaWhip 番木瓜 #FFEFD5
BlanchedAlmond 漂白的杏仁 #FFEBCD
NavajoWhite 纳瓦霍白 #FFDEAD
AntiqueWhite 古代的白色 #FAEBD7
Tan 晒黑 #D2B48C
BrulyWood 结实的树 #DEB887
Bisque (浓汤)乳脂,番茄等 #FFE4C4
DarkOrange 深橙色 #FF8C00
Linen 亚麻布 #FAF0E6
Peru 秘鲁 #CD853F
PeachPuff 桃色 #FFDAB9
SandyBrown 沙棕色 #F4A460
Chocolate 巧克力 #D2691E
SaddleBrown 马鞍棕色 #8B4513
SeaShell 海贝壳 #FFF5EE
Sienna 黄土赭色 #A0522D
LightSalmon 浅鲜肉(鲑鱼)色 #FFA07A
Coral 珊瑚 #FF7F50
OrangeRed 橙红色 #FF4500
DarkSalmon 深鲜肉(鲑鱼)色 #E9967A
Tomato 番茄 #FF6347
MistyRose 薄雾玫瑰 #FFE4E1
Salmon 鲜肉(鲑鱼)色 #FA8072
Snow #FFFAFA
LightCoral 淡珊瑚色 #F08080
RosyBrown 玫瑰棕色 #BC8F8F
IndianRed 印度红 #CD5C5C
Red 纯红 #FF0000
Brown 棕色 #A52A2A
FireBrick 耐火砖 #B22222
DarkRed 深红色 #8B0000
Maroon 栗色 #800000
White 纯白 #FFFFFF
WhiteSmoke 白烟 #F5F5F5
Gainsboro 亮灰色 #DCDCDC
LightGrey 浅灰色 #D3D3D3
Silver 银白色 #C0C0C0
DarkGray 深灰色 #A9A9A9
Gray 灰色 #808080
DimGray 暗淡的灰色 #696969
Black 纯黑 #000000

参考链接 & 来源:十六进制颜色码

2022年8月18日更新 · Beta 0.2

  • 增加禁用遮罩图片时设定生成的词云图片尺寸。

    图片尺寸(长×宽)

    • 当选择禁用遮罩图片时,指定最后生成出来的的词云图片尺寸。有两个输入框。前者填长,后者填宽;
    • 当选择启用遮罩图片时,该输入框无效(呈灰色状,无法输入)。

写在最后

作者:DawnNeon
若要转载请标明出处:https://blog.csdn.net/Dawn_Neon/article/details/126126184


网站公告

今日签到

点亮在社区的每一天
去签到

热门文章