基于PyQt5制作一个数据图表生成器

我的需求:手动配置X轴、Y轴、图表标题等参数自动通过Pyecharts模块生成可视化的html数据图表,并将浏览器图表展示到UI界面上。

制作出图表后的效果展示如下:

另外,生成后的图表结果会使用 html 的形式保存下来。

导入 UI 界面相关的 PyQt5 第三方模块库。

from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *

若是使用PyQt5的版本是5.10.1以上,则需要单独安装一下PyQtWebEngine,说是QtWebEngineWidgets模块被新版本移除了。执行一下下面安装单独安装一下PyQtWebEngine就OK了。

pip install PyQtWebEngine

导入 Web 浏览器引擎的支持。

from PyQt5.QtWebEngineWidgets import QWebEngineView

应用其他的相关模块导入。

import sys  # 应用操作库
import os

from datetime import datetime
from pyecharts.charts import *  # 图表设置展示库
from pyecharts import options  # 图标参数配置库

主要的代码块实现过程如下:

class DataVisual(QWidget):
    def __init__(self):
        super(DataVisual, self).__init__()
        self.cwd = os.getcwd()  # 获取当前路径
        self.init_ui()

    def init_ui(self):
        self.setWindowTitle('数据图表生成器')
        self.setWindowIcon(QIcon('数据.ico'))

        self.brower = QWebEngineView()
        self.brower.setMinimumWidth(800)
        self.brower.setMaximumWidth(1400)
        self.brower.setUrl(QUrl(''))

        form = QFormLayout()

        '''折线图/柱状图控件开始'''
        self.selected_label = QLabel()
        self.selected_label.setText('设置图表类型:')
        self.selected_cobox = QComboBox()
        self.selected_cobox.addItems(['Bar(柱状图/条形图)', 'Line(折线/面积图)', 'Pie(饼图)'])
        self.selected_cobox.currentIndexChanged.connect(self.selected_cobox_change)

        self.title_label = QLabel()
        self.title_label.setText('设置标题:')
        self.title_text = QLineEdit()
        self.title_text.setPlaceholderText('请输入图表标题(最大长度10)')
        self.title_text.setMaxLength(10)

        self.subtitle_label = QLabel()
        self.subtitle_label.setText('设置副标题:')
        self.subtitle_text = QLineEdit()
        self.subtitle_text.setPlaceholderText('请输入图表副标题(最大长度20)')
        self.title_text.setMaxLength(20)

        self.data_label_x = QLabel()
        self.data_label_x.setText('设置X轴数据:')
        self.data_text_x = QLineEdit()
        self.data_text_x.setPlaceholderText("湖北, 四川, 重庆, 河北, 云南")
        self.data_text_x.setMaxLength(1000)

        self.data_label_y1_name = QLabel()
        self.data_label_y1_name.setText('设置Y1轴标签:')
        self.data_text_y1_name = QLineEdit()
        self.data_text_y1_name.setPlaceholderText("请输入Y1轴标签")

        self.data_label_y1 = QLabel()
        self.data_label_y1.setText('设置Y1轴数据:')
        self.data_text_y1 = QLineEdit()
        self.data_text_y1.setPlaceholderText("34500, 3000, 3218, 2890, 50023")
        self.data_text_y1.setMaxLength(1000)

        self.data_label_y2_name = QLabel()
        self.data_label_y2_name.setText('设置Y2轴标签:')
        self.data_text_y2_name = QLineEdit()
        self.data_text_y2_name.setPlaceholderText("请输入Y2轴标签")

        self.data_label_y2 = QLabel()
        self.data_label_y2.setText('设置Y2轴数据:')
        self.data_text_y2 = QLineEdit()
        self.data_text_y2.setPlaceholderText("1200, 100, 300, 130, 1004")
        self.data_text_y2.setMaxLength(1000)
        '''折线图/柱状图控件结束'''

        '''饼图控件开始'''
        self.pie_table_label = QLabel()
        self.pie_table_label.setText('设置标题:')
        self.pie_table_label.setVisible(False)
        self.pie_table_text = QLineEdit()
        self.pie_table_text.setPlaceholderText('请输入标题')
        self.pie_table_text.setVisible(False)

        self.pie_data_label = QLabel()
        self.pie_data_label.setText('设置饼图数据:')
        self.pie_data_label.setVisible(False)
        self.pie_data_text = QLineEdit()
        self.pie_data_text.setPlaceholderText("华为:35,三星:59")
        self.pie_data_text.setVisible(False)

        self.pie_radius = QLabel()
        self.pie_radius.setText('设置数据显示比例:')
        self.pie_radius.setVisible(False)
        self.pie_radius_text = QLineEdit()
        self.pie_radius_text.setPlaceholderText('65%')
        self.pie_radius_text.setVisible(False)

        self.pie_radius_cle = QLabel()
        self.pie_radius_cle.setText('设置圆环空心比例:')
        self.pie_radius_cle.setVisible(False)
        self.pie_radius_text_cle = QLineEdit()
        self.pie_radius_text_cle.setPlaceholderText('60%')
        self.pie_radius_text_cle.setVisible(False)

        '''饼图控件结束'''

        '''公共控件开始'''
        self.save_dir_text = QLineEdit()
        self.save_dir_text.setPlaceholderText('请选择图表保存地址')
        self.save_dir_text.setReadOnly(True)
        self.save_dir_btn = QPushButton()
        self.save_dir_btn.setText('存储路径')
        self.save_dir_btn.clicked.connect(self.save_dir_btn_click)

        self.version = QLabel()
        self.version.setText('<font color="green">公众号:[Python 集中营]</font>')
        self.generate_btn = QPushButton()
        self.generate_btn.setText('生成图表')
        self.generate_btn.clicked.connect(self.generate_btn_click)

        '''公共控件结束'''

        '''折线图/柱状图布局开始'''
        form.addRow(self.selected_label, self.selected_cobox)
        form.addRow(self.title_label, self.title_text)
        form.addRow(self.subtitle_label, self.subtitle_text)
        form.addRow(self.data_label_x, self.data_text_x)
        form.addRow(self.data_label_y1_name,self.data_text_y1_name)
        form.addRow(self.data_label_y1, self.data_text_y1)
        form.addRow(self.data_label_y2_name,self.data_text_y2_name)
        form.addRow(self.data_label_y2, self.data_text_y2)
        '''折线图/柱状图布局结束'''

        '''柱状图'''
        form.addRow(self.pie_table_label, self.pie_table_text)
        form.addRow(self.pie_radius, self.pie_radius_text)
        form.addRow(self.pie_radius_cle, self.pie_radius_text_cle)
        form.addRow(self.pie_data_label, self.pie_data_text)
        '''柱状图'''

        '''公共布局'''
        form.addRow(self.save_dir_text, self.save_dir_btn)
        form.addRow(self.version, self.generate_btn)
        '''公共布局'''

        hbox = QHBoxLayout()
        hbox.addWidget(self.brower)
        hbox.addSpacing(10)
        hbox.addLayout(form)
        self.setLayout(hbox)

    def save_dir_btn_click(self):
        directory = QFileDialog.getExistingDirectory(self, "选取文件夹", self.cwd)
        self.save_dir_text.setText(directory)

    def selected_cobox_change(self):
        selected = self.selected_cobox.currentText().strip()
        print(selected)
        if selected == 'Line(折线/面积图)' \
                or selected == 'Bar(柱状图/条形图)':

            '''显示控件'''
            self.title_label.setVisible(True)
            self.title_text.setVisible(True)

            self.subtitle_label.setVisible(True)
            self.subtitle_text.setVisible(True)

            self.data_label_x.setVisible(True)
            self.data_text_x.setVisible(True)

            self.data_label_y1.setVisible(True)
            self.data_text_y1.setVisible(True)

            self.data_label_y2.setVisible(True)
            self.data_text_y2.setVisible(True)

            self.data_label_y1_name.setVisible(True)
            self.data_text_y1_name.setVisible(True)

            self.data_label_y2_name.setVisible(True)
            self.data_text_y2_name.setVisible(True)

            '''隐藏控件'''
            self.pie_table_label.setVisible(False)
            self.pie_table_text.setVisible(False)

            self.pie_data_label.setVisible(False)
            self.pie_data_text.setVisible(False)

            self.pie_radius.setVisible(False)
            self.pie_radius_text.setVisible(False)

            self.pie_radius_cle.setVisible(False)
            self.pie_radius_text_cle.setVisible(False)
        elif selected == 'Pie(饼图)':

            '''隐藏控件'''
            self.title_label.setVisible(False)
            self.title_text.setVisible(False)

            self.subtitle_label.setVisible(False)
            self.subtitle_text.setVisible(False)

            self.data_label_x.setVisible(False)
            self.data_text_x.setVisible(False)

            self.data_label_y1.setVisible(False)
            self.data_text_y1.setVisible(False)

            self.data_label_y2.setVisible(False)
            self.data_text_y2.setVisible(False)

            self.data_label_y1_name.setVisible(False)
            self.data_text_y1_name.setVisible(False)

            self.data_label_y2_name.setVisible(False)
            self.data_text_y2_name.setVisible(False)

            '''显示控件'''
            self.pie_table_label.setVisible(True)
            self.pie_table_text.setVisible(True)

            self.pie_data_label.setVisible(True)
            self.pie_data_text.setVisible(True)

            self.pie_radius.setVisible(True)
            self.pie_radius_text.setVisible(True)

            self.pie_radius_cle.setVisible(True)
            self.pie_radius_text_cle.setVisible(True)

    def generate_btn_click(self):

        selected = self.selected_cobox.currentText().strip()
        if selected == 'Pie(饼图)':
            pie_table_text = self.pie_table_text.text().strip()
            print(pie_table_text)
            pie_data_text_list = self.pie_data_text.text().strip().split(",")
            print(pie_data_text_list)
            list_data = []

            for str_ in pie_data_text_list:
                d_list = str_.split(":")
                tuple_ = (d_list[0],) + (int(d_list[1]),)
                list_data.append(tuple_)

            print(list_data)

            pie_radius_text = self.pie_radius_text.text()
            print(pie_radius_text)
            pie_radius_text_cle = self.pie_radius_text_cle.text()
            print(pie_radius_text_cle)

            pie = Pie()

            pie.add(
                series_name=pie_table_text,
                data_pair=list_data,
                radius=[pie_radius_text_cle, pie_radius_text],
                rosetype='radius'
            )

            pie.set_series_opts(label_opts=options.LabelOpts(formatter='{b}:{d}%'))

            pie.set_global_opts(title_opts=options.TitleOpts(title=pie_table_text))

            html_file_path = self.save_dir_text.text().strip() + '/' + datetime.now().strftime("%Y%m%d%H%M%S") + '.html'

            print(html_file_path)

            pie.render(html_file_path)

            self.brower.setUrl(QUrl(html_file_path))

        elif selected == 'Bar(柱状图/条形图)':
            title = self.title_text.text().strip()
            subtitle = self.subtitle_text.text().strip()
            data_x = list(self.data_text_x.text().strip().split(","))
            data_y1 = list(self.data_text_y1.text().strip().split(","))
            data_y2 = list(self.data_text_y2.text().strip().split(','))
            bar = Bar()
            bar.add_xaxis(data_x)
            bar.add_yaxis(self.data_text_y1_name.text().strip(), data_y1)
            bar.add_yaxis(self.data_text_y2_name.text().strip(), data_y2)

            bar.set_global_opts(
                title_opts=options.TitleOpts(title=title, subtitle=subtitle),
                toolbox_opts=options.ToolboxOpts())

            bar.set_series_opts(
                label_opts=options.LabelOpts(is_show=False),
                markpoint_opts=options.MarkPointOpts(data=[
                    options.MarkPointItem(type_='min', name='最小值'),
                    options.MarkPointItem(type_='max', name='最大值')
                ]))
            html_file_path = self.save_dir_text.text().strip() + '/' + datetime.now().strftime("%Y%m%d%H%M%S") + '.html'
            print(html_file_path)
            bar.render(html_file_path)
            self.brower.setUrl(QUrl(html_file_path))
        elif selected == 'Line(折线/面积图)':
            title = self.title_text.text().strip()
            subtitle = self.subtitle_text.text().strip()
            data_x = list(self.data_text_x.text().strip().split(","))
            data_y1 = list(self.data_text_y1.text().strip().split(","))
            data_y2 = list(self.data_text_y2.text().strip().split(','))
            line = Line()
            # 3. 关联数据
            line.add_xaxis(data_x)

            line.add_yaxis(self.data_text_y1_name.text().strip(), data_y1,
                           is_smooth=True)

            line.add_yaxis(self.data_text_y2_name.text().strip(), data_y2, markpoint_opts=options.MarkPointOpts(
                data=[options.MarkPointItem(type_='min', name='最小值')]
            ))

            line.set_series_opts(markline_opts=options.MarkLineOpts(
                data=[options.MarkPointItem(type_='average', name='平均值'),
                      options.MarkPointItem(type_='max', name='最大值')]
            ))

            line.set_global_opts(title_opts=options.TitleOpts(title=title, subtitle=subtitle))

            html_file_path = self.save_dir_text.text().strip() + '/' + datetime.now().strftime("%Y%m%d%H%M%S") + '.html'
            print(html_file_path)
            line.render(html_file_path)
            self.brower.setUrl(QUrl(html_file_path))

