Gradio 案例——将文本文件转为词云图

news2024/11/17 23:44:35

文章目录

  • Gradio 案例——将文本文件转为词云图
    • 界面截图
    • 依赖安装
    • 项目目录结构
    • 代码

Gradio 案例——将文本文件转为词云图

  • 利用 word_cloud 库,将文本文件转为词云图
  • 更完整、丰富的示例项目见 GitHub - AlionSSS/wordcloud-webui: The web UI for word_cloud(text to word cloud picture converter)

界面截图

image.png

依赖安装

  • 新建一个虚拟环境 Python 3.9.16
  • 依赖
    • $ pip install gradio==4.29 -i "https://pypi.doubanio.com/simple/"
    • $ pip install wordcloud==1.9.3 -i "https://pypi.doubanio.com/simple/"
    • $ pip install jieba==0.42.1 -i "https://pypi.doubanio.com/simple/"

项目目录结构

wordcloud-webui         # 目录
--/resources             # 资源目录
--/consts.py             # py文件,常量
--/gradio_interfaces.py  # py文件,Gradio视图
--/jieba_util.py         # py文件,工具库文件
--/lib_word_cloud.py     # py文件,工具库文件
--/main.py               # py文件,入口

代码

  • main.py
from gradio_interfaces import iface

if __name__ == "__main__":
    iface.launch()
  • lib_word_cloud.py
from wordcloud import WordCloud, ImageColorGenerator
import numpy as np
from PIL import Image

from consts import *

def text2wordcount_normal(
    text: str,
    background_color: str = "white",
    margin = 2,
    min_font_size = 4,
    max_font_size = 200,
    font_path = None,
    width: int = 400,
    height: int = 200,
):
    if not background_color or "" == str(background_color).strip():
        background_color = "white"
    if not min_font_size or  min_font_size < 1:
        min_font_size = 4
    if not max_font_size or max_font_size < 4:
        max_font_size = 200    
    if not font_path or "" == str(font_path).strip():
        font_path = DEFAULT_FONT_PATH
    if not width or width < 1:
        width = 400
    if not height or height < 1:
        height = 200 

    # Generate a word cloud image
    wordcloud = WordCloud(
        font_path=font_path,
        width=width, height=height, background_color=background_color, 
        max_words=2000, 
        margin=margin, min_font_size=min_font_size, max_font_size=max_font_size, 
        random_state=42
    ).generate(text)
    return wordcloud.to_image()

def text2wordcount_mask(
    text: str,
    background_color: str = "white",
    margin = 2,
    min_font_size = 4,
    max_font_size = 200,
    font_path = None,
    mask_image = None,
    mask_color = None,
    contour_width=3,
    contour_color="steelblue",
):
    if not background_color or "" == str(background_color).strip():
        background_color = "white"
    if not min_font_size or  min_font_size < 1:
        min_font_size = 4
    if not max_font_size or max_font_size < 4:
        max_font_size = 200   
    if not font_path or "" == str(font_path).strip():
        font_path = DEFAULT_FONT_PATH
    if not contour_width or contour_width < 0:
        contour_width = 3      
    if not contour_color or "" == str(contour_color).strip():
        contour_color = "steelblue"
    
    # mask_color
    if mask_color is not None:
        image_colors = ImageColorGenerator(mask_color, True)
    else:
        image_colors = ImageColorGenerator(mask_image, True)

    # Generate a word cloud image
    wordcloud = WordCloud(
        font_path=font_path,
        mask=mask_image,
        background_color=background_color,
        color_func=image_colors,
        contour_width=contour_width,
        contour_color=contour_color,
        max_words=2000, 
        margin=margin, min_font_size=min_font_size, max_font_size=max_font_size, 
        random_state=42
    ).generate(text)

    return wordcloud.to_image()
  • jieba_util.py
import jieba
# jieba.enable_parallel(4)

from consts import *

