Python词云生成工具3:定制更多参数

news2024/11/26 0:31:54

文章目录

    • 添加整型参数
    • 布尔型参数
    • 背景颜色
    • 词云生成逻辑
    • 源代码

  • Python打造一个词云软件
  • 显示分词结果

添加整型参数

我们所有的设置都放在了wcDct中,所以若想用更多的参数来定制词云,那么只需在wcDct中添加内容,例如下面这些整型参数

其次,WordCloud中有很多参数的数据类型都是整型,这些适用于Spinbox

参数说明合适的范围步长
width词云宽度100-200010
height词云高度100-200010
min_font_size最小文字尺寸1-501
max_font_size最大文字尺寸10-100010
font_step字体步长1-201
max_words最大单词数10-50010
min_word_length最短单词长度0-101
scale图像缩放默认是1

下面就是要向wcDct中添加的内容。

wcDct = {
    "最小文字" : {
        "ctrl": ttk.Spinbox, 
        "paras" : {"width":10, "from_":1, "to":50, "increment":1},
        "default":4,
        "call" : "min_font_size"},
    "最大文字" : {
        "ctrl": ttk.Spinbox, 
        "paras" : {"width":10, "from_":10, "to":1e3, "increment":10},
        "default":400,
        "call" : "max_font_size"},
    "字体步长" : {
        "ctrl": ttk.Spinbox, 
        "paras" : {"width":10, "from_":1, "to":20, "increment":1},
        "default":10,
        "call" : "font_step"},
    "最短词长" : {
        "ctrl": ttk.Spinbox, 
        "paras" : {"width":10, "from_":0, "to":10, "increment":1},
        "default":1,
        "call" : "min_word_length"},
    "最多词数" : {
        "ctrl": ttk.Spinbox, 
        "paras" : {"width":10, "from_":10, "to":500, "increment":10},
        "default":200,
        "call" : "max_words"},
    "图像缩放" : {
        "ctrl": ttk.Spinbox, 
        "paras" : {"width":10, "from_":0.5, "to":5, "increment":0.1},
        "default":1,
        "call" : "scale"},
}

布尔型参数

然后是一些布尔类型的参数,适合用Checkbutton

参数说明类型适用组件
repeat是否重复单词默认FalseCheckbutton
include_numbers是否包含数字默认False
normalize_plurals是否去掉词尾的s默认True
wcDct = {
    "单词重复" : {
        "ctrl": ttk.Checkbutton, 
        "paras" : {"width":10},
        "default": False,
        "call" : "repeat"},
    "包含数字" : {
        "ctrl": ttk.Checkbutton, 
        "paras" : {"width":10},
        "default": False,
        "call" : "include_numbers"},
    "去词尾s" : {
        "ctrl": ttk.Checkbutton, 
        "paras" : {"width":10},
        "default": False,
        "call" : "normalize_plurals"},
}

背景颜色

最后,还有一个背景颜色对话框

参数说明对话框类型说明
background_color背景色颜色对话框默认"black"
wcDct = {
    "背景颜色" : {
        "ctrl": DialogButton,
        "paras" : {"height":5, "widthL":22, "widthR":8, "logtype":"颜色"},
        "call" : "background_color",
        "default" : "balck"},
}

更改之后的界面如下

在这里插入图片描述

词云生成逻辑

有了这些之后,还要修改词云生成逻辑,即调用这些参数所获得的值,最后根据上图中的参数,得到点云如下

在这里插入图片描述

源代码

所有源代码如下

import tkinter as tk 
import tkinter.ttk as ttk
from tkinter.filedialog import (askopenfilename,
    askopenfilenames, askdirectory, asksaveasfilename)
from tkinter.colorchooser import askcolor

from threading import Thread

import numpy as np
import re
import csv
import jieba
from wordcloud import WordCloud

import os