以上就是基于PyQt5制作一个数据图表生成器的详细内容,更多关于PyQt5数据图表生成的资料请关注我们其它相关文章!

(0)

相关推荐

  • Python使用plotly绘制数据图表的方法

    导语:使用 python-plotly 模块来进行压测数据的绘制,并且生成静态 html 页面结果展示. 不少小伙伴在开发过程中都有对模块进行压测的经历,压测结束后大家往往喜欢使用Excel处理压测数据并绘制数据可视化视图,但这样不能很方便的使用web页面进行数据展示.本文将介绍使用python-plotly模块来进行压测数据的绘制,并且生成静态html页面方便结果展示. Plotly简介 Plotly是一款使用JavaScript开发的制图工具,提供了与主流数据分析语言交互的API(如:Pyt

  • python实现数据图表

    平时压力测试,生成一些数据后分析,直接看 log 不是很直观,前段时间看到公司同事分享了一个绘制图表python 模块 : plotly, 觉得很实用,利用周末时间熟悉下. plotly plotly 主页 : https://plot.ly/python/ 安装 在 ubuntu 环境下,安装 plotly 很简单 python 版本2.7+ $ sudo pip install plotly 绘图 在 plotly 网站注册后,可以直接将生成的图片保存到网站上,便于共享保存. 这里使用离线的

  • Python读取Excel数据并生成图表过程解析

    一.需求背景 自己一直在做一个周基金定投模拟,每周需要添加一行数据,并生成图表.以前一直是用Excel实现的.但数据行多后,图表大小调整总是不太方便,一般只能通过缩放比例解决. 二.需求实现目标 通过Python程序读取Excel文件中的数据,生成图表,最好将生成图表生成至浏览器页面,后期数据多之后,也能自动缩放,而不会出现显示不全问题. 三.需求实现代码 # 调用本地echarts.min.js 文件 from pyecharts.globals import CurrentConfig Cu

  • Python数据分析:手把手教你用Pandas生成可视化图表的教程

    大家都知道,Matplotlib 是众多 Python 可视化包的鼻祖,也是Python最常用的标准可视化库,其功能非常强大,同时也非常复杂,想要搞明白并非易事.但自从Python进入3.0时代以后,pandas的使用变得更加普及,它的身影经常见于市场分析.爬虫.金融分析以及科学计算中. 作为数据分析工具的集大成者,pandas作者曾说,pandas中的可视化功能比plt更加简便和功能强大.实际上,如果是对图表细节有极高要求,那么建议大家使用matplotlib通过底层图表模块进行编码.当然,我

  • Python数据可视化 pyecharts实现各种统计图表过程详解

    1.pyecharts介绍 Echarts是一款由百度公司开发的开源数据可视化JS库,pyecharts是一款使用python调用echarts生成数据可视化的类库,可实现柱状图,折线图,饼状图,地图等统计图表. 2.柱状图 适用场合是二维数据集(每个数据点包括两个值x和y),但只有一个维度需要比较,用于显示一段时间内的数据变化或显示各项之间的比较情况. 优点: 利用柱子的高度,反映数据的差异,肉眼对高度差异很敏感. 缺点: 只适用中小规模的数据集. 柱状图最基本用法 from pyechart

  • python从Oracle读取数据生成图表

    初次学习python,连接Oracle数据库,导出数据到Excel,再从Excel里面读取数据进行绘图,生成png保存出来. 1.涉及到的python模块(模块安装就不进行解释了): import os import cx_Oracle import openpyxl import time import csv import xlrd from matplotlib import pyplot as plt from matplotlib import font_manager 2.连接数据库

  • 基于PyQt5制作一个数据图表生成器

    我的需求:手动配置X轴.Y轴.图表标题等参数自动通过Pyecharts模块生成可视化的html数据图表,并将浏览器图表展示到UI界面上. 制作出图表后的效果展示如下: 另外,生成后的图表结果会使用 html 的形式保存下来. 导入 UI 界面相关的 PyQt5 第三方模块库. from PyQt5.QtCore import * from PyQt5.QtWidgets import * from PyQt5.QtGui import * 若是使用PyQt5的版本是5.10.1以上,则需要单独安

  • 基于PyQt5制作一个gif动态图片生成器

    这个小工具制作的目的是为了将多张图片组合后生成一张动态的GIF图片.设置界面化的操作,只需要将选中的图片导入最后直接生成动态图片. 导入界面相关的第三方库 from PyQt5.QtWidgets import * from PyQt5.QtGui import * 动态图片处理模块 import imageio 应用操作相关库 import sys import os from datetime import datetime 这是用图片生成器生成的一张GIF图片,大家在生成时尽量选择两张大小

  • 基于PyQt5制作一个动态指针时钟

    想实现这样一个功能,然后pyqt5中又没有现成的组件可以使用,于是就想着只能通过绘图的方式来实现.说到绘图的话,turtle框架无疑是最常见的选择,但其实通过pyqt5的QPainter组件也是可以实现的.而且最后呈现出来的效果还是挺漂亮的. 实现思路:通过使用pyqt5的QPainter组件来绘制好时钟的图表,最后通过定时器不断的改变当前当前时间在图表上面的显示位置.这样最终就实现了一个指针时钟在不断的走动的过程. 和前面的UI应用一样,我们用到的UI相关的组件库还是这三个. from PyQ

  • 基于PyQt5制作Excel数据分组汇总器

    在写数据汇总分组工具之前梳理一下需求,要求一:能够将excel的数据展示到列表中.要求二:能够支持按列汇总数据,并且多列分组汇总.要求三:能够预览分组汇总以后的数据,最后将分好组汇总的数据保存到新的excel数据文件中. 主要使用到第三方python模块有下面这些,和前面几个 PyQt5 应用不同的是这次增加了一个样式模块 qdarkstyle ,通过最后将这个模块直接加入到 QApplication 中就可以显示成黑色酷酷的应用了.这个样式我个人是比较喜欢的... '''应用操作库''' im

  • 基于PyQT5制作一个课堂点名系统

    刷抖音的时候发现一个老师在用的课堂点名系统.用PyQt5实现了一下同款,导入学生姓名,测试了一下完美运行. 操作效果展示: 完整源代码块还是放在了文章的最后面 使用的时候准备好学生姓名的文件,使用导入数据的按钮直接导入就可以开始点名了.新建一个文本文档,将姓名设置设置好,姓名文件示例如下. 使用系统库或者第三方库都比较常规,这里就不一一介绍了. from PyQt5.QtWidgets import * from PyQt5.QtGui import * from PyQt5.QtCore im

  • 基于PyQT5制作一个二维码生成器

    个性化二维码的exe桌面应用的获取方式我放在文章最后面了,注意查收.通过执行打包后的exe应用程序可以直接运行生成个性化二维码. 开始之前先来看一下通过二维码生成器是如何生成个性化二维码的. 其中使用的python包和之前的GUI应用制作使用的模块是一样的. # -*- coding:utf-8 -*- import os import sys from PyQt5.QtWidgets import * from PyQt5.QtGui import * from PyQt5.QtCore im

  • 基于PyQt5制作一个windows通知管理器

    前几天看到一个python框架win10toast,它可以用来做windows的消息通知功能.通过设定通知的间隔时间来实现一些事件通知的功能,比如可以可以提醒一头扎进代码编写过程的我们按时喝水. 界面布局采用的依旧是pyqt5的ui设计,使用界面化直接设置好想要提示的内容和时间就可以给我们定时的发通知了. UI相关的部分的还是这几个常用的组件包. from PyQt5.QtGui import * # UI 界面相关 from PyQt5.QtCore import * # 核心组件包 from

  • 基于PyQT5制作一个敏感词检测工具

    设计思路:根据敏感词库文件筛选,查看输入的文本中是否包含敏感词汇.从而过滤出相关的敏感词. 导入应用相关的模块. import os import logging import sys 导入UI界面相关的模块. from PyQt5.QtWidgets import QApplication,QWidget,QVBoxLayout,QTextEdit,QGridLayout,QLineEdit,QPushButton,QFileDialog from PyQt5.QtGui import QIc

  • 基于PyQT5制作一个桌面摸鱼工具

    目录 前言 按键功能控制 主要功能 核心代码 前言 现在我能一整天都严肃地盯着屏幕,看起来就像在很认真地工作, 利用摸鱼,打开小说,可实行完美摸鱼,实时保存进度 用PYQT5 Mock一个摸鱼软件 类似于Thief 按键功能控制 q 退出 B 书签功能 F 增加字体大小 Shift F 减小字体 O 打开文件,现在仅仅支持 utf8格式的txt文件 主要功能 FlameLess Window 无边框窗口 一键快速退出 ini 文件读写 右键上下文菜单 核心代码 pyqt 实现功能还是比较顺畅的,

  • 基于PyQt5制作一个猜数字小游戏

    开始之前,直接来看一下实现后的效果.想自己实现或者需要源码的童鞋直接进场... 将PyQt5的相关模块直接导入即可. from PyQt5.QtGui import * from PyQt5.QtCore import * from PyQt5.QtWidgets import * 为了照顾一下新关注的童鞋,这里介绍一下PyQt5的安装,还是采用pip的安装方式. pip install PyQt5 将准备好的样式导入到代码块中. # 主题样式模块引用 from QCandyUi import

随机推荐