点击上方“编程派”,选择设为“设为星标”

优质文章,第一时间送达!

作者:BuyiXiao

出处:月小水长公众号

在一篇论文中,最吸引审稿人目光的莫过于枯燥的文字间精美的图表。在一份项目路演 ppt 中,酷炫的财务报表往往是打动投资人的最后一剂强心剂

作为数据分析最后也是最直接的一环,数据可视化的重要性不言而喻

数据可视化大致可分为两类,一类是 excel、powerBI 这类不需要写代码的,另一类是需要写代码的;而对于 Python 来说,数据可视化框架,我个人觉得大致可以分为以下两类(推荐程度从高到底)

1、如果对于数据交互性没有特殊要求的话,首推 matplotlib + seaborn ,其中 matplotlib 中成熟而强大的绘图 api 应有尽有,seaborn 相当于调色笔,修改 matplotlib 本身的主题、配色风格等;matplotlib 的另一大优势是可以结合 pandas 快速喂入数据。

2、如果对数据交互性要求高,需要点击图表查看数据,首推 pyecharts;如果还喜欢二次元可爱风的话,可以用 cutecharts, cutecharts 和 pycharts 均基于百度主导的 JavaScript 可视化框架 Echarts。

可以看到,cutecharts 绘制的图表比较 Q(显然不能做正式数据报表和论文图表),当鼠标悬停到天线原理这一列时,会显示出学生 A 和 B 的成绩,但是 cutecharts 生成的是一个 HTML 文件,需要用浏览器打开才能显示图表,而 Python 第三方 GUI 库 PyQt5 实现了浏览器组件 QtWebEngineWidgets,结合 Echarts 的 JavaScript API 就能不打开浏览器实现酷炫的数据交互效果。

实现效果

今天要讲的主题就是使用 PyQt5+Echarts 实现股票数据看板,股票数据采集自网上公开接口,考虑到网易财经历史数据全但有延时,Tushare 数据更新快颗粒度高但调用次数有限制,融合使用网易财经和 Tushare,爬虫这部分代码不是今天的主题,可以跳过,且所有代码均已上传,关注本公众号并在后台回复 股票 即可获得所有代码(包括爬虫+可视化)的下载链接。

界面布局

如上图所示,界面可细分为三大块,左上角的昨日股票涨跌行情饼状图,右上角的展示股票排行榜的 QTabWidget 表格,以及下方的某只股票 Open-Close-High-Low 折线图。上图中,考虑到计算量的问题,饼状图和表格的数据都是直接伪造的,只有股票的折线图数据是真实的。

整个界面继承自 QMainWindow,最外层的布局是竖直布局 QVBoxLayout,它包含界面上部分的 QHBoxLayout 和下方的 QHBoxLayout,并同时设置这两个 QHBoxLayout 的 拉伸因子为 1,这样就能够实现上下部分等分整个界面并大小随界面自适应改变,其语法格式是

vbox = QVBoxLayout()
vbox.addLayout(QHBoxLayout())
vbox.addLayout(QHBoxLayout())
# 第一个参数表示 vbox 中组件的序号,也就是添加顺序
# 第二个参数 表示组件在 vbox 中的权重
vbox.setStretch(0,1)
vbox.setStretch(1,1)

从小的方面来说,左上角和下部分的布局都是 PyQt5 中的 QtWebEngineWidgets 组件,它就像一个浏览器,通过 QtWebEngineWidgets 调用 Echarts 中的 API,就能在 PyQt5 的界面中显示 Echarts 各种各样的的图表。而右上角是一个 QTabWidget 组件,为了减少代码之间的耦合,我单独把它写成一个 RightTableView 类,