# The function for processing text with Jieba
def jieba_processing_txt(text, userdict_list=['阿Q', '孔乙己', '单四嫂子']):
    if userdict_list is not None:
        for word in userdict_list:
            jieba.add_word(word)

    mywordlist = []
    seg_list = jieba.cut(text, cut_all=False)
    liststr = "/ ".join(seg_list)

    with open(STOPWORDS_PATH, encoding='utf-8') as f_stop:
        f_stop_text = f_stop.read()
        f_stop_seg_list = f_stop_text.splitlines()

    for myword in liststr.split('/'):
        if not (myword.strip() in f_stop_seg_list) and len(myword.strip()) > 1:
            mywordlist.append(myword)
    return ' '.join(mywordlist)
  • gradio_interfaces.py
import gradio as gr

import lib_word_cloud
import jieba_util

from consts import *

def service_text2wc(
    text_file,
    text_lang,
    text_dict: str,
    background_color,
    margin,
    max_font_size,
    min_font_size,
    font_file,
    width,
    height,
    mask_image,
    mask_color,
    contour_width,
    contour_color,
):
    if not text_file:
        gr.Warning(f"请传入正确的文本文件!")
        return
    if margin < 0 :
        gr.Warning(f"字体间隔配置不合法!")
        return
    if min_font_size < 0 or max_font_size < 0 or min_font_size > max_font_size:
        gr.Warning(f"字体大小配置不合法!")
        return

    try:
        with open(file=text_file.name, encoding="utf-8") as file:
            text = file.read()
            
        if text_lang == '中文':
            gr.Info(f"选择了中文,将使用Jieba库解析文本!")
            userdict_list = []
            if text_dict is not None:
                # userdict_list = map(lambda w: w.strip(), text_dict.split(", "))
                userdict_list = [w.strip() for w in text_dict.split(",")]
            text = jieba_util.jieba_processing_txt(text, userdict_list)
            
        font_path = font_file.name if font_file else None
        
        if mask_image is not None:
            return lib_word_cloud.text2wordcount_mask(
                text,
                background_color,
                margin,
                min_font_size,
                max_font_size,
                font_path,
                mask_image,
                mask_color,
                contour_width,
                contour_color,
            )
        else:
            return lib_word_cloud.text2wordcount_normal(
                text, 
                background_color, 
                margin,
                min_font_size,
                max_font_size,
                font_path, 
                width, 
                height
            )
    except Exception as e:
        print(e)
        raise gr.Error("文本转词云图时,发生异常:" + str(e))

js = """
function createGradioAnimation() {
    var container = document.createElement('div');
    container.id = 'gradio-animation';
    container.style.fontSize = '2em';
    container.style.fontWeight = 'bold';
    container.style.textAlign = 'center';
    container.style.marginBottom = '20px';

    var text = '欢迎使用“词云转换器”!';
    for (var i = 0; i < text.length; i++) {
        (function(i){
            setTimeout(function(){
                var letter = document.createElement('span');
                letter.style.opacity = '0';
                letter.style.transition = 'opacity 0.5s';
                letter.innerText = text[i];

                container.appendChild(letter);

                setTimeout(function() {
                    letter.style.opacity = '1';
                }, 50);
            }, i * 200);
        })(i);
    }

    var gradioContainer = document.querySelector('.gradio-container');
    gradioContainer.insertBefore(container, gradioContainer.firstChild);

    return 'Animation created';
}
"""

