Python可视化数据分析-柱状图/折线图

一、前言

使用python编写一个图表生成器,输入各公司的不良品数量,可以在一张图中同时展示数据的柱状图和折线图。

效果如下:

二、基础知识

绘制折线图和柱状图主要使用到了 pyecharts.charts 模块中的 LineBar 类。它们允许用户通过简单的调用方法创建和定制各种样式的折线图和柱状图,从而展示数据分布和趋势。以下是关于这两个类的详细解释:

1)Line类

Line 类用于绘制折线图,展示数据随时间或其他连续变量的变化趋势。以下是一些关键特征和方法 :

创建折线图

from pyecharts.charts import Line

from pyecharts import options as opts 

line_chart = Line()

添加 x 轴和 y 轴数据

line_chart.add_xaxis(["Jan", "Feb", "Mar", "Apr", "May"])
line_chart.add_yaxis("Sales", [150, 230, 224, 300, 290])

设置全局选项

# 设置全局选项,包括标题选项
line_chart.set_global_opts(title_opts=opts.TitleOpts(title="Sales Trend",  # 设置图表标题为 "Sales Trend"subtitle="Monthly Sales",  # 设置图表副标题为 "Monthly Sales"pos_left="left",  # 标题靠左显示pos_top="top",  # 标题距离顶部位置title_textstyle_opts=opts.TextStyleOpts(font_size=20, color="blue")  # 设置标题文本样式)
)

渲染和保存

line_chart.render("line_chart.html")

 效果图:

2) Bar类

Bar 类用于绘制柱状图,适用于展示不同类别或组的数据对比。以下是一些关键特征和方法:

创建柱状图: 

from pyecharts.charts import Bar

bar_chart = Bar()

添加 x 轴和 y 轴数据

bar_chart.add_xaxis(["A", "B", "C", "D", "E"])
bar_chart.add_yaxis("Category 1", [25, 40, 60, 55, 75])

设置柱状图特性

bar_chart.set_series_opts(itemstyle_opts=opts.ItemStyleOpts(color="skyblue")) 

设置全局选项:

bar_chart.set_global_opts(title_opts=opts.TitleOpts(title="Bar Chart")) 

渲染和保存

bar_chart.render("bar_chart.html") 

如何使用 LineBar 绘制并渲染折线图和柱状图: 

from pyecharts.charts import Line, Bar
from pyecharts import options as opts# 创建折线图
line_chart = Line()
line_chart.add_xaxis(["Jan", "Feb", "Mar", "Apr", "May"])
line_chart.add_yaxis("Sales", [150, 230, 224, 300, 290])
line_chart.set_global_opts(title_opts=opts.TitleOpts(title="Sales Trend"))
line_chart.render("line_chart.html")# 创建柱状图
bar_chart = Bar()
bar_chart.add_xaxis(["A", "B", "C", "D", "E"])
bar_chart.add_yaxis("Category 1", [25, 40, 60, 55, 75])
bar_chart.set_global_opts(title_opts=opts.TitleOpts(title="Bar Chart"))
bar_chart.render("bar_chart.html")

三、编写图表生成器
1)功能需求:

        1.输入各公司每月的不良品数据,可以生成柱状图和折线图。

         2.可以自由添加公司和月份。

        3.折线图和柱状图在同一个表中。