class DialogButton(ttk.Frame):
    def __init__(self, master, 
        height, widthL, widthR, logtype, label=None, text=None, 
        frmDct={}, btnDct={}, enyDct={}, logDct={}):
        w = widthL + widthR
        super().__init__(master, 
            height=height, width = w, **frmDct)
        self.pack(fill=tk.X)

        self.text = tk.StringVar() if not text else text
        ttk.Entry(self, width=widthL, textvariable=self.text, 
            **enyDct).pack(side=tk.LEFT, fill = tk.X, padx=5)
        
        ttk.Button(self, width=widthR, 
            text=self.setLabel(logtype, label),
            command = self.Click, **btnDct).pack(side=tk.RIGHT)
        self.logtype = logtype
        self.logDct = logDct

    def setLabel(self, key, label=None):
        if label:
            return label
        labelDct = {
            "文件"   : "选择文件",
            "文件夹" : "选择路径",
            "多文件" : "选择多个文件",
            "保存" : "存储路径",
            "颜色"   : "选择颜色",
        }
        return labelDct[key]

    def Click(self):
        typeDct = {
            "文件"  : askopenfilename,
            "文件夹": askdirectory,
            "多文件": askopenfilenames,
            "保存"  : asksaveasfilename,
            "颜色"  : askcolor,
        }
        text = typeDct[self.logtype](**self.logDct)
        if self.logtype == "颜色":
            text = text[1]
        self.text.set(text)

    def get(self):
        return self.text.get()

    def set(self, txt):
        self.text.set(txt)

wcDct = {
    "词云宽度" : {
        "ctrl": ttk.Spinbox, 
        "paras" : {"width":10, "from_":100, "to":2000, "increment":10},
        "default":800,
        "call" : "width"},
    "词云高度" : {
        "ctrl": ttk.Spinbox, 
        "paras" : {"width":10, "from_":100, "to":2000, "increment":10},
        "default":450,
        "call" : "height"},
    "图像缩放" : {
        "ctrl": ttk.Spinbox, 
        "paras" : {"width":10, "from_":0.5, "to":10, "increment":0.1},
        "default":1,
        "call" : "scale"},
    "最小文字" : {
        "ctrl": ttk.Spinbox, 
        "paras" : {"width":10, "from_":1, "to":50, "increment":1},
        "default":4,
        "call" : "min_font_size"},
    "最大文字" : {
        "ctrl": ttk.Spinbox, 
        "paras" : {"width":10, "from_":10, "to":1e3, "increment":10},
        "default":400,
        "call" : "max_font_size"},
    "字体步长" : {
        "ctrl": ttk.Spinbox, 
        "paras" : {"width":10, "from_":1, "to":20, "increment":1},
        "default":10,
        "call" : "font_step"},
    "最短词长" : {
        "ctrl": ttk.Spinbox, 
        "paras" : {"width":10, "from_":0, "to":10, "increment":1},
        "default":1,
        "call" : "min_word_length"},
    "最多词数" : {
        "ctrl": ttk.Spinbox, 
        "paras" : {"width":10, "from_":10, "to":500, "increment":10},
        "default":200,
        "call" : "max_words"},
    "字体路径" : {"ctrl": DialogButton,
                 "paras" : {"height":5, "widthL":22, "widthR":8, "logtype":"文件"},
                 "call" : "font_path",
                 "default" : r"C:\Windows\Fonts\simhei.ttf"},
    "输入路径" : {"ctrl": DialogButton, "paras" : {"width":25},
                "paras" : {"height":5, "widthL":22, "widthR":8, "logtype":"文件"},},
    "输出路径" : {"ctrl": DialogButton, "paras" : {"width":25},
                "paras" : {"height":5, "widthL":22, "widthR":8, "logtype":"保存"},},
    "背景颜色" : {
        "ctrl": DialogButton,
        "paras" : {"height":5, "widthL":22, "widthR":8, "logtype":"颜色"},
        "call" : "background_color",
        "default" : "balck"},
    "单词重复" : {
        "ctrl": ttk.Checkbutton, 
        "paras" : {"width":10},
        "default": False,
        "call" : "repeat"},
    "包含数字" : {
        "ctrl": ttk.Checkbutton, 
        "paras" : {"width":10},
        "default": False,
        "call" : "include_numbers"},
    "去词尾s" : {
        "ctrl": ttk.Checkbutton, 
        "paras" : {"width":10},
        "default": False,
        "call" : "normalize_plurals"},
}