with gr.Blocks(title="词云转换器", js=js) as iface:
    with gr.Row():
        with gr.Column():
            with gr.Group():
                with gr.Row():
                    input_text_file = gr.File(label="待处理的文本文件(必填)")
                    with gr.Column():
                        gr.Label(label="Tips", value="请传入正常可读的文本文件,如以.txt结尾的文档", color="#fee2e2")
                        gr.File(value=EXAMPLE_TEXT_FILE, label="文本文件的样例")
                        input_text_lang = gr.Radio(label="文本语言模式", choices=["中文", "英文"], value="中文")
                input_text_dict = gr.Textbox(label="自定义分词词典(可选)", info="中文模式使用,多个词之间用英文逗号分隔,例如'阿Q, 孔乙己, 单四嫂子'")
            with gr.Tab("普通模式"):
                with gr.Row():
                    input_width = gr.Number(value=400, label="生成图像的宽", minimum=1)
                    input_height = gr.Number(value=200, label="生成图像的高", minimum=1)
                gr.Label(label="Tips", value="使用该模式时,记得清理掉“Mask模式”下的“Mask图像”", color="#fee2e2")
            with gr.Tab("Mask模式"):
                with gr.Row():
                    input_contour_width = gr.Number(value=3, label="轮廓线的粗细", minimum=0)
                    input_contour_color = gr.Textbox(value="steelblue", label="轮廓线的颜色")
                with gr.Row():
                    input_mask_image = gr.Image(label="Mask图像(决定词云的形状、颜色、宽高)")
                    input_mask_color = gr.Image(label="若传入该图,则词云的颜色由该图决定")
                # gr.Image(value=EXAMPLE_MASK_IMAGE_PATH, label="Mask图像的样例", interactive=False)
                gr.Gallery(value=[EXAMPLE_MASK_IMAGE_PATH, EXAMPLE_MASK_IMAGE_PATH, EXAMPLE_MASK_IMAGE_PATH], label="Mask图像的样例", interactive=False)
        with gr.Column():
            with gr.Group():
                with gr.Row():
                    with gr.Group():
                        input_bg_color = gr.Textbox(value="white", label="词云图的背景色(默认为'white')")
                        input_margin = gr.Number(value=2, label="字体间隔(默认为'2')", minimum=0)
                        with gr.Row():
                            input_min_font_size = gr.Number(value=4, label="字体大小-最小值", minimum=1)
                            input_max_font_size = gr.Number(value=200, label="字体大小-最大值", minimum=4)    
                    input_font_file = gr.File(label="词云图的字体文件(可选,如otf文件)")
                format_radio = gr.Radio(choices=["png", "jpeg", "webp", "bmp", "tiff"], label="词云图像格式", value="png")
            submit_button = gr.Button("开始处理", variant="primary")
            output_image = gr.Image(label="词云图", format="png")

    def fix_format(x):
        output_image.format = x 
        return None

    format_radio.change(fn=fix_format, inputs=format_radio)

    submit_button.click(
        fn=service_text2wc,
        inputs=[
            input_text_file,
            input_text_lang,
            input_text_dict,
            input_bg_color,
            input_margin,
            input_max_font_size,
            input_min_font_size,
            input_font_file,
            input_width,
            input_height,
            input_mask_image,
            input_mask_color,
            input_contour_width,
            input_contour_color,
        ],
        outputs=output_image,
    )

  • consts.py,记得修改下下面文件的地址,和resource目录对应
# 样例文本
EXAMPLE_TEXT_FILE = r".\wordcloud-webui\resources\CalltoArms.txt"
# MASK图像样例
EXAMPLE_MASK_IMAGE_PATH = r".\wordcloud-webui\resources\parrot_mask.png "
# 分词器的 stop word 库
STOPWORDS_PATH = r".\wordcloud-webui\resources\stopwords_cn_en.txt"
# 词云图的默认字体
DEFAULT_FONT_PATH = r".\wordcloud-webui\resources\SourceHanSerifK-Light.otf"

  • resources 目录
    • parrot_mask.png parrot_mask.png
    • CalltoArms.txt https://github.com/amueller/word_cloud/blob/main/examples/wc_cn/CalltoArms.txt
    • SourceHanSerifK-Light.otf https://github.com/amueller/word_cloud/blob/main/examples/fonts/SourceHanSerif/SourceHanSerifK-Light.otf
    • stopwords_cn_en.txt https://github.com/amueller/word_cloud/blob/main/examples/wc_cn/stopwords_cn_en.txt

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

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

相关文章

一个浏览器插件,绕过限制,登录微信网页版!

