一、介绍
1.1 什么是pyqtgraph?
PyQtGraph是Python的图形和用户界面库,它充分利用PyQt和PtSide的高质量的图形表现水平和NumPy的快速科学计算与处理能力,在数学、科学和工程领域都有广泛的应用。 其主要目标是:
-
为数据(绘图,视频等)提供快速可交互式图形显示。
-
提供帮助快速开发应用程序的工具(例如,Qt Designer中使用的属性树)。
PyQtGraph被大量应用于Qt GUI平台(通过PyQt或PySide),因为它的高性能图形和numpy可用于大量数据处理。 特别注意的是,pyqtgraph使用了Qt的GraphicsView框架,它本身是一个功能强大的图形系统; 我们将最优化和简化的语句应用到这个框架中,以最小的工作量实现数据可视化。
支持Linux,Windows和OSX系统
1.2 它可以做什么?
pyqtgraph的核心特征是:
-
基本的2D交互视图中框绘制
-
线和散点图
-
数据可平移/缩放鼠标
-
实时数据的显示和交互的快速绘制
-
图像显示与互动的查找表和电平控制
-
显示所有数据类型(int或float;任何比特深度;RGB,RGBA,或亮度)
-
切片的多维图像任意角度的函数
-
快速更新的视频显示和实时交互
-
三维图形系统(需要Python OpenGL绑定)
-
体积数据的渲染
-
三维表面和散点图
-
网格的等值面生成渲染
-
交互式视口旋转/缩放鼠标
-
更容易编程的基本的3D场景图
-
数据选择/标记和感兴趣的控制区
-
交互标记垂直/水平的地块的位置和区域
-
从图像中选择任意区域的部件和自动切片数据匹配
1.3 例子
PyQtGraph包含一系列可通过运行来访问的示例:
import pyqtgraph.examples
pyqtgraph.examples.run()
运行结果:
这将启动一个启动器并列出可用的示例。 从列表中选择一个项目以查看其源代码,然后双击一个项目以运行该示例。 注意如果你已经用python setup.py开发安装pyqtgraph,那么这些例子就会被错误地提示为top-level module。 在这种情况下,使用导入示例:examples.run()。
1.4 与其他绘图库对比
-
matplotlib:对于绘图而言,pyqtgraph几乎不像matplotlib完整或者成熟,但运行速度更快。 Matplotlib的目标更多是制作出版质量的图形,而pyqtgraph则用于数据采集和分析应用。Matplotlib对于matlab程序员来说更直观。pyqtgraph对python/qt程序员更直观。Matplotlib(据我所知)并不包含许多pyqtgraph的功能,如图像交互,体绘制,参数树,流程图等。
-
pyqwt5:大概和pyqwt5一样快,但对绘图功能来说不完全一样。 pyqtgraph中的图像处理更完整(同样,qwt中没有ROI小部件)。 另外,pyqtgraph是用纯python编写的,所以它比pyqwt更易于移植,pyqwt在开发中经常落后于pyqt(我最初使用pyqwt,但认为在我的项目中依赖它是太麻烦了)。 就像matplotlib一样,pyqwt(据我所知)并不包含很多pyqtgraph的特性,比如图像交互,体积渲染,参数树,流程图等。
二、鼠标交互
大多数使用pyqtgraph数据可视化的应用程序都会生成可交互缩放,平移和使用鼠标配置的小部件。 本节介绍鼠标与这些小部件的交互。
2.1二维图形
在pyqtgraph中,大多数2D可视化遵循以下鼠标交互:
-
左键:与场景中的项目交互(选择/移动对象等)。 如果鼠标光标下没有可移动的物体,那么用左边的按钮拖动就会平移场景。
-
右键拖动:缩放场景。 水平拖动左/右缩放; 向上/向下拖动垂直缩放(尽管某些场景将其x / y缩放比例锁定在一起)。 如果在场景中有x / y轴可以闪动,那么右键拖动轴会影响该轴。
-
右键单击:在大多数情况下单击右键将根据鼠标光标下的对象显示具有各种选项的上下文菜单。
-
中间按钮(或滚轮)拖动:按下滚轮拖动鼠标将始终平移场景(在场景中其他对象阻止左侧平移的情况下,此功能非常有用)。
-
轮旋转:放大和缩小场景。
对于使用右侧或中间按钮拖动很困难的机器(通常是Mac),存在另一种鼠标交互模式。 在此模式下,用鼠标左键拖动可在场景的某个区域上绘制一个框。 按钮释放后,场景将缩放并平移以适合框。 可以在上下文菜单中或通过调用以下方式访问此模式:
pyqtgraph.setConfigOption('leftButtonPan', False)
2.2 上下文菜单
右键单击大多数场景将显示一个上下文菜单,其中包含用于更改场景行为的各种选项。 这个菜单中的一些选项是:
-
数据范围变化时启用/禁用自动缩放
-
将多个视图的轴链接在一起
-
启用禁用每个轴的鼠标交互
-
显式设置可见范围值
菜单中可用的确切项目取决于场景的内容和点击的对象。
2.3 三维图形
3D可视化使用以下鼠标交互:
-
左键拖动:围绕中心点旋转场景
-
中间按钮拖动:通过移动x-y平面内的中央“查看”点来平移场景
-
中间按钮拖动+ CTRL:通过沿z轴移动中央“查看”点来平移场景
-
滚轮旋转:放大/缩小
-
车轮+ CTRL:改变视场角
键盘控制:
-
箭头键围绕中心点旋转,就像拖动鼠标左键一样
三、如何使用pyqtgraph?
这里有几个建议使用pyqtgraph的方法:
-
从交互式shell(python -i,ipython等)
-
显示应用程序的弹出窗口
-
将小部件嵌入到PyQt应用程序中
3.1 使用命令行
PyQtGraph使得从命令行可视化数据变得非常容易。注意:
这个例子就是告诉你有两个主要的函数:pg.plot,pg.image。一个画曲线,一个画图像。
import numpy as np
import pyqtgraph as pg
data = np.random.normal(size=1000)
pg.plot(data, title="Simplest possible plotting example")# data can be a list of values or a numpy array
data = np.random.normal(size=(500,500))
pg.image(data, title="Simplest possible image example")# data can be a list of values or a numpy array
## Start Qt event loop unless running in interactive mode or using pyside.
if __name__ == '__main__':
import sys
if sys.flags.interactive != 1 or not hasattr(QtCore, 'PYQT_VERSION'):
pg.QtGui.QApplication.exec_()
运行结果:
上面的例子将打开一个窗口,显示给定数据的线图。 对pg.plot的调用返回创建的绘图窗口小部件的句柄,从而允许将更多数据添加到同一个窗口。 注意:python提示符中的交互式绘图仅适用于PyQt; 在交互式提示符运行时,PySide不运行Qt事件循环。 如果你想与PySide交互使用pyqtgraph,请参阅'console'示例。
其他例子:
pw = pg.plot(xVals, yVals, pen='r') # plot x vs y in red
pw.plot(xVals, yVals2, pen='b')
win = pg.GraphicsWindow() # Automatically generates grids with multiple items
win.addPlot(data1, row=0, col=0)
win.addPlot(data2, row=0, col=1)
win.addPlot(data3, row=1, col=0, colspan=2)
pg.show(imageData) # imageData must be a numpy array with 2 to 4 dimensions
我们在这里只是展示最基本的用法 - 这些函数接受许多不同的数据格式和选项来自定义数据的外观。
3.2 在应用程序中显示窗口
虽然我认为这种方法有些懒惰,但“懒惰”往往与“高效”无法区分。 这里的方法很简单,就是使用与命令行相同的功能,但是在现有的应用程序中使用。 当我只是想立即获得关于应用程序中数据状态的反馈时,我经常使用它,而无需花时间为其构建用户界面。
3.3 在PyQt应用程序中嵌入小部件
对于认真的应用程序开发人员来说,pyqtgraph中的所有功能都可以通过像其他任何Qt小部件一样嵌入来使用。 更多的重要信息,请参阅:lotWidget
,ImageView
,GraphicsLayoutWidget
和GraphicsView
。 PyQtGraph的小部件可以通过“Promote To ...”功能包含在Designer的ui文件中:
-
Designer中,创建一个QGraphicsView小部件(“Graphics View”类别下的“Display Widgets”)。
-
用鼠标右键单击QGraphicsView并选择““Promote To...”。
-
在“Promoted calss name”下,输入您希望使用的类名称(“PlotWidget”,“GraphicsLayoutWidget”等)。
-
在“Header file”下,输入“pyqtgraph”。
-
点击“Add”,然后点击“Promote”。
有关promoting widgets的更多信息,请参阅设计器文档。“VideoSpeedTest”和“ScatterPlotSpeedTest”示例都演示了如何使用pyui4或pyside-uic编译为.py模块的.ui文件。“designerExample”示例演示从.ui文件动态生成python类(不需要pyuic4 / pyside-uic)。
3.4 PyQt and PySide
PyQtGraph支持两种常用的Qt库python包:PyQt和PySide。 这两个软件包提供了几乎相同的API和功能,但由于各种原因,您可能更喜欢使用一个软件包或其他软件包。 当第一次导入pyqtgraph时,它会通过一下检测来确定使用哪个库:
-
如果PyQt4已经导入,请使用它
-
否则,如果PySide已经导入,就使用它
-
否则,尝试导入PyQt4
-
如果导入失败,请尝试导入PySide。
如果你的系统上已经安装了这两个库,并且你想强制pyqtgraph使用其中一个或者另一个,只需确保它在pyqtgraph之前被导入:
import PySide ## this will force pyqtgraph to use PySide instead of PyQt4
import pyqtgraph as pg
3.5 将PyQtGraph库导入到大型项目中
在编写使用pyqtgraph的应用程序或python包时,通常在系统范围内(或在virtualenv中)安装pyqtgraph,并在应用程序内调用import pyqtgraph。 这样做的主要好处是pyqtgraph是独立于应用程序进行配置的,因此您(或您的用户)可以自由安装较新版本的pyqtgraph,而无需在应用程序中更改任何内容。 这是用python开发时的标准做法。
然而,特别是对于科学应用来说,情况也是如此,即软件是为特定目的而编写的,然后进行存档。如果我们想要确保软件在十年后仍能正常工作,那么最好将应用程序绑定到一个特定版本的pyqtgraph上,并避免导入系统安装的pyqtgraph版本,这可能会更新(可能不兼容)。尤其当应用程序需要对主要版本中可能不存在的pyqtgraph软件包进行特定的修改时,情况如此。
PyQtGraph通过两种机制来促进这种用法。首先,pyqtgraph中的所有内部导入语句都是相对的,它允许将包重命名或用作子包,而不会与系统中其他版本的pyqtgraph产生任何命名冲突(即,pyqtgraph从未在内部将其自身称为“pyqtgraph ”)。其次,可以在 https://github/pyqtgraph/pyqtgraph-core.git 找到一个git树状子目录存储库,它只包含'pyqtgraph /'树状子目录,允许将代码直接克隆为使用它的应用程序的子目录。
基本的方法是将存储库克隆到包中的适当位置。从包中导入pyqtgraph时,一定要使用全名来避免导入任何系统安装的pyqtgraph包。例如,假设一个简单的项目具有以下结构:
my_project/
__init__.py
plotting.py
"""Plotting functions used by this package"""
import pyqtgraph as pg
def my_plot_function(*data):
pg.plot(*data)
要导入特定版本的pyqtgraph,我们将克隆项目中的pyqtgraph-core存储库:
my_project$ git clone https://github/pyqtgraph/pyqtgraph-core.git
然后相应地调整导入语句:
my_project/
__init__.py
pyqtgraph/
plotting.py
"""Plotting functions used by this package"""
import my_project.pyqtgraph as pg # be sure to use the local subpackage
# rather than any globally-installed
# versions.
def my_plot_function(*data):
pg.plot(*data)
使用 git checkout pyqtgraph-core-x.x.x 选择特定版本的存储库,或使用 git pull 从上游拉取pyqtgraph更新(有关更多信息,请参阅git文档)。
对于已经使用git进行代码控制的项目,也可以在你自己的仓库中包含pyqtgraph作为git树状子目录。 这种方法的主要优点是,除了能够从上游存储库中获取pyqtgraph更新之外,还可以将本地pyqtgraph更改提交到项目存储库并向上游推送这些更改:
my_project$ git remote add pyqtgraph-core https://github/pyqtgraph/pyqtgraph-core.git
my_project$ git fetch pyqtgraph-core
my_project$ git merge -s ours --no-commit pyqtgraph-core/core
my_project$ mkdir pyqtgraph
my_project$ git read-tree -u --prefix=pyqtgraph/ pyqtgraph-core/core
my_project$ git commit -m "Added pyqtgraph to project repository"
有关更多信息,请参阅 git subtree 文档。
四、安装
-
根据您的需要,有许多不同的方式来安装pyqtgraph:
$ pip install pyqtgraph
有些用户可能需要调用pip3。 这种方法应该适用于所有平台。
-
要访问最新的功能和bug,请从github复制pyqtgraph:
$ git clone https://github/pyqtgraph/pyqtgraph
现在你可以从源代码安装pyqtgraph:
$ python setup.py install
..或者你可以简单地把pyqtgraph文件夹放置在可导入的地方,比如在另一个项目的根目录中。 PyQtGraph不需要以任何方式“built”或编译。
-
pyqtgraph的软件包还有其他几种形式:
-
Anaconda:
conda install pyqtgraph
-
Debian,Ubuntu和类似的Linux:使用
apt install python-pyqtgraph
或下载在pyqtgraph官网网页顶部的.deb文件。 -
Arch Linux:安装包(感谢 windel)。(https://aur.archlinux/packages.php?ID=62577)
-
Windows:在pyqtgraph官网顶部下载.exe安装程序文件。
五、配置
PyQtGraph依赖于:
-
Python 2.7 or Python 3.x
-
A Qt library such as PyQt4, PyQt5, or PySide
-
numpy
满足这些配置的最简单方法是使用pip或像Anaconda这样的科学Python发行版。
六、Qt 快速教学
几乎所有的PyQtGraph库的图形界面都是由Qt来生成。 Qt的文档写得很好,我们鼓励所有pyqtgraph开发人员熟悉它。 本节的目的是介绍如何使用Qt(使用PyQt或PySide)编写pyqtgraph开发者程序。
6.1 窗口和布局
Qt GUI几乎都是由几个基本组件组成:
-
一个窗口。 这通常由QMainWindow提供,但请注意,如果窗口小部件没有父窗口,只需调用widget.show(),就可以在窗口中显示所有QWidgets。
-
多个QWidget实例,如QPushButton,QLabel,QComboBox等
-
QLayout实例(可选,但强烈鼓励),它可以自动管理窗口小部件的位置,同时允许GUI以可调整的方式调整大小。
PyQtGraph通过提供自己的QWidget子类插入到你的GUI中来适应这个方案。
例如:
from PyQt4 import QtGui # (the example applies equally well to PySide)
import pyqtgraph as pg
## Always start by initializing Qt (only once per application)
app = QtGui.QApplication([])
## Define a top-level widget to hold everything
w = QtGui.QWidget()
## Create some widgets to be placed inside
btn = QtGui.QPushButton('press me')
text = QtGui.QLineEdit('enter text')
listw = QtGui.QListWidget()
plot = pg.PlotWidget()
## Create a grid layout to manage the widgets size and position
layout = QtGui.QGridLayout()
w.setLayout(layout)
## Add widgets to the layout in their proper positions
layout.addWidget(btn, 0, 0) # button goes in upper-left
layout.addWidget(text, 1, 0) # text edit goes in middle-left
layout.addWidget(listw, 2, 0) # list widget goes in bottom-left
layout.addWidget(plot, 0, 1, 3, 1) # plot goes on right side, spanning 3 rows
## Display the widget as a new window
w.show()
## Start the Qt event loop
app.exec_()
运行结果:
更复杂的界面可以使用Qt Designer进行图形化设计,它可以简单的拖拽小部件到窗口中定义其外观。
6.2 命名约定
事实上pyqtgraph中的每个类都是Qt提供的基类的扩展。 在阅读文档时,请记住Qt的所有类都以字母“Q”开头,而pyqtgraph的类没有。 在阅读任何类的方法时,这样通常有助于查看使用了哪些Qt基类,然后查看Qt文档。
大多数Qt的类都定义了很难区别于常规方法的信号。几乎所有由pyqtgraph定义的信号显示都以’sig’开头,表示这些信号不是在Qt级定义。
在大多数情况下,以’Widget’结尾的类都是QWidget的子类,因此可以用作Qt窗口中的GUI元素。 以’Item’结尾的类是QGraphicsItem的子类,只能在QGraphicsView实例(如GraphicsLayoutWidget或PlotWidget)中显示。
6.3 信号、槽和事件
Qt通过执行其事件循环来检测用户交互并对其做出反应。
-
事件循环中发生了什么?
-
我什么时候需要使用QApplication.exec_()?
-
我对事件循环执行有什么控制?(QApplication.processEvents)
6.4 GraphicsView and GraphicsItems
有关Qt GraphicsView体系结构的更多信息:http://qt-project/doc/qt-4.8/graphicsview.html
6.5 坐标系与转换
有关Qt GraphicsView中坐标系的更多信息:http://qt-project/doc/qt-4.8/graphicsview.html#the-graphics-view-coordinate-system
七、在pyqtgraph中绘图
在pyqtgraph中绘制数据有几种基本的方法:
方法 | 描述 |
---|---|
pyqtgraph.plot() | 创建一个显示数据的新图形窗口 |
PlotWidget.plot() | 将一组新数据添加到现有的绘图小部件 |
PlotItem.plot() | 将一组新数据添加到现有的绘图小部件 |
GraphicsLayout.addPlot() | 在网格中添加一个新的图形 |
所有这些方法都接收相同的基本参数,这些参数控制如何绘制数据和显示图形:
-
x - 可选的X数据; 如果未指定,则会自动生成一系列整数。
-
y - Y数据。
-
pen - 绘制绘图线时使用的笔,或者无以禁用线。
-
symbol - 描述用于每个点的符号形状的字符串。 可选地,这也可以是对于每个点具有不同符号的字符串序列。
-
symbolPen - 绘制符号轮廓时使用的笔(或笔序列)。
-
symbolBrush - 填充符号时使用的画笔(或画笔序列)。
-
fillLevel - 填充曲线下面的区域为该Y值。
-
brush - 填充曲线时使用的笔刷。
请参阅“绘图”示例来演示这些参数。
所有上述函数会将返回值给创建它的对象,允许进一步修改绘图和数据。
7.1 建立绘图类
显示绘图数据时有几种类型。 大多数这些类都是自动实例化的,但了解它们是如何组织和相互关联是非常有用的。 PyQtGraph很大程度上基于Qt的GraphicsView框架 - 如果您还不熟悉这一点,那么值得一读(但不是必需的)。 最重要的是:1)Qt GUI由QWidgets组成,2)称为QGraphicsView的特殊小部件用于显示复杂图形,3)QGraphicsItems定义在QGraphicsView中显示的对象。
-
数据类(QGraphicsItem的所有子类)
-
PlotCurveItem
- 显示给定x,y数据的绘图线 -
ScatterPlotItem
- 显示给定x,y数据的点 -
PlotDataItem
- 组合PlotCurveItem和ScatterPlotItem。上面讨论的绘图函数创建了这种类型的对象。
-
-
容器类(QGraphicsItem的子类;包含其他QGraphicsItem对象,必须从GraphicsView中查看)
-
PlotItem
- 包含用于显示数据的ViewBox以及用于显示轴和标题的AxisItems和标签。这是一个QGraphicsItem子类,因此只能在GraphicsView中使用 -
GraphicsLayout
- 显示项目网格的QGraphicsItem子类。 这用于一起显示多个PlotItem。 -
ViewBox
- 一个用于显示数据的QGraphicsItem子类。 用户可以使用鼠标缩放/平移ViewBox的内容。 通常,所有PlotData / PlotCurve / ScatterPlotItems都是在ViewBox中显示的。 -
AxisItem
- 显示轴值,刻度和标签。 最常用于PlotItem。
-
-
容器类(QWidget的子类;可能嵌入在PyQt GUI中)
-
PlotWidget
- 显示一个PlotItem的GraphicsView的子类。 PlotItem提供的大多数方法也可以通过PlotWidget获得。 -
GraphicsLayoutWidget
- 显示单个GraphicsLayoutItem的QWidget子类。 GraphicsLayoutItem提供的大多数方法也可以通过GraphicsLayoutWidget获得。
-
7.2 例子
有关更多信息,请参阅pyqtgraph附带的“plotting”和“PlotWidget”示例。
将x,y数据显示为散点图:
import pyqtgraph as pg
import numpy as np
x = np.random.normal(size=1000)
y = np.random.normal(size=1000)
pg.plot(x, y, pen=None, symbol='o') ## setting pen=None disables line drawing
运行结果:
创建/显示一个绘图小部件,显示三条数据曲线:
import pyqtgraph as pg
import numpy as np
x = np.arange(1000)
y = np.random.normal(size=(3, 1000))
plotWidget = pg.plot(title="Three plot curves")
for i in range(3):
plotWidget.plot(x, y[i], pen=(i,3)) ## setting pen=(i,3) automaticaly creates three different-colored pens
运行结果:
八、显示图像和视频
PyQtGraph将2D numpy数组显示为图像,并提供确定如何在屏幕上的numpy数据类型和RGB值之间进行转换的工具。 如果要显示常用图像和视频文件格式的数据,则需要先使用另一个库(PIL适用于图像和内置numpy转换)加载数据。
显示二维或三维数据最简单的方法是使用pyqtgraph.image()函数:
import pyqtgraph as pg
pg.image(imageData)
该函数将接受任何浮点数或整数数据类型,并显示包含数据的单个ImageView小部件。 此小部件包含用于确定图像数据如何转换为32位RGBa值的控件。 转换分两步进行(两者都是可选的):
-
缩放和偏移数据(通过选择显示的直方图上的黑暗/亮度级别)
-
使用查找表将数据转换为颜色(由渐变编辑器中显示的颜色确定)
如果数据是3D(时间,x,y),则时间轴将显示一个可以设置当前显示帧的滑块。 (如果数据中的坐标轴的排列方式不同,请使用numpy.transpose重新排列它们)
还有其他一些显示图像的方法:
-
ImageView
类也可以直接实例化并嵌入到Qt应用程序中。 -
ImageItem
的实例可以在ViewBox
或GraphicsView
中使用。 -
为了获得更高的性能,请使用
RawImageWidget
。
通过调用setImage()来显示一个新的帧,任何这些类都可以用来显示视频。 为了提高性能,图像处理系统使用scipy.weave生成编译库。 如果您的计算机具有可用的编译器,则编译器将自动尝试根据需要构建它所需的库。 如果失败,则会使用较慢的纯Python方法。
有关更多信息,请参阅上面列出的类和’VideoSpeedTest’,’ImageItem’,’ImageView’和’HistogramLUT’示例。
九、3D图像
PyQtGraph使用OpenGL提供3D场景图系统。 该系统功能强大,但仍处于开发早期阶段。 目前的功能包括:
-
带缩放/旋转控件的3D视图控件(鼠标拖动和滚轮)
-
场景图允许通过每项转换和父/子关系从场景添加/删除项目。
-
三角网格
-
基本网格计算函数:等值面,每顶点法线
-
体积渲染项目
-
网格/轴项目
基本用法示例:
from PyQt4 import QtGui
## build a QApplication before building other widgets
import pyqtgraph as pg
app = QtGui.QApplication([])
pg.mkQApp()
## make a widget for displaying 3D objects
import pyqtgraph.opengl as gl
view = gl.GLViewWidget()
view.show()
## create three grids, add each to the view
xgrid = gl.GLGridItem()
ygrid = gl.GLGridItem()
zgrid = gl.GLGridItem()
view.addItem(xgrid)
view.addItem(ygrid)
view.addItem(zgrid)
## rotate x and y grids to face the correct direction
xgrid.rotate(90, 0, 1, 0)
ygrid.rotate(90, 1, 0, 0)
## scale each grid differently
xgrid.scale(0.2, 0.1, 0.1)
ygrid.scale(0.2, 0.1, 0.1)
zgrid.scale(0.1, 0.2, 0.1)
app.exec_()
运行结果:
十、线,填充和颜色
Qt依靠它的QColor,QPen和QBrush类为所有绘图指定线条和填充样式。 在内部,pyqtgraph使用相同的系统,但也允许许多简写方法指定相同的样式选项。
pyqtgraph中的许多函数和方法接受指定线条样式(笔),填充样式(笔刷)或颜色的参数。 对于大多数这些函数参数,可能会使用以下值:
-
表示颜色的单字符串(b,g,r,c,m,y,k,w)
-
(r,g,b)或(r,g,b,a)元组
-
单灰度值(0.0 - 1.0)
-
(index,maximum)元组,用于自动迭代颜色(请参阅intColor)
-
QColor
-
QPen / QBrush在适当的地方
值得注意的是,使用mkPen()/ mkBrush()函数或使用Qt的QPen和QBrush类可以轻松构建更复杂的笔和画笔:
mkPen('y', width=3, style=QtCore.Qt.DashLine) ## Make a dashed yellow line 2px wide
mkPen(0.5) ## solid grey line 1px wide
mkPen(color=(200, 200, 255), style=QtCore.Qt.DotLine) ## Dotted pale-blue line
有关’QPen’和’PenStyle’的更多线型选项,请参阅Qt文档,更多填充选项请参阅’QBrush’。 颜色也可以使用mkColor(),intColor(),hsvColor()或Qt的QColor类来构建。
10.1 默认背景和前景色
默认情况下,pyqtgraph为其绘图使用黑色背景,而轴,文本和绘图线使用灰色。 这些默认值可以使用pyqtgraph.setConfigOption()来更改:
import pyqtgraph as pg
## Switch to using white background and black foreground
pg.setConfigOption('background', 'w')
pg.setConfigOption('foreground', 'k')
## The following plot has inverted colors
pg.plot([1,4,2,3,5])
运行结果:
请注意,这必须在创建任何小部件之前设置
十一、交互式数据选择控件
PyQtGraph包含图形项目,允许用户选择和标记数据区域。
11.1 线性选择和标记
两个类允许标记和选择一维数据:LinearRegionItem
和InfiniteLine
。 第一个类LinearRegionItem
可以添加到任何ViewBox
或PlotItem
中,以标记水平或垂直区域。 该区域可以拖动,边界边缘可以独立移动。 第二类InfiniteLine
通常用于标记沿x或y轴的特定位置。 这些可能会被用户拖动。
11.2 二维选择和标记
要从图像中选择2D区域,pyqtgraph使用ROI
类或其任何子类。 默认情况下,ROI只是显示一个矩形,可以由用户移动以标记特定区域(通常这将是图像的区域,但这不是必需的)。 为了允许ROI被调整大小或旋转,有几种方法可以添加可由用户拖动的句柄(addScaleHandle
,addRotateHandle
等)。 这些手柄可以放置在相对于ROI的任何位置,并且可以在任意中心点周围缩放/旋转ROI。 有几个ROI子类具有各种形状和交互模式。
要使用ROI和ImageItem自动提取图像数据的区域,请使用ROI.getArrayRegion
。 ROI类使用affineSlice
函数来执行此提取。
ROI也可以用作移动/旋转/缩放场景中的项目的控件,类似于大多数vetctor图形编辑应用程序。
有关更多信息,请参阅ROITypes示例。
十二、导出
PyQtGraph为所有2D图形提供各种导出格式。 有关3D图形,请参阅下面的导出3D图形。
12.1 从GUI导出
右键单击图形,然后从上下文菜单中选择“导出”,即可导出任何2D图形。 这将显示用户必须在其中输出的导出对话框:
-
选择要导出的项目(或整个场景)。 选择一个项目将使该项目在原始图形窗口中被加亮(但这个hilight将不会显示在导出的文件中)。
-
选择导出格式。
-
更改任何所需的导出选项。
-
单击“导出”按钮。
12.2 导出口格式
-
图像 - PNG是默认格式。 支持的确切图像格式集取决于您的Qt库。 但是,常见的格式如PNG,JPG和TIFF几乎总是可用的。
-
SVG - 作为SVG导出的图形可以与Inkscape和Adobe Illustrator一起使用。 对于高质量的SVG导出,请使用PyQtGraph 0.9.3或更高版本。 这是从PyQtGraph生成发布图形的首选方法。
-
CSV - 将绘制的数据导出为CSV。 此导出器仅在选择PlotItem导出时才有效。
-
Matplotlib - 此导出器打开一个新窗口,尝试使用matplotlib(如果可用)重新绘制数据。 请注意,某些图形功能要么未针对此导出器实现,要么在matplotlib中不可用。 此导出器仅在选择PlotItem导出时才有效。
-
打印机 - 导出到操作系统的打印服务。 此出口商是为了完整性而提供的,但由于Qt打印系统的问题而得不到很好的支持。
12.3 从API导出
要以编程方式导出文件,请按照以下示例操作:
import pyqtgraph as pg
import pyqtgraph.exporters
# generate something to export
plt = pg.plot([1,5,2,4,3])
# create an exporter instance, as an argument give it
# the item you wish to export
exporter = pg.exporters.ImageExporter(plt.plotItem)
# set export parameters if needed
exporter.parameters()['width'] = 100 # (note this also affects height parameter)
# save to file
exporter.export('fileName.png')
运行结果:
12.4 导出3D图形
上述导出功能尚不适用于3D图形。 但是,可以使用QGLWidget.grabFrameBuffer或QGLWidget.renderPixmap从GLViewWidget生成图像:
glview.grabFrameBuffer().save('fileName.png')
有关更多信息,请参阅Qt文档。
十三、快速GUI原型设计
[只是一个概述; 文件尚未完成]
PyQtGraph提供了一些常用于工程和科学应用的强大功能。
13.1 Parameter Trees
参数树系统提供了一个窗口小部件,显示一个可修改值的树,类似于大多数GUI编辑器应用程序中使用的树。 这允许用户以相对较少的编程工作来控制大量变量。 该系统还提供被控制数据和控制它的用户界面(模型/视图架构)之间的分离。 可以将参数分组/嵌套到任何深度,并且可以通过Parameter和ParameterItem的子类化来构建自定义参数类型。
有关更多信息,请参阅 parametertree documentation。
13.2 可视化编程流程图
PyQtGraph的流程图提供了一个类似于概念的可视化编程环境,LabView功能模块被添加到流程图中并通过电线连接以定义更复杂和任意可配置的算法。 pyqtgraph包含少量预定义模块(称为节点),但大多数流程图开发人员都希望定义自己的节点库。 从本质上讲,节点只不过是1)Python功能2)输入/输出终端列表,3)可选小部件为节点提供控制面板。 节点可以通过其终端发送/接收任何类型的Python对象。
有关详细信息,请参阅flowchart documentation和流程图示例。
13.3 图形画布
Canvas是一个系统,旨在允许用户向2D画布添加/删除项目,类似于大多数矢量图形应用程序。 可以翻译/缩放/旋转项目,每个项目可以定义自己的自定义控制界面。
13.4 可停靠的小部件
dockarea系统允许用户界面的设计,用户界面可以在运行时由用户重新排列。 码头可以移动,调整大小,堆叠和撕掉主窗口。 这在原理上与Qt内置的对接系统类似,但提供了更确定的对接放置API(在Qt中,以编程方式生成复杂的对接布置非常困难)。 此外,Qt的底座设计用作窗户外缘周围的小面板。 PyQtGraph的底座是在整个窗口(或其任何部分)由可停靠组件组成的概念下创建的。
十四、参数树
参数树是用于处理参数的层次结构的系统,同时自动生成一个或多个GUI以显示参数并与参数交互。 例如,在用户界面设计应用程序中常见这一特征,该应用程序显示每个小部件的可编辑属性列表。 参数通常具有名称,数据类型(int,float,string,color等)以及与数据类型匹配的值。 参数可以被分组和嵌套以形成层次结构,并且可以被子类化以提供自定义行为和显示窗口小部件。
PyQtGraph的参数树系统与Qt的某些组件使用的模型 - 视图架构的工作方式类似:参数是纯粹的数据处理类,独立于任何图形界面而存在。 ParameterTree是一个窗口小部件,它自动生成一个图形界面,表示参数对象层次结构的状态,并允许用户编辑该层次结构中的值。 数据(模型)和图形界面(视图)的这种分离允许相同的数据以多种不同的方式被多次表示。
有关更多信息,请参阅pyqtgraph附带的'parametertree'示例和API参考
-
ParameterTree API参考
-
Parameter
-
ParameterTree
-
Built-in Parameter Types
-
ParameterItem
-
十五、使用流程图进行可视化编程
PyQtGraph的流程图提供了一个类似于概念的可视化编程环境,LabView功能模块被添加到流程图中并通过电线连接以定义更复杂和任意可配置的算法。 pyqtgraph包含少量预定义模块(称为节点),但大多数流程图开发人员都希望定义自己的节点库。 从本质上讲,节点只不过是1)python功能2)输入/输出终端列表,以及3)为节点提供控制面板的可选小部件。 节点可以通过其终端发送/接收任何类型的Python对象。
流程图的一个主要限制是在流程图中没有用于循环的机制。 (但是单个节点可能包含循环(它们可能包含任何Python代码),并且整个流程图可以在循环内执行)。
在流程图中有两种不同的执行代码的模式:
-
将数据提供给流程图的输入终端。 此方法较慢,并且在通过流程图时将提供数据的图形表示。 这对于调试很有用,因为它允许用户检查每个终端上的数据并查看流程图中发生异常的位置。
-
调用
Flowchart.process()
。 该方法不更新流程图的显示状态,只要需要就保留每个终端的状态。 另外,忽略对流程图的输出值没有贡献的节点(例如绘图节点)。 该模式允许更快地处理大数据集并避免如果流程图中一次存在太多数据(例如,当通过若干阶段处理图像数据时)可能发生的存储器问题。
有关更多信息,请参阅流程图示例。
API参考:
-
flowchart.Flowchart
-
flowchart.Node
-
flowchart.Terminal
15.1 flowchart.Flowchart
15.2 flowchart.Node
15.3 flowchart.Terminal
15.4 基本用法
流程图在您希望用户可以任意配置的应用程序中具有处理阶段的情况下最有用。 您不必提供带有参数的预定义算法供用户调整,而是提供一组预定义的函数,并允许用户按照自己喜欢的方式排列和连接这些函数。 一个非常常见的例子是在音频/视频处理应用中使用滤波器网络。
首先,您必须确定流程图的输入和输出变量。 创建一个为每个变量定义一个终端的流程图:
## This example creates just a single input and a single output.
## Flowcharts may define any number of terminals, though.
from pyqtgraph.flowchart import Flowchart
fc = Flowchart(terminals={
'nameOfInputTerminal': {'io': 'in'},
'nameOfOutputTerminal': {'io': 'out'}
})
在上面的示例中,每个终端都由定义该终端行为的选项字典定义(有关更多信息和选项,请参阅 Terminal.__init__()
)。 请注意,未键入终端; 任何python对象都可以从一个终端传递到另一个终端。
创建流程图后,将其控件小部件添加到您的应用程序:
ctrl = fc.ctrlWidget()
myLayout.addWidget(ctrl) ## read Qt docs on QWidget and layouts for more information
控件小部件提供了几个功能:
-
显示流程图中包含每个节点的控件窗口小部件的所有节点的列表。
-
通过“流程图”按钮提供对流程图设计窗口的访问。
-
用于将流程图保存/恢复到磁盘的接口。
此时,您的用户可以基于内置节点库生成流程图。 建议为用户提供一组默认的流程图。
剩下的就是通过流程图处理数据。 如上所述,有两种方法可以做到这一点:
-
使用
Flowchart.setInput()
设置输入终端的值,然后使用Flowchart.output()
读取输出终端的值:fc.setInput(nameOfInputTerminal=newValue) output = fc.output() # returns {terminalName:value}
此方法更新流程图设计窗口中显示的所有值,允许用户检查流程图中所有终端的值,并指示处理期间发生的错误的位置。
-
调用
Flowchart.process()
:output = fc.process(nameOfInputTerminal=newValue)
该方法处理数据而不更新任何显示的终端值。 此外,使用display = False调用所有
Node.process()
方法,以请求它们不调用任何自定义显示代码。 这样可以更快速地处理数据并减少内存占用,但Flowchart.process()期间发生的错误对于用户来说将更难以诊断。 因此,建议使用此方法通过已使用方法1测试和调试的流程图进行批处理。
15.5 实现自定义节点
PyQtGraph包含一个内置流程图节点的小型库。 该库旨在涵盖一些最常用的函数,并提供一些更奇特的Node类型的示例。 大多数使用流程图系统的应用程序都会发现内置库不足,因此需要实现自定义Node类。
节点子类至少实现:
-
输入/输出终端列表及其属性
-
一个
process()
函数,它将输入终端的名称作为关键字参数,并返回一个以输出终端的名称为键的dict。
可选地,Node子类可以实现ctrlWidget()方法,该方法必须返回将在流程图控制面板中显示的QWidget(通常包含其他小部件)。 最小的Node子类如下所示:
class SpecialFunctionNode(Node):
"""SpecialFunction: short description
This description will appear in the flowchart design window when the user
selects a node of this type.
"""
nodeName = 'SpecialFunction' # Node type name that will appear to the user.
def __init__(self, name): # all Nodes are provided a unique name when they
# are created.
Node.__init__(self, name, terminals={ # Initialize with a dict
# describing the I/O terminals
# on this Node.
'inputTerminalName': {'io': 'in'},
'anotherInputTerminal': {'io': 'in'},
'outputTerminalName': {'io': 'out'},
})
def process(self, **kwds):
# kwds will have one keyword argument per input terminal.
return {'outputTerminalName': result}
def ctrlWidget(self): # this method is optional
return someQWidget
一些节点实现了相当复杂的控件小部件,但大多数节点遵循一个简单的形式模式:参数名列表和每个参数的单个值(表示为旋转框,复选框等)。 为了简化这一过程, CtrlNode
子类允许您改为定义一个简单的数据结构,CtrlNode将使用该结构自动生成控件小部件。 这用于许多内置库节点(尤其是过滤器)。
节点和终端还有许多其他可选参数 - 是否允许用户添加/删除/重命名终端,是否可以将一个终端连接到许多其他终端或仅连接一个终端等。有关更多信息,请参阅 Node
和 Terminal
类的文档细节。
在实现新的Node子类之后,您很可能希望注册该类,以便它出现在用户可以从中选择的节点菜单中:
import pyqtgraph.flowchart.library as fclib
fclib.registerNodeType(SpecialFunctionNode, [('Category', 'Sub-Category')])
registerNodeType的第二个参数是元组列表,每个元组描述一个菜单位置,其中应显示SpecialFunctionNode。
有关更多信息,请参阅FlowchartCustomNode示例。
15.5.1 调试自定义节点
在设计流程图或自定义节点时,必须使用至少与您要处理的数据具有相同类型和结构的数据来设置流程图的输入(请参阅上面的 processing methods #1)。 使用 Flowchart.setInput()
时,流程图在其设计窗口中显示可视反馈,可以告诉您在任何终端上存在哪些数据以及处理中是否存在错误。 生成错误的节点显示为红色边框。 如果选择节点,将显示其输入和输出值以及节点处理时发生的异常(如果有)。
15.6 使用没有流程图的节点
流程图节点通过将功能与用于配置该功能的GUI组合在一起,在数据处理中实现了非常有用的概括。 即使在流程图的上下文之外,这种概括也是有用的。 例如:
## We defined a useful filter Node for use in flowcharts, but would like to
## re-use its processing code and GUI without having a flowchart present.
filterNode = MyFilterNode("filterNodeName")
## get the Node's control widget and place it inside the main window
filterCtrl = filterNode.ctrlWidget()
someLayout.addWidget(filterCtrl)
## later on, process data through the node
filteredData = filterNode.process(inputTerminal=rawData)
十六、内部 - Qt的GraphicsView的扩展
-
GraphicsView
-
GraphicsScene (鼠标事件)
-
GraphicsObject
-
GraphicsWidget
-
ViewBox
十七、API参考
内容:
-
Global Configuration Options全局配置选项
-
PyQtGraph的助手功能
-
Simple Data Display Functions
-
Color, Pen, and Brush Functions
-
Data Slicing
-
Coordinate Transformation
-
SI Unit Conversion Functions
-
Image Preparation Functions
-
Mesh Generation Functions
-
Miscellaneous Functions
-
-
PyQtGraph的图形项目
-
PlotDataItem
-
PlotItem
-
ImageItem
-
GraphItem
-
ViewBox
-
LinearRegionItem
-
InfiniteLine
-
ROI
-
GraphicsLayout
-
PlotCurveItem
-
ScatterPlotItem
-
IsocurveItem
-
AxisItem
-
TextItem
-
ErrorBarItem
-
ArrowItem
-
FillBetweenItem
-
CurvePoint
-
CurveArrow
-
GridItem
-
ScaleBar
-
LabelItem
-
VTickGroup
-
LegendItem
-
GradientEditorItem
-
TickSliderItem
-
HistogramLUTItem
-
GradientLegend
-
ButtonItem
-
GraphicsObject
-
GraphicsWidget
-
GraphicsItem
-
UIGraphicsItem
-
GraphicsWidgetAnchor
-
-
PyQtGraph的小部件
-
PlotWidget
-
ImageView
-
dockarea module
-
SpinBox
-
GradientWidget
-
HistogramLUTWidget
-
parametertree module
-
ConsoleWidget
-
ColorMapWidget
-
ScatterPlotWidget
-
GraphicsView
-
DataTreeWidget
-
TableWidget
-
TreeWidget
-
CheckTable
-
ColorButton
-
GraphicsLayoutWidget
-
ProgressDialog
-
FileDialog
-
JoystickButton
-
MultiPlotWidget
-
VerticalLabel
-
RemoteGraphicsView
-
MatplotlibWidget
-
FeedbackButton
-
ComboBox
-
LayoutWidget
-
PathButton
-
ValueLabel
-
BusyCursor
-
-
PyQtGraph的3D图形系统
-
GLViewWidget
-
GLGridItem
-
GLSurfacePlotItem
-
GLVolumeItem
-
GLImageItem
-
GLMeshItem
-
GLLinePlotItem
-
GLAxisItem
-
GLGraphicsItem
-
GLScatterPlotItem
-
MeshData
-
-
ColorMap色彩表
-
Parameter Trees
-
ParameterTree API Reference
-
-
QGraphicsScene和鼠标事件
-
GraphicsScene
-
HoverEvent
-
MouseClickEvent
-
MouseDragEvent
-
-
使用流程图进行可视化编程
-
flowchart.Flowchart
-
flowchart.Node
-
flowchart.Terminal
-
Basic Use
-
Implementing Custom Nodes
-
Using Nodes Without Flowcharts
-
17.1 全局配置选项
PyQtGraph有几个全局配置选项,允许您更改其默认行为。 可以使用 setConfigOptions()
和 getConfigOption()
函数访问它们:
选项 | 类型 | 默认 | |
---|---|---|---|
leftButtonPan | bool | True | 如果为True,则在ViewBox上拖动鼠标左键会导致视图被平移。 如果为False,则拖动鼠标左键会绘制一个ViewBox将缩放到的矩形。 |
foreground | See
| ‘d’ | 文本,线条,轴等的默认前景色 |
background | See
| ‘k’ | GraphicsView 的默认背景。 |
antialias | bool | False | 启用抗锯齿功能会导致以平滑边缘绘制线条,但会降低性能。 |
imageAxisOrder | str | ‘col-major’ | 对于“行主要”,图像数据预期以标准行主(行,列)顺序排列。 对于'col-major',图像数据预期以反向列主要(列,行)顺序。 向后兼容性的默认值为“col-major”,但将来可能会发生变化。 |
editorCommand | str or None | None | 用于从ConsoleWidget调用代码编辑器的命令。 |
exitCleanup | bool | True | 尝试解决PyQt和PySide中的一些退出崩溃错误。 |
useWeave | bool | False | 如果可用,使用编织来加速某些操作。 |
weaveDebug | bool | False | 如果编织编译失败,则打印完整错误消息。 |
useOpenGL | bool | False | 在GraphicsView中启用OpenGL。 这会对稳定性和性能产生不可预测的影响。 |
enableExperimental | bool | False | 启用实验功能(好奇的人可以在代码中搜索此密钥)。 |
crashWarning | bool | False | 如果为True,则打印有关可能导致崩溃的情况的警告。 |
1.pyqtgraph.setConfigOptions
(**opts)[source]
设置全局配置选项。
每个关键字参数设置一个全局选项。
2.pyqtgraph.getConfigOption
(opt)[source]
返回单个全局配置选项
更多推荐
pyqtgraph中文文档
发布评论