class DrawWords(ttk.Frame):
    def __init__(self, master, **options):
        super().__init__(master, **options)
        self.pack()
        self.words = None

        self.initWidgets()

    
    def initWidgets(self):
        frm = ttk.Frame(self)
        frm.pack(side=tk.LEFT, fill=tk.Y)
        self.initPara(frm)

        frm = ttk.LabelFrame(self, text="分词结果")
        frm.pack(fill=tk.BOTH, expand=True)
        self.txtSplit = tk.Text(frm)
        self.txtSplit.pack(side=tk.LEFT, fill=tk.BOTH, padx=5, pady=5, expand=True)
        self.addScroll(frm, self.txtSplit)
    
    def addScroll(self, frm, txt):
        scroll = ttk.Scrollbar(frm)
        scroll.pack(side=tk.RIGHT,fill=tk.Y)
        txt.config(yscrollcommand=scroll.set)
        scroll.config(command=txt.yview)

    def setOneCheck(self, frm, key):
        v = wcDct[key]      # 组件参数
        n = v["call"]       # 调用名
        self.vars[n] = tk.BooleanVar()
        self.vars[n].set(v["default"])
        self.checks[n] = v["ctrl"](frm, text=key,
            variable=self.vars[n], **v["paras"])
        self.checks[n].pack(side=tk.LEFT)
        

    def setOneSpinBox(self, frm, key):
        ttk.Label(frm, width=8, text=key).pack(side=tk.LEFT)
        v = wcDct[key]      # 组件参数
        n = v["call"]       # 调用名
        self.spins[n] = v["ctrl"](frm, **v["paras"])
        self.spins[n].set(v["default"])
        self.spins[n].pack(side=tk.LEFT)
    
    def setOneDiaButton(self, frmPara, key):
        frm = ttk.Frame(frmPara)
        frm.pack(side=tk.TOP, fill=tk.X)
        ttk.Label(frm, width=8, text=key).pack(side=tk.LEFT)
        v = wcDct[key]
        n = v["call"] if 'call' in v else key
        self.paths[n] = v["ctrl"](frm, **v['paras'])
        self.paths[n].pack(side=tk.LEFT)
        if 'default' in v:
            self.paths[n].set(v['default'])

    def setOneColButton(self, frm, key):
        frm = ttk.Frame(frmPara)
        frm.pack(side=tk.TOP, fill=tk.X)
        ttk.Label(frm, width=8, text=key).pack(side=tk.LEFT)
        v = wcDct[key]
        n = v["call"] if 'call' in v else key
        self.paths[n] = v["ctrl"](frm, **v['paras'])
        self.paths[n].pack(side=tk.LEFT)
        if 'default' in v:
            self.paths[n].set(v['default'])


    def initPara(self, frmPara):
        self.spins = {}
        self.checks = {}
        self.vars = {}
        keys = ["词云宽度", "词云高度", "最小文字", "最大文字", 
            "字体步长", "图像缩放", "最短词长", "最多词数"]
        for i,key in enumerate(keys):
            if i%2==0:
                frm = ttk.Frame(frmPara)
                frm.pack(side=tk.TOP, fill=tk.X, pady=2)
            self.setOneSpinBox(frm, key)
        
        keys = ["单词重复", "包含数字", "去词尾s"]
        for i,key in enumerate(keys):
            if i%4==0:
                frm = ttk.Frame(frmPara)
                frm.pack(side=tk.TOP, fill=tk.X, pady=2)
            self.setOneCheck(frm, key)

        self.paths = {}
        for key in ["背景颜色", "输入路径", "输出路径", "字体路径"]:
            self.setOneDiaButton(frmPara, key)
                
        frm = ttk.Frame(frmPara)
        frm.pack(side=tk.TOP, fill=tk.X)
        ttk.Button(frm, text="分词预览", 
            command=self.splitWords).pack(side=tk.LEFT)
        ttk.Button(frm, text="分词保存", 
            command=self.saveWords).pack(side=tk.LEFT)
        ttk.Button(frm, text="输出词云", 
            command=self.genWordCloud).pack(side=tk.LEFT)

    def splitWords(self):
        p = self.paths["输入路径"].get()
        with open(p, encoding='utf8') as f:
            text = f.read()
        words = jieba.lcut(text)
        self.words = [w for w in words if len(w)>1] # 取出长度大于1的词
        self.setSplit("\n".join(self.words))

    def saveWords(self):
        path = asksaveasfilename()
        with open(path) as f:
            f.write(self.txtSplit.get(1.0, 'end'))

    def genWordCloud(self):
        dct = {}
        keys = ['width', 'height', 'font_path', 'scale',
            'min_font_size', 'max_font_size', 'font_step', 
            'max_words', 'min_word_length', 'background_color',
            'repeat', 'include_numbers', 'normalize_plurals']
        for key in keys:
            if key in self.spins:
                dct[key] = int(self.spins[key].get())
            if key in self.paths:
                dct[key] = self.paths[key].get()
            if key in self.checks:
                dct[key] = self.vars[key].get()=='1'  
        print(dct)
        try:
            cloud = WordCloud(**dct)
        except Exception as e:
            print(e)
        txt = self.txtSplit.get(1.0, "end")
        txt = " ".join(txt.split("\n"))
        cloud.generate(txt)
        p = self.paths["输出路径"].get()
        if not (p.endswith('.png') or p.endswith('.svg')):
            p = p+".png"
        cloud.to_file(p)
    
    def setSplit(self, txt):
        self.txtSplit.delete(1.0, "end")
        self.txtSplit.insert("end", txt)
        self.txtSplit.see("end")