摘要 早在2017年开始&#xff0c;微信网页版就已经住逐渐开始停止登录&#xff0c;以为了保障你的账号安全为由引导你使用电脑版微信。具体如下&#xff1a; 当然这个影响并不是所有账号&#xff0c;还是有一些账号不明觉厉地没有被影响到&#xff0c;我自己有2个号都还是可以…

MinIO 使用

MinIO自建对象存储 1、dock-compose 使用dock-compose拉取 minio:image: "minio/minio"container_name: minioports:- "9000:9000"- "9001:9001"volumes:- "./minio/data1:/data1"- "./minio/data2:/data2"restart: on-fai…

32. 【Java教程】集合

在前面的小节中&#xff0c;我们学习了数组&#xff0c;本小节学习的集合同样用于存放一组数据&#xff0c;我们将学习什么是集合、集合的应用场景 &#xff0c;在应用场景部分我们将对比 Java 数组与集合的区别&#xff0c;还将系统介绍 Java 集合的架构&#xff0c;也将结合实…

调查问卷和考试系统SurveyKing

什么是 SurveyKing &#xff1f; SurveyKing 是功能更强大的调查问卷、考试系统&#xff0c;很多功能体验超过问卷网、问卷星。支持在线考试/调查问卷/公开查询/题库刷题/投票。 软件特性 &#x1f947; 支持 20 多种题型&#xff0c;如填空、选择、下拉、级联、矩阵、分页、签…

TCP的重传机制

TCP 是一个可靠的传输协议&#xff0c;解决了IP层的丢包、乱序、重复等问题。这其中&#xff0c;TCP的重传机制起到重要的作用。 序列号和确认号 之前我们在讲解TCP三次握手时&#xff0c;提到过TCP包头结构&#xff0c;其中有序列号和确认号&#xff0c; 而TCP 实现可靠传输…

FPGA高端项目:FPGA解码MIPI视频+图像缩放+视频拼接,基于MIPI CSI-2 RX Subsystem架构实现,提供4套工程源码和技术支持

目录 1、前言工程概述免责声明 2、相关方案推荐我这里已有的 MIPI 编解码方案本方案在Xilinx Artix7-35T上解码MIPI视频的应用本方案在Xilinx Artix7-100T上解码MIPI视频的应用本方案在Xilinx Kintex7上解码MIPI视频的应用本方案在Xilinx Zynq7000上解码MIPI视频的应用本方案在…

小邪大佬最新版微信hook

