在一篇论文中,最吸引审稿人目光的莫过于枯燥的文字间精美的图表

在一份项目路演 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 Qt

class 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 = 0

while i

if not self.dictList[i].get(key,None):

self.dictList[i][key] = value

return i

i += 1

newDict = {}

newDict[key] = value

self.dictList.append(newDict)

return i

def 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 -= 1

def 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 result

result.append(response)

return result

def __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 += aItem

return resStr

if __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

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

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

  1. Python 制作动态图表,看全球疫情变化趋势

    作者 | 刘早起早起 责编 | 屠敏 前言 最近国内疫情已经有所好转,但是国外的情况不容乐观,那么怎样用Python去制作动态图表来看全球疫情变化趋势呢?比如下面的国内外疫情发展趋势: 还是全球疫情发 ...

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

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

  3. python echarts数据可视化实战

    python echarts数据可视化 python echarts数据可视化实战 引言 词云分析 柱状图分析 饼图分析 总结 python echarts数据可视化实战 引言 引言 上一章我给大家用 ...

  4. python 3d大数据可视化软件_最受欢迎的大数据可视化软件

    最受欢迎的大数据可视化软件 发布时间:2020-05-26 想像阅读书本一样阅读数据流?这只有在电影中才有可能发生. 在现实世界中,企业必须使用数据可视化工具来读取原始数据的趋势和模式. 大数据可视化 ...

  5. Python数据可视化实战——iris数据集可视化

    首先,这个Python数据可视化实战是在Iris数据集上完成的.所使用的是Python 3环境下的jupyter notebook. 实战中我们需要用到的库包括:pandas , matplotlib ...

  6. 27【源码】数据可视化大屏:基于 Echarts + Python Flask 实现的32-9超宽大屏范例 - 监控指挥中心

    目录 效果展示 1. 效果动图 2. 多种主题效果 一. 确定需求方案 1. 屏幕分辨率 2. 部署方式 二. 整体架构设计 三. 编码实现 (基于篇幅及可读性考虑,此处展示部分关键代码) 1. 前端 ...

  7. 29【源码】数据可视化大屏:基于 Echarts + Python Flask 实现的32-9超宽大屏 - 企业综合信息

    我是 YYDataV数据可视化  专注于 数据可视化大屏,工厂扫码装箱系统 等 我的微信 6550523,多多交流 ~ 本案例为32:9超宽分辨率的大屏. 效果展示 1.动态实时更新数据效果图 2.鼠 ...

  8. python pandas_Python库Pandas数据可视化实战案例

    点击上方"爱好Python的胡同学",选择"星标"公众号 每晚八点,Python干货,不见不散! 数据可视化可以让我们很直观的发现数据中隐藏的规律,察觉到变量之 ...

  9. Python使用tsne进行高维数据可视化实战:二维可视化、三维可视化

    Python使用tsne进行高维数据可视化实战:二维可视化.三维可视化 # 绘制二维可视化图像并添加标签字符函数 def plot_embedding(data, label, title):x_mi ...

最新文章

  1. Cadvisor源码分析监控项
  2. 觉得酒驾处罚太严厉?看看国外的再说吧...
  3. vty 虚拟终端连接 line vty 0 4 和line vty 5 15 区别
  4. Dependency Walker PE模块依赖性分析工具
  5. concurrenthashmap 1.7/1.8
  6. [html] html5中的meta标签http-equiv属性有什么作用?
  7. 上海市名校一年级数学考试附加题,难住学霸
  8. 该内存不能为read
  9. 如何开启电脑远程桌面服务器,远程桌面服务怎么开启
  10. 笔记本的无线网卡驱动服务器,无线网卡驱动,详细教您怎么笔记本无线网卡驱动...
  11. XTU,C语言,Tri-Triangle
  12. OCR--PC单机版车牌识别技术
  13. 蓝牙、红外线与wifi 区别以及不同频段无线电磁波的穿墙和绕过障碍物能力
  14. Exporter介绍与指标数据汇总(完结)
  15. 金庸小说人物知识图谱构建——以《雪山飞狐》为例
  16. 北航计算机学院保研占比,许明杰:CSP助力保研入北航
  17. 基于C90标准的C语言开发工具
  18. 宝塔一个服务器创建多个站点
  19. 蓝魔法师(树形dp)
  20. 申宝投资-指数上周五中阴杀跌

热门文章

  1. [技术发展-8]:高级研修班-人工智能篇-数字化时代下的大数据与人工智能
  2. 9月8日阿里巴巴杭州举办“世界级”年会
  3. 里程计运动模型及标定
  4. XML declaration should precede all document content
  5. ARM官方矩阵乘法库函数arm_mat_mult_q31结果不太对路的问题
  6. IBM任命联想老将陈旭东为大中华区总经理
  7. 高性能Linux服务器构建实战 服务器安全运维
  8. 徐小明是不折不扣的垃圾,根本不会炒股;靠卖书,讲课骗钱!!
  9. 图片格式jpg,gif,png-8,png-24的区别,及其各自的使用场景
  10. 智能机器人在机器人机器人感知与运动控制技术与应用案例