Qcustomplot2_python版本

# 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_())
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容