目前小邪大佬已经更新到最新版本微信hook了。 /发送文件 BOOL SendCdnFilePbMsg(string sendId, string cdnkey, string aes_key,string file_name,string md5, int size, string syncKey) {FileMessage sfm;sfm.set_file_id(cdnkey);sfm.set_size(size);sfm.set_aes_key(aes_…

内燃机智能制造工厂工业物联数字孪生平台,推进制造业数字化转型

内燃机智能制造工厂工业物联数字孪生平台&#xff0c;推进制造业数字化转型。随着科技的飞速发展&#xff0c;制造业正迎来一场深刻的数字化转型。内燃机智能制造工厂工业物联数字孪生平台&#xff0c;作为这一转型的重要推手&#xff0c;正逐渐改变着传统制造业的面貌。 内燃…

《异常检测——从经典算法到深度学习》29 EasyTSAD: 用于时间序列异常检测模型的工业级基准

《异常检测——从经典算法到深度学习》 0 概论1 基于隔离森林的异常检测算法 2 基于LOF的异常检测算法3 基于One-Class SVM的异常检测算法4 基于高斯概率密度异常检测算法5 Opprentice——异常检测经典算法最终篇6 基于重构概率的 VAE 异常检测7 基于条件VAE异常检测8 Donut: …

LC 旋转 - 模拟对象

原文链接 链接 液晶 (LC) 旋转网格属性允许您以 theta、phi 为单位指定空间变化的 LC 导向。 液晶由杆状分子结构组成&#xff0c;这些分子结构具有相对于长轴的旋转对称性。因此&#xff0c;液晶具有空间变化的单轴光学特性。 相对于分子长轴和分子短轴的折射率称为非寻常 ne …

Mybatis数据加密解密

文章目录 Mybatis数据加密解密一、自定义注解二、自定义参数处理拦截器结果集拦截器加密解密 Mybatis数据加密解密 方案一&#xff1a;Mybatis拦截器之数据加密解密【Interceptor】 拦截器介绍 Mybatis Interceptor 在 Mybatis 中被当作 Plugin(插件)&#xff0c;不知道为什么…

注意力可视化代码

读取网络层输出的特征到txt文件&#xff0c;arr为文件名 def hot(self, feature, arr):# 在第二维&#xff08;通道维&#xff09;上相加summed_tensor torch.sum(feature, dim1, keepdimTrue) # 结果形状为 [1, 1, 64, 64]selected_matrix summed_tensor.squeeze(1) # 移除…

【RS】哨兵系列新网站无法下载的问题及解决办法(Sentinel-2)

最近有些小伙伴留言说哨兵数据无法下载&#xff0c;网站打开后会有一层蒙版&#xff0c;无法选取研究区等信息&#xff0c;今天就跟大家分享一下如何解决这个问题。还知道如何下载的小伙伴可以移步到之前的文章&#xff1a;【RS】欧空局Sentinel-2卫星数据下载(哨兵1、2、3、5P…

shopee签名x-sap-ri、x-sap-sec算法还原

最新版签名&#xff0c;免账号登录成功率百分百&#xff0c;需要可d 两种方式base64 MTQzMDY0OTc3OA QXVndXN0MjItZnF4

JS【详解】快速排序

快速排序的时间复杂度为 O(n2) 排序流程 1、首先设定一个分界值&#xff08;比如数组最中间的元素&#xff09;&#xff0c;通过该分界值将数组分成左右两部分。 2、将大于或等于分界值的数据集中到数组右边&#xff0c;小于分界值的数据集中到数组的左边。 3、对左侧和右侧的…

【网络层】IP地址基础 与 子网掩码

文章目录 IP地址基础IP地址概念IP地址分类公网地址和私网地址 子网掩码子网掩码作用默认子网掩码网络地址、主机地址、广播地址 IP地址基础 IP地址概念 IP地址&#xff1a;IP Address 在网络中&#xff0c;通信节点都需要有一个IP地址 IP地址以点分十进制表示&#xff0c;有…

【QEMU中文文档】1.1 支持的构建平台

本文由 AI 翻译&#xff08;ChatGPT-4&#xff09;完成&#xff0c;并由作者进行人工校对。如有任何问题或建议&#xff0c;欢迎联系我。联系方式&#xff1a;jelin-shoutlook.com。 原文&#xff1a;Supported build platforms — QEMU documentation QEMU 旨在支持在多个主机…

prometheus docker部署

1.安装Docker sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-EOF {"registry-mirrors":["https://hub-mirror.c.163.com"] } EOF export DOWNLOAD_URL"https://hub-mirror.163.com/docker-ce" curl -fsSL https://ge…

携手亚马逊云科技,神州泰岳如何打通生成式AI落地最后三公里

导读&#xff1a;神州泰岳成为首批获得亚马逊云科技生成式AI能力认证的合作伙伴。 “过去6年来&#xff0c;在与亚马逊云科技的合作过程中&#xff0c;我们大概签约了300家以上的中国出海企业。”近日在一次沟通会上&#xff0c;神州泰岳副总裁兼云事业部总经理刘家歆这样向媒…

springboot编写日志环境搭建过程

AOP记录日志 AOP记录日志的主要优点包括&#xff1a; 1、低侵入性&#xff1a;AOP记录日志不需要修改原有的业务逻辑代码&#xff0c;只需要新增一个切面即可。 2、统一管理&#xff1a;通过AOP记录日志可以将各个模块中需要记录日志的部分进行统一管理&#xff0c;降低了代…