# -*- coding: utf-8 -*-
# author:           inspurer(月小水长)
# pc_type           lenovo
# create_time:      2019/12/18 21:54
# file_name:        rightview.py
# github            https://github.com/inspurer
# qq邮箱            2391527690@qq.com
# 微信公众号         月小水长(ID: inspurer)import sys
from PyQt5.QtWidgets import QApplication,QWidget,QVBoxLayout,QTabWidget,QLabel,QTableWidget,QAbstractItemView,QTableWidgetItem
from PyQt5.QtCore import Qtclass RightTableView(QWidget):def __init__(self):super().__init__()self.mainLayout = QVBoxLayout()tabWidgets = QTabWidget()label = QLabel("前一日涨幅排名前十的股票详细信息")tabWidgets.addTab(label, "涨幅排名")label = QLabel("前一日成交量排名前十的股票详细信息")tabWidgets.addTab(label, "成交量排名")tabWidgets.currentChanged['int'].connect(self.tabClicked)   # 绑定标签点击时的信号与槽函数self.mainLayout.addWidget(tabWidgets)self.tableView = QTableWidget()self.table = QTableWidget(self)self.table.setColumnCount(6)self.table.setSelectionBehavior(QAbstractItemView.SelectRows)  # 设置表格的选取方式是行选取self.table.setSelectionMode(QAbstractItemView.SingleSelection)  # 设置选取方式为单个选取self.table.setHorizontalHeaderLabels(["股票代码", "开盘", "收盘",'最高','最低','成交量'])  # 设置行表头self.mainLayout.addWidget(self.table)self.mainLayout.setStretch(0,1)self.mainLayout.setStretch(1,12)self.setLayout(self.mainLayout)self.updateView()def updateView(self):self.table.insertRow(0)stock_code = QTableWidgetItem("1001")stock_code.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)  stock_code.setTextAlignment(Qt.AlignCenter)stock_open = QTableWidgetItem("10.20")  stock_open.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)  stock_open.setTextAlignment(Qt.AlignCenter)stock_close = QTableWidgetItem("10.20")  stock_close.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)  stock_close.setTextAlignment(Qt.AlignCenter)stock_high = QTableWidgetItem("10.20")  stock_high.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) stock_high.setTextAlignment(Qt.AlignCenter)stock_low = QTableWidgetItem("10.20")  stock_low.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)  stock_dealNum.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) stock_dealNum.setTextAlignment(Qt.AlignCenter)self.table.setItem(0, 0, stock_code)self.table.setItem(0, 1, stock_open)self.table.setItem(0, 2, stock_close)self.table.setItem(0, 3, stock_high)self.table.setItem(0, 4, stock_low)self.table.setItem(0, 5, stock_dealNum)def tabClicked(self,index):'''tab 监听事件,在此添加业务逻辑'''print(index)

RightTableView 实现了 tab 的监听,切换不同的 tab 可根据 index 展示不同的数据,因此,在主模块中初始化 RightTableView 类的时候,应当给定 RightTableView 可能用到的所有数据,这样可以避免使用 Signal 信号来进行主模块和 RightTableView 模块的通信。

在主模块中,通过 from rightview import RightTableView
即可引入 RightTableView 布局,其中 rightview 是文件名,RightTableView 是类名,如改行代码爆红(实际上不影响运行),可在项目上右键 Mark Dircectory as -> Sources Root 解决之。

数据驱动

实际上,在三个小布局中,界面上部的两个布局的数据均是伪造的,因为这个数据的采集及计算太过耗时

在 basic 表中,我记录了 5000 支股票的基础信息:股票交易所、股票发行公司、股票代码,上部的两个布局需要这 5000 支股票的整体数据,即 5000 支股票昨日相较于前日的跌涨幅,5000 支股票的跌涨幅度的排名,作为一个客户端软件,我觉得一个操作所能忍受的时延是 3 s 以内,优于接口还有速率限制,粗略计算了一下,这个过程远远超过了 30 s,所以我觉得可行的办法是将这种采集和计算过程部署到服务器,通过设置定时任务执行,客户端每次打开只需要一个简单的 Get 请求即可立即渲染数据。

而下方的股票 Open-Close-High-Low 折线图所需数据的计算量比较小,可直接完成,用户输入股票发行公司,即可返回该公司发行股票的代码,(因为我们一般记住的是股票发行公司而不是股票代码,就行我们往往记住网站的域名而不是 ip 地址),如果数据库中不存在代码该股票的表(表名=发行公司_股票代码),就新建,并抓取指定日期的数据存入该表;如果表存在但是缺少用户想要的数据,则更新数据即可;这样设计的好处是尽可能减少平均操作时延。

再说这个用户输入股票发行公司,即可返回该公司发行股票的代码,乍一看就是一个 key-value 字典,为了减少数据库的操作,在程序初始化过程中,我们需要把 basic 表中的股票数据全部加载进内存,也就是放进字典里,但是由于一个公司可能发现很多股票,但是 Python 内置的字典 一个 key 只能对应一个 value ,我们很容易想到把 value 设计成一个列表,但是这样破环了字典的原子性,假如后面我们新加了一个需要,根据 value 反查 key,也就是说根据股票代码反查股票发行公司,如果设计成列表,这个反查耗时将是巨大的,考虑再三,我在不破坏字典 item 的原子性的前提下,实现了 value 可重复 dict,其本质是一个列表,列表元素为字典,核心思想是把键重复的item分散到不同字典,不过经过封装,对外操作和字典一样,下面是该可重复字典的实现