2)代码如下:
import sys
import os
from datetime import datetime
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QPushButton, QLabel, QLineEdit, \QMessageBox, QInputDialog
from pyecharts.charts import Line, Bar
from pyecharts import options as opts
import weakref
import webbrowserclass PPMDataInputWidget(QWidget):instances = weakref.WeakSet()  # 使用 WeakSet 存储实例def __init__(self, company_name, parent=None):super().__init__(parent)self.company_name = company_nameself.initUI()PPMDataInputWidget.instances.add(self)  # 添加实例到 WeakSet 中def initUI(self):self.layout = QVBoxLayout()# 添加公司名称标签company_label = QLabel(f"填写 {self.company_name} 的 不良品 数量:")self.layout.addWidget(company_label)self.input_fields = {}  # 存储输入框的字典# 添加输入框用于填写不定数量的月份 不良品 数量self.add_input_field("1月")self.add_input_field("2月")self.add_input_field("3月")# 添加按钮用于增加月份输入框add_month_button = QPushButton("添加月份", self)add_month_button.clicked.connect(self.add_month_input)self.layout.addWidget(add_month_button)# 添加删除按钮delete_button = QPushButton("删除公司", self)delete_button.clicked.connect(self.delete_company)self.layout.addWidget(delete_button)self.setLayout(self.layout)def add_input_field(self, month_name):edit = QLineEdit(self)edit.setPlaceholderText(f"{month_name}  不良品 数量")self.layout.addWidget(edit)self.input_fields[month_name] = editdef add_month_input(self):# 使用对话框获取新的月份名称new_month_name, ok = QInputDialog.getText(self, "添加新月份", "输入新月份名称:")if ok and new_month_name:self.add_input_field(new_month_name)def get_ppm_data(self):ppm_data = []for month_name, edit in self.input_fields.items():ppm_value = float(edit.text().strip())ppm_data.append(ppm_value)return ppm_datadef delete_company(self):reply = QMessageBox.question(self, "确认删除", f"确定要删除 {self.company_name} 吗?",QMessageBox.Yes | QMessageBox.No, QMessageBox.No)if reply == QMessageBox.Yes:self.setParent(None)self.deleteLater()PPMDataInputWidget.instances.discard(self)  # 从 WeakSet 中移除实例class PPMInputApp(QMainWindow):def __init__(self):super().__init__()self.setWindowTitle("填写 不良品 数量")self.setGeometry(100, 100, 600, 400)central_widget = QWidget()self.setCentralWidget(central_widget)layout = QVBoxLayout()central_widget.setLayout(layout)# 添加按钮用于添加新公司和月份add_company_button = QPushButton("添加公司", self)add_company_button.clicked.connect(self.add_company_input_dialog)layout.addWidget(add_company_button)# 添加按钮用于生成所有公司折线图和柱状图并保存为 HTMLgenerate_button = QPushButton("生成所有公司折线图和柱状图并保存为 HTML", self)generate_button.clicked.connect(self.generate_all_charts)layout.addWidget(generate_button)# 添加退出按钮exit_button = QPushButton("退出", self)exit_button.clicked.connect(self.close)layout.addWidget(exit_button)self.widgets = []  # 存储 PPMDataInputWidget 的列表def add_company_widget(self, company_name):widget = PPMDataInputWidget(company_name)self.widgets.append(widget)layout = self.centralWidget().layout()layout.addWidget(widget)def add_company_input_dialog(self):# 使用对话框获取新公司名称new_company_name, ok = QInputDialog.getText(self, "添加新公司", "输入新公司名称:")if ok and new_company_name:self.add_company_widget(new_company_name)def generate_all_charts(self):try:print("Generating all charts...")line_chart = Line()bar_chart = Bar()# 遍历 WeakSet 中的实例,仅处理存在且有效的部件for widget in PPMDataInputWidget.instances:if widget.isVisible() and widget in self.widgets:company_name = widget.company_nameppm_data = widget.get_ppm_data()print(f"Processing widget: {company_name}")# 添加折线图数据line_chart.add_xaxis(list(widget.input_fields.keys()))line_chart.add_yaxis(company_name, ppm_data,markpoint_opts=opts.MarkPointOpts(data=[opts.MarkPointItem(type_="max")]),label_opts=opts.LabelOpts(formatter="{c}"))# 添加柱状图数据bar_chart.add_xaxis(list(widget.input_fields.keys()))bar_chart.add_yaxis(company_name, ppm_data, gap="0%")  # 设置柱子之间的间距为0%并设置柱子宽度# 设置折线图和柱状图的全局选项line_chart.set_global_opts(# title_opts=opts.TitleOpts(title="各公司 不良品 折线图"),# yaxis_opts=opts.AxisOpts(name="数量")yaxis_opts=opts.AxisOpts(name="数量", axislabel_opts=opts.LabelOpts(font_weight="bold")))bar_chart.set_global_opts(# title_opts=opts.TitleOpts(title="各公司 不良品 柱状图"),# yaxis_opts=opts.AxisOpts(name="数量")yaxis_opts=opts.AxisOpts(name="数量", axislabel_opts=opts.LabelOpts(font_weight="bold")))# 叠加折线图和柱状图并保存为 HTML 文件overlap_chart = line_chart.overlap(bar_chart)# overlap_chart.set_global_opts(#     title_opts=opts.TitleOpts(title="折线图和柱状图")# )# 生成 HTML 文件路径timestamp = datetime.now().strftime("%Y%m%d%H%M%S")html_file_name = f"all_companies_PPM_{timestamp}.html"html_file_path = os.path.join(os.getcwd(), html_file_name)# 渲染并打开 HTML 文件overlap_chart.render(html_file_path)print(f"生成所有公司的 不良品 折线图和柱状图 HTML 文件:{html_file_path}")webbrowser.open(f"file://{html_file_path}", new=2)except Exception as e:print(f"Error occurred during chart generation: {e}")if __name__ == '__main__':app = QApplication(sys.argv)window = PPMInputApp()window.show()sys.exit(app.exec_())
3)主要功能和结构解析:
  1. PPMDataInputWidget 类

    • 用于创建一个 QWidget 子类,用于输入和展示单个公司的产品不良品数量。
    • 每个实例对应一个公司的数据输入界面。
    • 使用 QVBoxLayout 进行布局管理,包括输入框、添加月份按钮和删除按钮。
    • add_input_field 方法用于添加新的月份输入框。
    • get_ppm_data 方法用于获取输入的不良品数量数据。
    • delete_company 方法用于删除当前公司的输入界面。
  2. PPMInputApp 类

    • 主窗口类,继承自 QMainWindow。
    • 包含添加新公司、生成图表和退出等功能按钮。
    • add_company_widget 方法用于在布局中添加新的 PPMDataInputWidget 实例。
    • generate_all_charts 方法用于生成所有公司的折线图和柱状图,并保存为 HTML 文件。
  3. 关键点解释

    • PPMInputApp 中,通过点击按钮添加新公司,每个公司对应一个 PPMDataInputWidget 实例,用于填写产品不良品数据。
    • 点击生成图表按钮时,遍历所有 PPMDataInputWidget 实例,获取数据并使用 Pyecharts 创建折线图和柱状图。
    • 折线图和柱状图数据使用 add_xaxisadd_yaxis 方法添加,同时设置全局选项,如标题和 Y 轴名称等。
    • 最后将折线图和柱状图叠加在一起,并保存为 HTML 文件,通过 webbrowser.open 打开该文件。