if __name__ == "__main__":
    root = tk.Tk()
    DrawWords(root).pack(side=tk.TOP, fill=tk.BOTH)
    root.mainloop()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1169726.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux】进程概念III --fork函数解析

Halo,这里是Ppeua。平时主要更新C语言,C,数据结构算法…感兴趣就关注我吧!你定不会失望。 本篇导航 0. 创建进程1. 认识fork函数2.使用Fork函数3.关于fork的为什么3.1 一个函数如何返回两次?fork究竟在干什么?3.2 为什么要给子…

0-1矩阵列互斥问题——回溯法 Python实现

三、 0-1 矩阵的列集互斥问题。给定一个 m n m \times n mn 的 0-1 矩阵 A \mathrm{A} A 。定义列互斥为: 对于矩阵 A A A 中的任意两列 i i i 和 j j j, 如果在对应的每一行上, i i i 和 j j j 不存在同时为 1 的情况, 则称列 i \mathrm{i} i 和 j \mathrm{j} j 互斥…

Redis-命令操作Redis->redis简介,redis的安装(Linux版本windows版本),redis的命令

redis简介redis的安装(Linux版本&windows版本)redis的命令 1.redis简介 Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理。 它支持字符串、哈…

零基础入门Python,主要该学些什么?一文详解。

文章目录 前言一、Python开发基础二、Python高级编程和数据库开发三、前端开发四、WEB框架开发五、爬虫开发六、全栈项目实战七、数据分析八、人工智能九、自动化运维&开发十、高并发语言GO开发关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精…

Nginx的location优先级和重定向

Nginx的location有优先级级和匹配方式: 在http模块有server,在server模块才有location,location匹配的是uri /test /image 在一个server当中有多个location,如何来确定匹配哪个location。 Nginx的正则表达式: ^:字符串的起始位置 $:字符串的结束位…

推荐彩虹知识商城源码

彩虹知识商城7.0.3小森升级版新增供货商开心学习版,新增邮件提醒功能,支持给用户发订单、结算等邮件通知,支持给管理员发送提现、域名审核等邮件通知,支持设置手续费最低扣除金额,修复了其他一些已知问题。 演示地址&…

工作数字化的中国历程 | 从 OA 到 BPM 到数字流程自动化

