# 1.开始
# 安装
# pip install QCustomPlot2 -i https://pypi.tuna.tsinghua.edu.cn/simple
# 有点matplotlib背景将比较熟悉
# https://www.jianshu.com/u/14fa805306bd和https://blog.csdn.net/wzz953200463/article/details/123856334?spm=1001.2014.3001.5502,https://wendy.blog.csdn.net/?type=blog翻译这几个人博客,上面有理论解释
# 代码地址:https://gitee.com/becld/qcustom-plot2for-python.git
import sys
import math
from PyQt5.QtCore import Qt,QMargins
from PyQt5.QtGui import QPen, QBrush, QColor
from PyQt5.QtWidgets import QApplication, QMainWindow
from QCustomPlot2 import * #先导入PyQt5,不然报错
app = QApplication(sys.argv)
window = QMainWindow()
window.resize(800, 600)
customPlot = QCustomPlot() #相当于pyqt5的一个控件
window.setCentralWidget(customPlot)
customPlot.addGraph() #添加一个曲线图QGraph
x=[]
y=[]
for i in range(101):
x.append(i/50.0-1)
y.append(x[i]**2)
customPlot.graph(0).setData(x,y) #为曲线图添加数据
customPlot.graph(0).setName("第一个示例") #设置曲线图的名字
customPlot.xAxis.setLabel("x") #设置x轴的标签
customPlot.yAxis.setLabel("y")
customPlot.xAxis.setRange(-1,1) #设置x轴的范围为(-1,1)
customPlot.yAxis.setRange(0,1)
# customPlot.axisRect().setAutoMargins(QCP.msNone) #坐标轴到边界的距离,设置为0
customPlot.legend.setVisible(True) #显示图例
customPlot.replot()
window.show()
sys.exit(app.exec_())
# 外观
import sys
import math
from PyQt5.QtCore import Qt,QMargins
from PyQt5.QtGui import QPen, QBrush, QColor,QLinearGradient
from PyQt5.QtWidgets import QApplication, QMainWindow
from QCustomPlot2 import *
app = QApplication(sys.argv)
window = QMainWindow()
window.resize(800, 600)
customPlot = QCustomPlot()
window.setCentralWidget(customPlot)
plotGradient=QLinearGradient() #渐变色
plotGradient.setStart(0, 0)
plotGradient.setFinalStop(0, 350)
plotGradient.setColorAt(0, QColor(80, 80, 80))
plotGradient.setColorAt(1, QColor(50, 50, 50))
# customPlot.setBackground(plotGradient) # 设置背景颜色,整个画板的背景色
# customPlot.axisRect().setBackground(plotGradient) # 设置背景颜色,坐标轴包裹的区域
# customPlot.axisRect().setBackground(Qt.blue) #或者设置为纯色
customPlot.addGraph()
x=[]
y=[]
for i in range(101):
x.append(i/50.0-1)
y.append(x[i]**2)
customPlot.graph(0).setData(x,y)
customPlot.graph(0).setName("第一个示例")
customPlot.xAxis.setLabel("x")
customPlot.yAxis.setLabel("y")
# customPlot.xAxis.setBasePen(QPen(Qt.red,10)) #x轴的颜色和粗细
# customPlot.xAxis.setTickPen(QPen(Qt.red, 10)) #轴刻度线的画笔
# customPlot.xAxis.setSubTickPen(QPen(Qt.red, 10)) # 轴子刻度线的画笔
# customPlot.xAxis.setTickLabelColor(Qt.red) # 轴刻度文字颜色
# customPlot.xAxis.setLabel("标签") # 只有设置了标签,轴标签的颜色才会显示
# customPlot.xAxis.setLabelColor(Qt.red) # 轴标签颜色
# customPlot.xAxis.setTickLengthIn(30) # 轴线内刻度的长度,我搞的很大
# customPlot.xAxis.setTickLengthOut(50) # 轴线外刻度的长度
# customPlot.xAxis.setUpperEnding(QCPLineEnding(QCPLineEnding.esSpikeArrow)) # 设置轴线结束时的风格为 实角三角形但内部有凹陷的形状, setLowerEnding设置轴线开始时的风格
# customPlot.xAxis.grid().setPen(QPen(QColor(255, 0, 0), 1, Qt.DotLine)) # 网格线(对应刻度)画笔
# customPlot.yAxis.grid().setPen(QPen(QColor(255, 0, 0), 1, Qt.DotLine))
# customPlot.xAxis.grid().setSubGridVisible(True) # 显示子网格线
# customPlot.yAxis.grid().setSubGridVisible(True)
# customPlot.xAxis.grid().setSubGridPen(QPen(QColor(255, 0, 0), 10, Qt.DotLine)) # 子网格线(对应子刻度)画笔
# customPlot.yAxis.grid().setSubGridPen(QPen(QColor(255, 0, 0), 10, Qt.DotLine))
# customPlot.xAxis.grid().setZeroLinePen(QPen(Qt.red)) #设置刻度为0时的网格线的画笔
# customPlot.yAxis.grid().setZeroLinePen(QPen(Qt.red))
customPlot.xAxis.setRange(-1,1)
customPlot.yAxis.setRange(0,1)
customPlot.legend.setVisible(True) #显示图例
customPlot.replot()
window.show()
sys.exit(app.exec_())
# 3.图标风格
import sys
import math
from PyQt5.QtCore import Qt,QMargins
from PyQt5.QtGui import QPen, QBrush, QColor,QLinearGradient
from PyQt5.QtWidgets import QApplication, QMainWindow
from QCustomPlot2 import *
app = QApplication(sys.argv)
window = QMainWindow()
window.resize(800, 600)
customPlot = QCustomPlot()
window.setCentralWidget(customPlot)
lineNames=["lsNone", "lsLine","lsStepLeft","lsStepRight","lsStepCenter" , "lsImpulse"]
for i in range(QCPGraph.lsNone,QCPGraph.lsImpulse+1):
customPlot.addGraph()
pen=QPen()
pen.setColor(QColor(math.sin(i*1+1.2)*80+80, math.sin(i*0.3+0)*80+80, math.sin(i*0.3+1.5)*80+80))
customPlot.graph().setPen(pen) #设置图表的画笔
customPlot.graph().setName(lineNames[i-QCPGraph.lsNone])
customPlot.graph().setLineStyle(i) # 设置图表线段的风格,QCPGraph::LineStyle这里其实就是int类型
customPlot.graph().setScatterStyle(QCPScatterStyle(QCPScatterStyle.ssCircle, 5)) # 设置图表散点图的样式,散点图的样式有很多种,可以自己试试
x=[]
y=[]
for j in range(15):
x.append(j / 15.0 * 5 * 3.14 + 0.01)
y.append(7 * math.sin(x[j]) / x[j] - (i - QCPGraph.lsNone) * 5 + (QCPGraph.lsImpulse) * 5 + 2)
customPlot.graph().setData(x, y)
customPlot.graph().rescaleAxes(True)
customPlot.replot()
window.show()
sys.exit(app.exec_())
# 4.图标画刷
import sys
import math
from PyQt5.QtCore import Qt,QMargins
from PyQt5.QtGui import QPen, QBrush, QColor,QLinearGradient
from PyQt5.QtWidgets import QApplication, QMainWindow
from QCustomPlot2 import *
app = QApplication(sys.argv)
window = QMainWindow()
window.resize(800, 600)
customPlot = QCustomPlot()
window.setCentralWidget(customPlot)
customPlot.addGraph()
x=[]
y=[]
y1=[]
for i in range(-10,10):
x.append(i)
y.append(i**2-10)
y1.append(2*i)
customPlot.graph(0).setData(x,y)
# 与0刻度线围成区域
customPlot.graph(0).setPen(QPen(Qt.blue))
customPlot.graph(0).setBrush(QBrush(QColor(0, 0, 255, 20))) #这里是与0轴围起来的区域
customPlot.addGraph()
customPlot.graph(1).setData(x,y1)
customPlot.graph(1).setPen(QPen(Qt.red))
# 与其它图围成区域,使用的是图0的画刷
# customPlot.graph(0).setChannelFillGraph(customPlot.graph(1)) # 将图0与图1围成区域
customPlot.xAxis.setRange(-10,10) #设置x轴的范围为(-1,1)
customPlot.yAxis.setRange(-10,10)
customPlot.replot()
window.show()
sys.exit(app.exec_())
# 5.柱状图
import sys
import math
from PyQt5.QtCore import Qt,QMargins
from PyQt5.QtGui import QPen, QBrush, QColor
from PyQt5.QtWidgets import QApplication, QMainWindow
from QCustomPlot2 import * #先导入PyQt5,不然报错
app = QApplication(sys.argv)
window = QMainWindow()
window.resize(800, 600)
customPlot = QCustomPlot() #相当于pyqt5的一个控件
window.setCentralWidget(customPlot)
xk=customPlot.xAxis
yk=customPlot.yAxis
fossil = QCPBars(xk, yk) # 使用xAxis作为柱状图的x轴,yAxis作为y轴
# fossil = QCPBars(yk, xk) # 反过来就是横向
fossil.setAntialiased(False) # 为了更好的边框效果,关闭抗齿锯
fossil.setName("Fossil fuels") # 设置柱状图的名字,可在图例中显示
fossil.setPen(QPen(QColor(0, 168, 140).lighter(130))) # 设置柱状图的边框颜色
fossil.setBrush(QColor(0, 168, 140)) # 设置柱状图的画刷颜色
# 为柱状图设置一个文字类型的key轴,ticks决定了轴的范围,而labels决定了轴的刻度文字的显示
ticks = [1 , 2 , 3 , 4 , 5 , 6 , 7]
labels=["USA" , "Japan" , "Germany" , "France" , "UK" , "Italy" , "Canada"]
textTicker=QCPAxisTickerText()
textTicker.addTicks(ticks, labels)
xk.setTicker(textTicker) # 设置为文字轴
xk.setTickLabelRotation(60) # 轴刻度文字旋转60度
xk.setSubTicks(False) # 不显示子刻度
xk.setTickLength(0, 4) # 轴内外刻度的长度分别是0,4,也就是轴内的刻度线不显示
xk.setRange(0, 8) # 设置范围
yk.setRange(0, 12.1)
yk.setPadding(35) # 轴的内边距,可以到QCustomPlot之开始(一)看图解
yk.setLabel("Power Consumption in\nKilowatts per Capita (2007)")
fossilData =[0.86*10.5 , 0.83*5.5 , 0.84*5.5 , 0.52*5.8 , 0.89*5.2 , 0.90*4.2 , 0.67*11.2]
fossil.setData(ticks, fossilData)
customPlot.replot()
window.show()
sys.exit(app.exec_())
# 6.柱状堆积图
import sys
import math
from PyQt5.QtCore import Qt,QMargins
from PyQt5.QtGui import QPen, QBrush, QColor
from PyQt5.QtWidgets import QApplication, QMainWindow
from QCustomPlot2 import * #先导入PyQt5,不然报错
app = QApplication(sys.argv)
window = QMainWindow()
window.resize(800, 600)
customPlot = QCustomPlot() #相当于pyqt5的一个控件
window.setCentralWidget(customPlot)
xk=customPlot.xAxis
yk=customPlot.yAxis
fossil = QCPBars(xk, yk) # 使用xAxis作为柱状图的x轴,yAxis作为y轴
# fossil = QCPBars(yk, xk) # 反过来就是横向
regen = QCPBars(xk, yk) # 没设置颜色见谅
nuclear = QCPBars(xk, yk)
fossil.setAntialiased(False) # 为了更好的边框效果,关闭抗齿锯
fossil.setName("Fossil fuels") # 设置柱状图的名字,可在图例中显示
fossil.setPen(QPen(QColor(0, 168, 140).lighter(130))) # 设置柱状图的边框颜色
fossil.setBrush(QColor(0, 168, 140)) # 设置柱状图的画刷颜色
# 为柱状图设置一个文字类型的key轴,ticks决定了轴的范围,而labels决定了轴的刻度文字的显示
ticks = [1 , 2 , 3 , 4 , 5 , 6 , 7]
labels=["USA" , "Japan" , "Germany" , "France" , "UK" , "Italy" , "Canada"]
textTicker=QCPAxisTickerText()
textTicker.addTicks(ticks, labels)
xk.setTicker(textTicker) # 设置为文字轴
xk.setTickLabelRotation(60) # 轴刻度文字旋转60度
xk.setSubTicks(False) # 不显示子刻度
xk.setTickLength(0, 4) # 轴内外刻度的长度分别是0,4,也就是轴内的刻度线不显示
xk.setRange(0, 8) # 设置范围
yk.setRange(0, 12.1)
yk.setPadding(35) # 轴的内边距,可以到QCustomPlot之开始(一)看图解
yk.setLabel("Power Consumption in\nKilowatts per Capita (2007)")
fossilData =[0.86*10.5 , 0.83*5.5 , 0.84*5.5 , 0.52*5.8 , 0.89*5.2 , 0.90*4.2 , 0.67*11.2]
fossil.setData(ticks, fossilData)
nuclearData =[0.08*10.5 , 0.12*5.5 , 0.12*5.5 , 0.40*5.8 , 0.09*5.2 , 0.00*4.2 , 0.07*11.2]
regenData = [0.06*10.5 , 0.05*5.5 , 0.04*5.5 , 0.06*5.8 , 0.02*5.2 , 0.07*4.2 , 0.25*11.2]
nuclear.setData(ticks, nuclearData)
regen.setData(ticks, regenData)
regen.setStackingGap(1) # 设置堆积在其它柱状图上时的间距(像素)
nuclear.setStackingGap(1)
nuclear.moveAbove(fossil) # 将nuclear移到fossil之上
regen.moveAbove(nuclear)
customPlot.replot()
window.show()
sys.exit(app.exec_())
# 7. 图例的位置
import sys
import math
from PyQt5.QtCore import Qt,QMargins
from PyQt5.QtGui import QPen, QBrush, QColor,QLinearGradient,QFont
from PyQt5.QtWidgets import QApplication, QMainWindow
from QCustomPlot2 import *
app = QApplication(sys.argv)
window = QMainWindow()
window.resize(800, 600)
customPlot = QCustomPlot()
window.setCentralWidget(customPlot)
# ---
customPlot.legend.setVisible(True) #设置图例,图例就是legend,
customPlot.legend.setFont(QFont("Helvetica", 9))
customPlot.legend.setTextColor(Qt.red)
customPlot.legend.setIconSize(50, 20)
customPlot.legend.setBrush(QBrush(Qt.yellow))
customPlot.legend.setBorderPen(QPen(Qt.DashDotLine))
# ---
lineNames=["lsNone", "lsLine","lsStepLeft","lsStepRight","lsStepCenter" , "lsImpulse"]
for i in range(QCPGraph.lsNone,QCPGraph.lsImpulse+1):
customPlot.addGraph()
pen=QPen()
pen.setColor(QColor(math.sin(i*1+1.2)*80+80, math.sin(i*0.3+0)*80+80, math.sin(i*0.3+1.5)*80+80))
customPlot.graph().setPen(pen) #设置图表的画笔
customPlot.graph().setName(lineNames[i-QCPGraph.lsNone])
customPlot.graph().setLineStyle(i) # 设置图表线段的风格,QCPGraph::LineStyle这里其实就是int类型
customPlot.graph().setScatterStyle(QCPScatterStyle(QCPScatterStyle.ssCircle, 5)) # 设置图表散点图的样式,散点图的样式有很多种,可以自己试试
x=[]
y=[]
for j in range(15):
x.append(j / 15.0 * 5 * 3.14 + 0.01)
y.append(7 * math.sin(x[j]) / x[j] - (i - QCPGraph.lsNone) * 5 + (QCPGraph.lsImpulse) * 5 + 2)
customPlot.graph().setData(x, y)
customPlot.graph().rescaleAxes(True)
# customPlot.axisRect().insetLayout().setInsetAlignment(0, Qt.AlignLeft | Qt.AlignTop) #把图例放到左上
customPlot.replot()
window.show()
sys.exit(app.exec_())
# 8. 轴矩形和轴
import sys
import math,random
from PyQt5.QtCore import Qt,QMargins
from PyQt5.QtGui import QPen, QBrush, QColor
from PyQt5.QtWidgets import QApplication, QMainWindow
from QCustomPlot2 import * #先导入PyQt5,不然报错
app = QApplication(sys.argv)
window = QMainWindow()
window.resize(800, 600)
customPlot = QCustomPlot() #相当于pyqt5的一个控件
window.setCentralWidget(customPlot)
demoName = "Advanced Axes Demo"
customPlot.plotLayout().clear() # 首先清空默认的轴矩形,让我们从头开始
wideAxisRect =QCPAxisRect(customPlot, True) #还记得setupDefaultAxes为true时的作用吗,忘了的话翻上去看吧
wideAxisRect.setupFullAxesBox(True) # 让四个轴关联,并全部显示出来
wideAxisRect.addAxis(QCPAxis.atLeft).setTickLabelColor(QColor("#6050F8")) # 在左边多添加一个轴并且设置它的颜色
subLayout = QCPLayoutGrid()
customPlot.plotLayout().addElement(0, 0, wideAxisRect) #在第一行添加轴矩形
customPlot.plotLayout().addElement(1, 0, subLayout) #在第二行添加一个子布局,后面会添加两个轴矩形在里面
subRectLeft = QCPAxisRect(customPlot, False) #不配置轴
subRectRight = QCPAxisRect(customPlot, False)
# 让右边的轴矩形固定大小
subRectRight.setMaximumSize(100, 100)
subRectRight.setMinimumSize(100, 100)
subLayout.addElement(0, 0, subRectLeft) # 在第一列添加轴矩形
subLayout.addElement(0, 1, subRectRight) # 在第二列添加轴矩形
subRectLeft.addAxes(QCPAxis.atBottom | QCPAxis.atLeft) # 添加下轴和左轴
subRectRight.addAxes(QCPAxis.atBottom | QCPAxis.atRight) # 添加下轴和右轴
subRectLeft.axis(QCPAxis.atLeft).ticker().setTickCount(2) # 设置轴的刻度为一个固定的步进值
subRectRight.axis(QCPAxis.atRight).ticker().setTickCount(2)
subRectLeft.axis(QCPAxis.atBottom).grid().setVisible(True)
for i in customPlot.axisRects():
for j in i.axes():
j.setLayer("axes")
j.grid().setLayer("grid")
x0=[]
y0=[]
x1=[]
y1=[]
x2=[]
y2=[]
for i in range(21):
x0.append(i/float(21-1)*10-5.)
y0.append(math.cos(i/float(21-1)*10-5.))
for i in range (50):
temp=i/float(50*10-5.0)
x1.append(i/float(50*10-5.0))
y1.append(math.exp(-temp**2*0.2)*1000)
for i in range(100):
temp=i/100*10
x2.append(temp)
y2.append(random.random()/(temp+1))
x3 = [1 , 2 , 3 , 4]
y3 = [2 , 2.5 , 4 , 1.5]
# mainGraphCos和 mainGraphGauss 共享下轴,但是它们的左轴不同
mainGraphCos = customPlot.addGraph(wideAxisRect.axis(QCPAxis.atBottom), wideAxisRect.axis(QCPAxis.atLeft))
mainGraphCos.setData(x0,y0)
mainGraphCos.valueAxis().setRange(-1, 1)
mainGraphCos.rescaleKeyAxis()
mainGraphCos.setScatterStyle(QCPScatterStyle(QCPScatterStyle.ssCircle, QPen(Qt.black), QBrush(Qt.white), 6))
mainGraphCos.setPen(QPen(QColor(120, 120, 120), 2))
mainGraphGauss = customPlot.addGraph(wideAxisRect.axis(QCPAxis.atBottom), wideAxisRect.axis(QCPAxis.atLeft, 1))
mainGraphGauss.setData(x1,y1)
mainGraphGauss.setPen(QPen(QColor("#8070B8"), 2))
mainGraphGauss.setBrush(QColor(110, 170, 110, 30))
mainGraphCos.setChannelFillGraph(mainGraphGauss)
mainGraphCos.setBrush(QColor(255, 161, 0, 50))
mainGraphGauss.valueAxis().setRange(0, 1000)
mainGraphGauss.rescaleKeyAxis()
subGraphRandom = customPlot.addGraph(subRectLeft.axis(QCPAxis.atBottom), subRectLeft.axis(QCPAxis.atLeft))
subGraphRandom.setData(x2,y2)
subGraphRandom.setLineStyle(QCPGraph.lsImpulse)
subGraphRandom.setPen(QPen(QColor("#FFA100"), 1.5))
subGraphRandom.rescaleAxes()
subBars = QCPBars(subRectRight.axis(QCPAxis.atBottom), subRectRight.axis(QCPAxis.atRight))
subBars.setWidth(3/4)
subBars.setData(x3, y3)
subBars.setPen(QPen(Qt.black))
subBars.setAntialiased(False)
subBars.setAntialiasedFill(False)
subBars.setBrush(QColor("#705BE8"))
subBars.keyAxis().setSubTicks(False)
subBars.rescaleAxes()
# 给柱状图一个固定步进轴
intTicker=QCPAxisTickerFixed()
intTicker.setTickStep(1.0)
intTicker.setScaleStrategy(QCPAxisTickerFixed.ssMultiples)
subBars.keyAxis().setTicker(intTicker)
customPlot.replot()
window.show()
sys.exit(app.exec_())
# 9.添加一些曲线文字
import sys
import math,random
from PyQt5.QtCore import Qt,QMargins,QTimer,QDateTime
from PyQt5.QtGui import QPen, QBrush, QColor,QFont
from PyQt5.QtWidgets import QApplication, QMainWindow
from QCustomPlot2 import * #先导入PyQt5,不然报错
app = QApplication(sys.argv)
window = QMainWindow()
window.resize(800, 600)
customPlot = QCustomPlot() #相当于pyqt5的一个控件
window.setCentralWidget(customPlot)
# 设置可以拖动和缩放
customPlot.setInteractions(QCP.iRangeDrag | QCP.iRangeZoom)
# 添加图层1,并设置数据、设置pen
graph = customPlot.addGraph()
n = 500
phase = 0
k = 3
x=[]
y=[]
for i in range(n):
temp=i/(n-1)*34-17
x.append(temp)
y.append(math.exp(-temp**2/20.0)*math.sin(k*temp+phase))
graph.setData(x, y)
graph.setPen(QPen(Qt.blue))
# 设置y轴范围
customPlot.yAxis.setRange(-1.45, 1.65)
customPlot.xAxis.grid().setZeroLinePen(QPen(QColor(255,0,0), 0, Qt.SolidLine))
# 在顶部添加一个大括号
bracket = QCPItemBracket(customPlot)
bracket.left.setCoords(-8, 1.1) #设置左点坐标
bracket.right.setCoords(8, 1.1) #设置有点坐标
bracket.setLength(13)
# 在大括号附近设置文字Wavepacket
wavePacketText = QCPItemText(customPlot)
wavePacketText.position.setParentAnchor(bracket.center)
wavePacketText.position.setCoords(0, -10)#设置坐标
wavePacketText.setPositionAlignment(Qt.AlignBottom|Qt.AlignHCenter)
wavePacketText.setText("Wavepacket")
# 添加相位跟踪器(红色圆圈),它将粘附在图形数据上(并通过计时器事件在bracketDataSlot中更新):
phaseTracer = QCPItemTracer(customPlot)
itemDemoPhaseTracer = phaseTracer
phaseTracer.setGraph(graph)#为跟踪器设置图层,它将附着在上面
phaseTracer.setGraphKey((math.pi*1.5-phase)/k)# 设置跟踪器将定位的图形数据点的键。graph data中的key
phaseTracer.setInterpolating(True)
phaseTracer.setStyle(QCPItemTracer.tsCircle)
phaseTracer.setPen(QPen(Qt.red))
phaseTracer.setBrush(Qt.red)
phaseTracer.setSize(7)
# 为相位跟踪器添加标签
phaseTracerText = QCPItemText(customPlot)
phaseTracerText.position.setType(QCPItemPosition.ptAxisRectRatio)
phaseTracerText.setPositionAlignment(Qt.AlignRight|Qt.AlignBottom)
phaseTracerText.position.setCoords(1.0, 0.95)
phaseTracerText.setText("Points of fixed\nphase define\nphase velocity vp")
phaseTracerText.setTextAlignment(Qt.AlignLeft)
phaseTracerText.setPadding(QMargins(8, 0, 0, 0))
# 添加箭头指向相位跟踪器
phaseTracerArrow = QCPItemCurve(customPlot)
phaseTracerArrow.start.setParentAnchor(phaseTracerText.left)
phaseTracerArrow.startDir.setParentAnchor(phaseTracerArrow.start)
phaseTracerArrow.startDir.setCoords(-40, 0)
phaseTracerArrow.end.setParentAnchor(phaseTracer.position)
phaseTracerArrow.end.setCoords(10, 10)
phaseTracerArrow.endDir.setParentAnchor(phaseTracerArrow.end)
phaseTracerArrow.endDir.setCoords(30, 30)
phaseTracerArrow.setHead(QCPLineEnding(QCPLineEnding.esSpikeArrow))
phaseTracerArrow.setTail(QCPLineEnding(QCPLineEnding.esBar, (phaseTracerText.bottom.pixelPosition().y()-phaseTracerText.top.pixelPosition().y())*0.85))
# 添加组速度跟踪器(绿色圆圈):
groupTracer = QCPItemTracer(customPlot)
groupTracer.setGraph(graph)
groupTracer.setGraphKey(5.5)
groupTracer.setInterpolating(True)
groupTracer.setStyle(QCPItemTracer.tsCircle)
groupTracer.setPen(QPen(Qt.green))
groupTracer.setBrush(Qt.green)
groupTracer.setSize(7)
# 为组跟踪器添加标签:
groupTracerText = QCPItemText(customPlot)
groupTracerText.position.setType(QCPItemPosition.ptAxisRectRatio)
groupTracerText.setPositionAlignment(Qt.AlignRight|Qt.AlignTop)
groupTracerText.position.setCoords(1.0, 0.20)
groupTracerText.setText("Fixed positions in\nwave packet define\ngroup velocity vg")
groupTracerText.setTextAlignment(Qt.AlignLeft)
groupTracerText.setPadding(QMargins(8, 0, 0, 0))
# 添加箭头指向组跟踪器
groupTracerArrow = QCPItemCurve(customPlot)
groupTracerArrow.start.setParentAnchor(groupTracerText.left)
groupTracerArrow.startDir.setParentAnchor(groupTracerArrow.start)
groupTracerArrow.startDir.setCoords(-40, 0)
groupTracerArrow.end.setCoords(5.5, 0.4)
groupTracerArrow.endDir.setParentAnchor(groupTracerArrow.end)
groupTracerArrow.endDir.setCoords(0, -40)
groupTracerArrow.setHead(QCPLineEnding(QCPLineEnding.esSpikeArrow))
groupTracerArrow.setTail(QCPLineEnding(QCPLineEnding.esBar, (groupTracerText.bottom.pixelPosition().y()-groupTracerText.top.pixelPosition().y())*0.85))
# 添加一个分散箭头(一条曲线)
arrow = QCPItemCurve(customPlot)
arrow.start.setCoords(1, -1.1)
arrow.startDir.setCoords(-1, -1.3)
arrow.endDir.setCoords(-5, -0.3)
arrow.end.setCoords(-10, -0.2)
arrow.setHead(QCPLineEnding(QCPLineEnding.esSpikeArrow))
# 为分散箭头添加标签
dispersionText = QCPItemText(customPlot)
dispersionText.position.setCoords(-6, -0.9)
dispersionText.setRotation(40)
dispersionText.setText("Dispersion with\nvp < vg")
# slot
def bracketDataSlot():
secs = QCPAxisTickerDateTime.dateTimeToKey(QDateTime.currentDateTime())
n = 500
phase = secs * 5
k = 3
x,y=[],[]
for i in range(n):
temp=i / (n - 1) * 34 - 17
x.append(temp)
y.append(math.exp(-temp * temp / 20.0) * math.sin(k * temp + phase))
customPlot.graph().setData(x, y)
itemDemoPhaseTracer.setGraphKey((8 * math.pi + math.fmod(math.pi * 1.5 - phase, 6 * math.pi)) / k)
customPlot.replot()
timer=QTimer()
timer.timeout.connect(bracketDataSlot)
timer.start(0)
customPlot.replot()
window.show()
sys.exit(app.exec_())
# 10. 绘制方程
import sys
import math
from PyQt5.QtCore import Qt,QMargins,QTimer
from PyQt5.QtGui import QPen, QBrush, QColor
from PyQt5.QtWidgets import QApplication, QMainWindow
from QCustomPlot2 import * #先导入PyQt5,不然报错
app = QApplication(sys.argv)
window = QMainWindow()
window.resize(800, 600)
customPlot = QCustomPlot() #相当于pyqt5的一个控件
window.setCentralWidget(customPlot)
curve = QCPCurve(customPlot.xAxis, customPlot.yAxis)
curve.setPen(QPen(Qt.red))
# 由于我们是动态图,并且其范围不变化,所以预先设置好了范围
customPlot.xAxis.setRange(-2.5, 12.5)
customPlot.yAxis.setRange(-2.8, 2.8)
t = -math.pi # 定义起始t
reversed = False # 为了重复绘制
def dynamicLemniscateSlot():
global t
global reversed
# 伯努利双纽线(无穷大的符号)
x = -686 * math.cos(t) + 735 * math.cos(2 * t) + 490 * math.sqrt(math.pow(math.sin(t), 4)) - 265
x /= (280 * math.cos(t) - 298)
y = 5 * math.sqrt(math.pow(math.sin(t), 4)) * (10 / math.sin(t) - 7 / math.tan(t)) + 3 * (35 * math.cos(t) - 33) * math.sin(t)
y = 7 * y / (140 * math.cos(t) - 149)
if not reversed:# 还未绘制完成
t += 0.01
curve.data().add(QCPCurveData(t, x, y))
else:
#绘制已经完成,倒退回去
t -= 0.01
curve.data().removeAfter(t) #这里不能用remove,因为精度原因,remove并不能精确匹配,导致无法删除数据点
customPlot.replot()
# 重复绘制
if t>=math.pi:
t=math.pi
reversed=True
elif reversed and t<=-math.pi:
t=-math.pi
reversed=False
timer=QTimer()
timer.timeout.connect(dynamicLemniscateSlot)
timer.start(10)
customPlot.replot()
window.show()
sys.exit(app.exec_())
#11.鼠标跟随点
import sys
import math
from PyQt5.QtCore import Qt,QMargins,QTimer
from PyQt5.QtGui import QPen, QBrush, QColor
from PyQt5.QtWidgets import QApplication, QMainWindow
from QCustomPlot2 import * #先导入PyQt5,不然报错
app = QApplication(sys.argv)
window = QMainWindow()
window.resize(800, 600)
customPlot = QCustomPlot() #相当于pyqt5的一个控件
window.setCentralWidget(customPlot)
# 生成数据,画出的是抛物线
x,y=[],[]
for i in range(101):
temp=i/50.0 - 1
x.append(temp) # x范围[-1,1]
y.append(temp**2)
customPlot.xAxis.setRange(-1, 1)
customPlot.yAxis.setRange(0, 1)
customPlot.addGraph()
customPlot.graph(0).setData(x, y) #把数据加入到绘制器cmPlot,绘制器会自动绘制曲线
#生成游标
tracer = QCPItemTracer(customPlot); #生成游标
tracer.setPen(QPen(Qt.red))#圆圈轮廓颜色
tracer.setBrush(QBrush(Qt.red))#圆圈圈内颜色
tracer.setStyle(QCPItemTracer.tsCircle)#圆圈
tracer.setSize(5)#设置大小
#游标说明
tracerLabel = QCPItemText(customPlot) #生成游标说明
tracerLabel.setLayer("overlay")#设置图层为overlay,因为需要频繁刷新
tracerLabel.setPen(QPen(Qt.black))#设置游标说明颜色
tracerLabel.setPositionAlignment(Qt.AlignLeft | Qt.AlignTop)#左上
tracerLabel.position.setParentAnchor(tracer.position)#将游标说明锚固在tracer位置处,实现自动跟随
def mouseMove1(e):
# 获得鼠标位置处对应的横坐标数据x
x=customPlot.xAxis.pixelToCoord(e.pos().x()) #就是游标的横坐标
y=x**2 # 就是游标的纵坐标,这里直接根据产生数据的函数获得
tracer.position.setCoords(x,y) # 设置游标位置
tracerLabel.setText(("x = {}, y = {}").format(x,y)) # 设置游标说明内容
customPlot.replot() # 绘制器一定要重绘,否则看不到游标位置更新情况
def mouseMove2(e): #但是上述方法只适合于函数比较简单的情况(比如幂函数或指数函数),计算yValue时计算开销不大,鼠标移动时响应比较迅速。如果函数形式比较复杂,计算量大,那么应该采用以下的方法。
# 获得鼠标位置处对应的横坐标数据x
x = customPlot.xAxis.pixelToCoord(e.pos().x()) # 就是游标的横坐标
tracer.setGraph(customPlot.graph(0)) # 将游标和该曲线图层想连接
tracer.setGraphKey(x) # 将游标横坐标设置成刚获得的横坐标数据x
tracer.setInterpolating(True) # 游标的纵坐标可以通过曲线数据线性插值自动获得
tracer.updatePosition() # 使得刚设置游标的横纵坐标位置生效
# 更新游标说明的内容
xValue = tracer.position.key()
yValue = tracer.position.value()
tracerLabel.setText(("x = {}, y = {}").format(xValue,yValue))
customPlot.replot() # 绘制器一定要重绘,否则看不到游标位置更新情况
#信号-槽连接语句
# customPlot.mouseMove.connect(mouseMove1)
customPlot.mouseMove.connect(mouseMove2)
customPlot.replot()
window.show()
sys.exit(app.exec_())
# 12.鼠标跟随点多条曲线
import sys
import math
from PyQt5.QtCore import Qt,QMargins,QTimer
from PyQt5.QtGui import QPen, QBrush, QColor
from PyQt5.QtWidgets import QApplication, QMainWindow,QToolTip
from QCustomPlot2 import * #先导入PyQt5,不然报错
app = QApplication(sys.argv)
window = QMainWindow()
window.resize(800, 600)
customPlot = QCustomPlot() #相当于pyqt5的一个控件
window.setCentralWidget(customPlot)
# 每条曲线都会独占一个graph()
customPlot.addGraph()
customPlot.graph(0).setPen(QPen(Qt.blue)) #曲线的颜色
customPlot.graph(0).setBrush(QBrush(QColor(0, 0, 255, 20))) #曲线与X轴包围区的颜色
customPlot.addGraph() #添加graph等价于添加一条新曲线
customPlot.graph(1).setPen(QPen(Qt.red)) # 曲线的颜色
#生成模拟数据点 (x-y0 第一条曲线, x-y1为第2条曲线):
x,y0,y1=[],[],[]
for i in range(251):
x.append(i)
y0.append(math.exp(-i/150.0)*math.cos(i/10.0)) # 第一条曲线:y0衰减cos
y1.append(math.exp(-i/150.0)) # 第二条曲线:y1衰减指数
# 边框右侧和上侧均显示刻度线,但不显示刻度值:
customPlot.xAxis2.setVisible(True)
customPlot.xAxis2.setTickLabels(False)
customPlot.yAxis2.setVisible(True)
customPlot.yAxis2.setTickLabels(False)
# // 使上下两个X轴的范围总是相等,使左右两个Y轴的范围总是相等
customPlot.xAxis.rangeChanged.connect(customPlot.xAxis2.setRange)
customPlot.yAxis.rangeChanged.connect(customPlot.yAxis2.setRange)
# 把已存在的数据填充进graph的数据区
customPlot.graph(0).setData(x, y0)
customPlot.graph(1).setData(x, y1)
#自动调整XY轴的范围,以便显示出graph(0)中所有的点(下面会单独讲到这个函数)
customPlot.graph(0).rescaleAxes()
#自动调整XY轴的范围,以便显示出graph(1)中所有的点
customPlot.graph(1).rescaleAxes(True)
# 支持鼠标拖拽轴的范围、滚动缩放轴的范围,左键点选图层(每条曲线独占一个图层)
customPlot.setInteractions(QCP.iRangeDrag | QCP.iRangeZoom | QCP.iSelectPlottables)
tracer = QCPItemTracer(customPlot)
# tracer.setInterpolating(False)
tracer.setStyle(QCPItemTracer.tsCircle)
tracer.setPen(QPen(Qt.red))
tracer.setBrush(Qt.red)
tracer.setSize(6)
def mouseMoveEvent(e):
mGraph = customPlot.graph(0)
#将像素点转换成qcustomplot中的坐标值,并通过setGraphKey将锚点值设为真实数据值。tracer->setGraphKey(xAxis->pixelToCoord(event->pos().x()));
graphCount=2
# 获得鼠标位置处对应的横坐标数据x
x = customPlot.xAxis.pixelToCoord(e.pos().x())
#遍历曲线
for i in range(graphCount):
# 判断哪一条曲线被选中
if customPlot.graph(i).selected():
# 显示锚点
tracer.setVisible(True)
mGraph = customPlot.graph(i)
tracer.setGraph(mGraph) # 将锚点设置到被选中的曲线上
tracer.setGraphKey(x) # 将游标横坐标设置成刚获得的横坐标数据x
tracer.setInterpolating(True)# 游标的纵坐标可以通过曲线数据线性插值自动获得
tracer.updatePosition() #使得刚设置游标的横纵坐标位置生效
xValue = tracer.position.key()
yValue = tracer.position.value()
# 显示tip框
QToolTip.showText(e.globalPos(), (
"<h4>{}</h4>"
"<table>"
"<tr>"
"<td><h5>X: {}</h5></td>" "<td> , </td>" "<td><h5>Y: {}</h5></td>"
"</tr>"
"</table>").format(mGraph.name(),xValue,yValue), customPlot, customPlot.rect())
break
else:
# 没有曲线被选中,不显示锚点
tracer.setVisible(False)
#重绘
customPlot.replot()
#信号-槽连接语句
customPlot.mouseMove.connect(mouseMoveEvent)
customPlot.replot()
window.show()
sys.exit(app.exec_())
网友评论