4)打包成exe

 在使用auto-py-to-exe或者Pyinstaller打包程序时,容易报错缺少map_filename.json或者直接缺失pyecharts包。我们在打包时,可以将文件夹一起打包:

pyinstaller --add-data="E:\anaconda3\envs\yolov5\Lib\site-packages\pyecharts;pyecharts" -F -w test.py

结果: 

5)运行

填好数据的效果如下:

 可以点击HTML查看,或者直接下载exe使用。

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

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

相关文章

完整、免费的把pdf转word文档

在线工具网 https://www.orcc.online/pdf 支持pdf转word,免费、完整、快捷 登录网站 https://orcc.online/pdf 选择需要转换的pdf文件: 等待转换完成 点击蓝色文件即可下载 无限制,完整转换。

动态IP与静态IP的区别,你选对了吗?

在互联网世界中,IP地址是每台设备在网络上的唯一标识。这些地址可以是动态的,也可以是静态的。对于非专业人士来说,理解这两者之间的区别可能会有些困难。本文旨在深入探讨动态IP和静态IP的主要差异,帮助读者根据自己的需求做出明…

Golang | Leetcode Golang题解之第37题解数独

题目: 题解: func solveSudoku(board [][]byte) {var line, column [9][9]boolvar block [3][3][9]boolvar spaces [][2]intfor i, row : range board {for j, b : range row {if b . {spaces append(spaces, [2]int{i, j})} else {digit : b - 1line…

docker网路和主机通讯问题

#注 1,安装docker和启动容器服务的时候如果防火墙处于开启状态,那么重启docker里面的容器的时候必须开启防火墙,否则会出现iptable错误; 2,linux开启防火墙会导致主机和docker网络之间单向通讯,主机可以访…

一周IT资讯

又降了?运维4月平均月薪1W6? 薪资作为大部分人的主要收入来源,是每个人最关注的话题之一。 最近,小编搜索了近半年的运维薪资趋势,看看你的钱包缩水了没? *数据来自看准网 据了解,运维2024年…

单链表详解(无哨兵位),实现增删改查

1.顺序表对比单链表的缺点 中间或头部插入时,需要移动数据再插入,如果数据庞大会导致效率降低每次增容就需要申请空间,而且需要拷贝数据,释放旧空间增容造成浪费,因为一般都是以2倍增容 2.链表的基础知识 链表也是线…

LeetCode---128双周赛

题目列表 3110. 字符串的分数 3111. 覆盖所有点的最少矩形数目 3112. 访问消失节点的最少时间 3113. 边界元素是最大值的子数组数目 一、字符串的分数 按照题目要求,直接模拟遍历即可,代码如下 class Solution { public:int scoreOfString(string …

如何使用ArcGIS Pro进行路径分析

路径分析是一种空间分析技术,用于确定两个或多个地点之间最佳路径或最短路径,这里为大家介绍一下在ArcGIS Pro中如何进行路径分析,希望能对你有所帮助。 数据来源 教程所使用的数据是从水经微图中下载的道路数据,除了道路数据&a…

阿里TTl使用管理日志

在管理日志的时候我们需要查看生成日志都是那些人干了那些事,那么怎么在日志上查看这些事情呢,首先呢可以直接使用Slf4j,然后再配置文件里配置一下 #日志文件最大上限 logging.file.max-size100MB #日志文件存储位置 logging.file.path./logs #日志文件…

中颖51芯片学习7. ADC模数转换

中颖51芯片学习7. ADC模数转换 一、ADC工作原理简介1. 概念2. ADC实现方式3. 基准电压 二、中颖芯片ADC功能介绍1. 中颖芯片ADC特性2. ADC触发源(1)**软件触发**(2)**TIMER4定时器触发**(3)**外部中断2触发…

面试: 悲观锁和乐观锁

一、悲观锁的代表是synchronized和Lock 锁 其核心思想是【线程只有占有了锁,才能去操作共享变量,每次只有一个线程占锁成功,获取锁失败的线程,都得停下来等待】线程从运行到阻塞、再从阻塞到唤醒,涉及线程上下文切换&a…

CTFHub(web sql注入)(三)

MYSQL 手工注入 1.判断字段数 输入1 输入2 输入3 得知字段有两个 2.判断注入类型 1 and 1 1 1 and 12 回显错误,说明存在sql注入 3.查看数据库内容 知道字段数量为2后,可以查看数据库位置 1 union select 1,2 使用union select 1,2查看未发现数…

【Java基础】21.重写(Override)与重载(Overload)

文章目录 一、重写(Override)1.方法重写2.方法的重写规则3.Super 关键字的使用 二、重载(Overload)1.方法重载2.重载规则3.实例 三、重写与重载之间的区别 一、重写(Override) 1.方法重写 重写(Override)是指子类定义了一个与其父类中具有相同名称、参…

阿里云OSS 存储对象的注册与使用

目录 一、什么是阿里云OSS 二、 点击免费试用 2.1 选择第一个,点击免费试用 ​编辑 2.2 登录管理控制台 2.3 进入Bucket 2.4、在阿里云网站上的个人中心配置Accesskey,查询accessKeyId和accessKeySecret。 2.5、进入AccssKey管理页面应该会出现下图提示&…

【VI/VIM】基本操作备忘录

简介 新建/打开文件 工作模式 常用命令 移动命令 文本选中 撤销、删除 复制粘贴 替换 缩排 查找 替换 插入 分屏 练习

【动态规划】C++简单多状态dp问题(打家劫舍、粉刷房子、买卖股票的最佳时机...)

文章目录 前言1. 前言 - 理解动态规划算法2. 关于 简单多状态的dp问题2.5 例题按摩师/打家劫舍 3. 算法题3.1_打家劫舍II3.2_删除并获得点数3.3_粉刷房子3.4_买卖股票的最佳时机含冷冻期3.5_买卖股票的最佳时机含手续费3.6_买卖股票的最佳时机III3.7_买卖股票的最佳时机IV 前言…

交换机的种类有哪些?主要都具有哪些作用?

在当今数字化时代,网络已经成为我们生活和工作中不可或缺的一部分。无论是家庭网络还是企业网络,都需要有效的网络设备来实现数据通信和资源共享。而网络交换机作为一种重要的网络设备,扮演着连接和管理网络设备的关键角色。本文将探讨交换机…

开源贡献代码之​探索一下CPython

探索一下Cython 本篇文章将会围绕最近给Apache提的一个feature为背景,展开讲讲CPython遇到的问题,以及尝试自己从0写一个库出来,代码也已经放星球了,感兴趣的同学可以去下载学习。 0.背景 最近在给apache arrow提的一个feature因为…

《TinyLlama: An Open-Source Small Language Model》全文翻译

【Title】 TinyLlama:开源小语言模型 【Abstract】 我们推出了 TinyLlama,这是一个紧凑的 1.1B 语言模型,在大约 1 万亿个令牌上进行了大约 3 个时期的预训练。 TinyLlama 基于 Llama 2(Touvron 等人,2023b&#xff…

VUE项目使用.env配置多种环境以及如何加载环境

第一步,创建多个环境配置文件 Vue CLI 项目默认使用 .env 文件来定义环境变量。你可以通过创建不同的 .env 文件来为不同环境设置不同的环境变量,例如: .env —— 所有模式共用.env.local —— 所有模式共用,但不会被 git 提交&…