业务流程是由“活动”(或称“工作任务”)构成的,在企业里的所有工作是不是都叫流程,或者属于流程的一部分,这个概念很绕,我觉得没有必要去做学究气的辨析。我曾经提出过一个从工作的两个特性(产…

x86保护模式笔记

多任务 调用门权级规则 合法调用门g1定义: 门g1.DPL 贱于或等于 门g1.目标段.DPL若 代码段p1.CPL 优于或等于 门g1.DPL 则 p1 正常 call g1TSS 权级规则 权级规则4. p代码段CPL d数据段DPL: 判定p访问d 若 p代码段CPL < d数据段DPL, 则p能访问d …

听听ChatGPT对IT行业的发展和就业前景的看法

&#x1f308;个人主页: Aileen_0v0&#x1f525;系列专栏:PYTHON学习系列专栏&#x1f4ab;"没有罗马,那就自己创造罗马~" 目录 (1)判断素数 写法1: 写法2: (2)计算1-100的偶数之和 写法1: 写法2: (3)计算1-100的奇数之和 (4)多层循环 IT行业哪个方向比较…

腾讯云双十一云服务器活动:88元1年的云服务器难道不香吗?

腾讯云双十一活动中&#xff0c;有三款轻量应用服务器可享受特惠优惠。这三款服务器分别是2核2G、2核4G和4核8G&#xff0c;价格分别为88元/年、166.6元/年和529元/15个月。对于需要低成本而又高性能的服务器需求&#xff0c;轻量应用服务器是一个理想的选择。 轻量应用服务器特…

Linux常用命令——chattr命令

在线Linux命令查询工具 chattr 用来改变文件属性 补充说明 chattr命令用来改变文件属性。这项指令可改变存放在ext2文件系统上的文件或目录属性&#xff0c;这些属性共有以下8种模式&#xff1a; 语法 chattr(选项)选项 a&#xff1a;让文件或目录仅供附加用途&#xff…

某某盾-滑块验证-自动获取validate值-(逆向js+python)

我是标题 1.从get&#xff1f;网站获取滑块图片以及token1.1获取fp值1.2 获取cb值1.3 模拟发包 2.获取滑块移动距离3.发包获取最终的validate值3.1轨迹生成3.2 check网站发包3.3 获取data值 4.结论 本实验是根据某某盾示例网站 主要分为两个部分 1.从get&#xff1f;网站获取滑…

TypeScript 第一站概念篇

前言 &#x1f52e; 好长一段时间没有写文章了&#xff0c;原因是经历了一次工作变动&#xff0c;加入了一个有一定规模的开发团队&#xff0c;前端算上我有四个人&#xff0c;很欣慰&#xff0c;体验一下团队配合的感觉&#xff0c;在我之上有一个组长&#xff0c;比我年长四…

Portraiture4.0介绍与插件安装包下载

相信有很多需要经常进行图像处理的小伙伴的电脑上都有一款PS软件吧&#xff0c;PS的功能非常强大&#xff0c;各种细节处理都非常细致&#xff0c;但还是需要一些插件来帮我们快速处理图片&#xff0c;能够省去很多时间和精力。今天给大家介绍一款PS磨皮插件&#xff0c;能够快…

【Linux】进程等待

文章目录 进程等待进程等待必要性实验(见见猪跑)进程等待的方法wait方法waitpid**方法**宏的使用方法获取子进程status 阻塞VS非阻塞概念对比非阻塞有什么好处 具体代码实现进程的阻塞等待方式:进程的非阻塞等待方式:让父进程做其他任务 进程等待 进程等待必要性 之前讲过&am…

2023腾讯云双11优惠3年轻量2核2G4M服务器366.6元,三年价哦!

腾讯云3年轻量应用服务器配置为2核2G4M带宽、50GB SSD系统盘双11优惠价格366.6元三年、108元一年&#xff0c;只是限制月流量&#xff0c;套餐自带300GB月流量。腾讯云百科txybk.com分享2023腾讯云双11优惠活动3年轻量2核2G4M带宽优惠价格、购买条件&#xff1a; 3年轻量2核2G…

大模型的“成本瘦身”运动

数据大、参数量大、算力大&#xff0c;大模型的某些能力才会“涌现”&#xff0c;这一点在科技圈广为流传。 做大模型的主流思想是&#xff1a;不要轻易说模型“不行”&#xff0c;如果“它还没行”&#xff0c;那就做得更大一点。 所以&#xff0c;不到一年的时间&#xff0c;…

MySQL InnoDB数据存储结构

1. 数据库的存储结构&#xff1a;页 索引结构给我们提供了高效的索引方式&#xff0c;不过索引信息以及数据记录都是保存在文件上的&#xff0c;确切说是存储在页结构中。另一方面&#xff0c;索引是在存储引擎中实现的&#xff0c;MySQL服务器上的存储引擎负责对表中数据的读…

Visual Studio使用Git忽略不想上传到远程仓库的文件

前言 作为一个.NET开发者而言&#xff0c;有着宇宙最强IDE&#xff1a;Visual Studio加持&#xff0c;让我们的开发效率得到了更好的提升。我们不需要担心环境变量的配置和其他代码管理工具&#xff0c;因为Visual Studio有着众多的拓展工具。废话不多说&#xff0c;直接进入正…

佳易王商超便利店等会员快速积分、积分兑换管理系统软件下载

佳易王商超便利店等会员快速积分、积分兑换管理系统软件下载 一、佳易王会员管理软件大众版 部分功能简介&#xff1a; 1、会员信息登记 &#xff1a;可以直接使用手机号登记&#xff0c;也可以使用实体卡片&#xff0c;推荐用手机号即可。 2、会员卡类型 &#xff1a;可以自…