# -*- coding: utf-8 -*-
# author:           inspurer(月小水长)
# pc_type           lenovo
# create_time:      2019/12/2 12:25
# file_name:        myDict.py
# github            https://github.com/inspurer
# qq邮箱            2391527690@qq.com
# 微信公众号         月小水长(ID: inspurer)class AllowKeyRepeatDict():'''自定义允许键重复的字典其本质是一个列表,列表元素为字典,核心思想是把键重复的item分散到不同字典封装后列表对外操作像字典'''def __init__(self):self.dictList = []def add(self,key,value):length = len(self.dictList)i = 0while i<length:if not self.dictList[i].get(key,None):self.dictList[i][key] = valuereturn ii += 1newDict = {}newDict[key] = valueself.dictList.append(newDict)return idef delete(self,key):''':param key: 根据 key 删除所有 item'''length = len(self.dictList)for i in range(length):response = self.dictList[i].pop(key,None)if not response:break# 清除哪些空容器,注意从后往前删,否则会出现下标越界while length>0:if self.dictList[length-1]=={}:del self.dictList[length-1]length -= 1def query(self,key):''':param key: 查询的健:return: 由于允许键重复,返回形式是一个列表'''result = []length = len(self.dictList)for i in range(length):response = self.dictList[i].get(key,None)if not response:return resultresult.append(response)return resultdef __str__(self):''':return: 打印整个字典'''resStr = ''length = len(self.dictList)if length==0:return '该字典为空'for i in range(length):for k,v in self.dictList[i].items():aItem = 'key:{:<8}value:{:<8}\n'.format(k,v)resStr += aItemreturn  resStrif __name__ == '__main__':app = QApplication(sys.argv)mainWin = RightTableView()mainWin.show()sys.exit(app.exec_())

设计模式

当 QtWebEngineWidgets 需要新建一个图表获取句柄时,它希望屏蔽掉新建的具体细节,我们可以设计一个函数对应一种图表来实现这个功能,但是
我们又不想每次新建图表时去找对应的函数,这个时候可以再设计一个代理函数,告诉这个代理函数我们需要怎样的图表即可获取相应图表的句柄。

# 代理函数
def getOptions(self,type):if type==None or type=='K':return self.createKlines()elif type=='Pie':return self.create_pie(v=[3000,600,5000])# K 图表工具函数
def createKlines(self):overlap = Overlap()for quote in self.quote_data:line = Line(quote['title'])print(quote)line.add('open',quote['date'],quote['open'],is_smooth=True)line.add('close',quote['date'],quote['close'],is_smooth=True)line.add('high',quote['date'],quote['high'],is_smooth=True)line.add('low',quote['date'],quote['low'],is_smooth=True)overlap.add(line)snippet = TRANSLATOR.translate(overlap.options)options = snippet.as_snippet()return options
# 饼图工具函数
def create_pie(self, v):pie = Pie()pie.add("昨日行情",['涨','平','跌'], v, is_label_show=True)snippet = TRANSLATOR.translate(pie.options)options = snippet.as_snippet()return options                           

以上就是本次话题的所有内容,代码开源,关注本公众号并在后台回复 股票 即可获得所有代码。

回复下方「关键词」,获取优质资源

回复关键词「 pybook03」,立即获取主页君与小伙伴一起翻译的《Think Python 2e》电子版

回复关键词「入门资料」,立即获取主页君整理的 10 本 Python 入门书的电子版

回复关键词「m」,立即获取Python精选优质文章合集

回复关键词「book 数字」,将数字替换成 0 及以上数字,有惊喜好礼哦~

题图:pexels,CC0 授权。

好文章,我在看❤️

使用 PyQt5 和 Echarts 打造股票数据看板相关推荐

  1. echarts tab切换_Python 数据可视化实战:使用 PyQt5 和 Echarts 打造股票数据看板

    月小水长一个编码者.思考者在一篇论文中,最吸引审稿人目光的莫过于枯燥的文字间精美的图表在一份项目路演ppt 中,酷炫的财务报表往往是打动投资人的最后一剂强心剂作为数据分析最后也是最直接的一环,数据可视 ...

  2. python制作股票图表怎么看_Python 数据可视化实战:使用 PyQt5 和 Echarts 打造股票数据看板...

    在一篇论文中,最吸引审稿人目光的莫过于枯燥的文字间精美的图表 在一份项目路演 ppt 中,酷炫的财务报表往往是打动投资人的最后一剂强心剂 作为数据分析最后也是最直接的一环,数据可视化的重要性不言而喻 ...

  3. 实践应用|PyQt5制作雪球网股票数据爬虫工具

    点击上方"菜鸟学Python",选择"星标"公众号 超级无敌干货第一时间推给你!!! 最近有盆友需要帮忙写个爬虫脚本,爬取雪球网一些上市公司的财务数据.盆友希望 ...

  4. python在财务中的应用实训报告-实践应用|PyQt5制作雪球网股票数据爬虫工具

    importrequests fromfake_useragentimportUserAgent url= 'https://xueqiu.com' session= requests. Sessio ...

  5. 用flask+echarts打造一个数据可视化大屏幕

    文章目录 1. big_screen项目说明 2. big_screen项目文件布局 3. 四大模块核心代码分析 3.1 数据准备模块 3.2 flask网页服务模块 3.3 网页视图模块 a. 网页 ...

  6. “大数据时代下的地理信息可视化:ECharts地图和数据面板实践“

    数据可视化是一种数据分析技术,它通过将数据转化为图形或图表等可视化方式,以便更好地理解和解释数据.在实际应用中,数据可视化被广泛用于数据监控.业务分析.决策支持等领域.而ECharts是一款优秀的数据 ...

  7. 腾讯TEG团队打造轻量级数据可视化工具——小马BI【强烈推荐大数据行业学习】

    推荐一个BI工具--小马BI 在职场中有一项共识是:数据驱动业务价值.业务在产品.运营.开发.技术支持.销售等环节都有着大量的数据需求, 市面上也出现了很多 BI 可视化工具,但如果能同时具备以下特性 ...

  8. 后羿采集器怎么导出数据_后羿采集器教程:如何采集东方财富网股票数据

    本文介绍如何使用采集器的智能模式,实时采集东方财富网行情中心新三板股票数据 采集工具简介: 后羿采集器是一款基于人工智能技术的网页采集器,只需要输入网址就能够自动识别网页数据,无需配置即可完成数据采集 ...

  9. BI工具对比|Smartbi与亿信ABI两款BI数据看板软件对比

    工欲善其事,必先利其器.随着互联网行业的飞速发展,越来越多的企业意识到BI工具对企业的业务发展有很大的推动作用,使得工作效率更高更强.BI工具作为目前最炙手可热的数据分析工具,在数据分析结果的展示方式 ...

  10. CSS实战---高科技感数据看板(管理层决策大屏演示)

    数据在各种屏幕上的显示,根据岗位的不同,用途也是不一样的,现在比较流行的是大.中.小屏联动的数字化作战体系建设,大屏用于管理决策,中屏用于生产调度,小屏用于作业执行.小屏一般是手机或平板,中屏一般是电 ...

最新文章

  1. 第三课.python编程基础(二)
  2. 【166期推荐】医院中电脑耗材采购该不该归信息科负责?
  3. 全球及中国生物技术产业创新发展模式及十四五应用方向研究报告2021-2027年
  4. 1337:【例3-2】单词查找树
  5. 【千字分析】剑指 Offer 46. 把数字翻译成字符串
  6. ListView smoothScrollToPosition 定位不准笨方法解决
  7. java statement 存储过程_Java+sql server+CallableStatement调用存储过程三种情况 (转)...
  8. 几款4Gb光纤连接产品对比
  9. 重学AS3之基础知识重点记忆
  10. 计算机dos命令大全TXT,dos命令大全常见命令图解
  11. linux学习教程:Vim编辑器和恢复ext4下误删除文件-Xmanager工具
  12. 猫哥教你写爬虫 034--爬虫-BeautifulSoup实践
  13. 梦三国2英霸模式貂蝉攻略(玩大流)
  14. 在tensorflow下进行pip操作时需要注意的地方
  15. uni-app登陆成功跳转到首页后禁止回退到登陆页面
  16. 微信从原版到现在所有界面图片_微信这4张登录界面图,你见过几张?微信老用户都不一定能认全!...
  17. cisp证书含金量如何
  18. 谈谈市面上无线路由器的性能和芯片
  19. 磷酸铁锂电池回收浸出液除铝
  20. C#利用SaveFileDialog实现保存的功能示例

热门文章

  1. 钉钉小程序踩坑:(与微信小程序的区别)
  2. JavaScript菜鸟教程笔记
  3. CAD图纸转BMP格式图片时怎么设置输出色彩?
  4. matlab:蚁群算法原理的实现
  5. matlab 方差,方差分解——matlab 代码
  6. matlab年平均,MATLAB平均每5个元素
  7. Python-科赫雪花(科克曲线)
  8. matlab中如何定义数组,matlab中如何定义一个数组为全局变量?
  9. 3D游戏建模快速制作枪械的几种方法【3Dmax,Zbrush,Maya】
  10. python机械臂仿真_如何用ROS+Rviz+Arbotix控制器仿真为六自由度机械臂建模-工业电子-与非网...