PyQt5 QCustomPlot常见图形
时间: 2025-08-27 20:56:49 AIGC 浏览: 28
<think>我们正在讨论PyQt5中QCustomPlot库支持的常见图形类型及使用方法。根据引用[2]和[4],QCustomPlot是一个强大的二维绘图库,支持多种图形类型。下面将详细介绍几种常见的图形类型及其使用方法。
## 1. 折线图 (Line Graph)
折线图是最基本的图表类型,用于显示数据随时间或其他连续变量的变化趋势。
### 示例代码:
```python
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPen
from qcustomplot import QCustomPlot, QCPGraph
import sys
import math
app = QApplication(sys.argv)
customPlot = QCustomPlot()
customPlot.setWindowTitle("折线图示例")
customPlot.setGeometry(100, 100, 800, 600)
# 创建两个折线图
graph1 = customPlot.addGraph()
graph2 = customPlot.addGraph()
# 设置线条样式
graph1.setPen(QPen(Qt.blue))
graph2.setPen(QPen(Qt.red))
# 生成数据
x = [i/10.0 for i in range(100)]
y1 = [math.sin(xi) for xi in x]
y2 = [math.cos(xi) for xi in x]
# 设置数据
graph1.setData(x, y1)
graph2.setData(x, y2)
# 设置坐标轴标签
customPlot.xAxis.setLabel("x")
customPlot.yAxis.setLabel("y")
# 自动调整坐标轴范围
customPlot.rescaleAxes()
# 显示网格
customPlot.xAxis.grid().setVisible(True)
customPlot.yAxis.grid().setVisible(True)
# 显示图表
customPlot.show()
sys.exit(app.exec_())
```
## 2. 柱状图 (Bar Chart)
柱状图用于比较不同类别的数据,如引用[1]和[2]中提到的QCPBars。
### 示例代码:
```python
from PyQt5.QtWidgets import QApplication
from PyQt5.QtGui import QColor
from qcustomplot import QCustomPlot, QCPBars
import sys
app = QApplication(sys.argv)
customPlot = QCustomPlot()
customPlot.setWindowTitle("柱状图示例")
customPlot.setGeometry(100, 100, 800, 600)
# 创建柱状图
bars = QCPBars(customPlot.xAxis, customPlot.yAxis)
# 设置数据
categories = ["A", "B", "C", "D"]
values = [10, 20, 15, 25]
x = [0, 1, 2, 3] # 类别位置
bars.setData(x, values)
bars.setWidth(0.6) # 设置柱子宽度
# 设置柱子颜色
bars.setBrush(QColor(50, 130, 200, 150))
bars.setPen(QColor(0, 0, 0))
# 设置坐标轴
customPlot.xAxis.setLabel("类别")
customPlot.yAxis.setLabel("数值")
customPlot.xAxis.setRange(-0.5, 3.5)
customPlot.xAxis.setTickVector(x)
customPlot.xAxis.setTickVectorLabels(categories)
customPlot.yAxis.setRange(0, 30)
# 显示图表
customPlot.show()
sys.exit(app.exec_())
```
## 3. 散点图 (Scatter Plot)
散点图用于展示两个变量之间的关系,每个点的位置由两个变量的值决定。
### 示例代码:
```python
from PyQt5.QtWidgets import QApplication
from PyQt5.QtGui import QPen, QColor
from qcustomplot import QCustomPlot, QCPScatterStyle
import sys
import numpy as np
app = QApplication(sys.argv)
customPlot = QCustomPlot()
customPlot.setWindowTitle("散点图示例")
customPlot.setGeometry(100, 100, 800, 600)
# 创建散点图
graph = customPlot.addGraph()
graph.setLineStyle(QCPGraph.lsNone) # 不连接点
graph.setScatterStyle(QCPScatterStyle(QCPScatterStyle.ssCircle, 8)) # 设置点样式为圆形,大小为8
# 生成随机数据
np.random.seed(42)
x = np.random.normal(size=100)
y = x * 0.5 + np.random.normal(size=100)
# 设置数据
graph.setData(x, y)
# 设置点颜色
graph.setPen(QPen(QColor(120, 120, 120))) # 点的边框颜色
graph.setBrush(QColor(200, 50, 50, 100)) # 点的填充颜色(带透明度)
# 设置坐标轴标签
customPlot.xAxis.setLabel("X变量")
customPlot.yAxis.setLabel("Y变量")
# 自动调整坐标轴范围
customPlot.rescaleAxes()
# 显示图表
customPlot.show()
sys.exit(app.exec_())
```
## 4. 曲线图 (Curve Plot)
曲线图与折线图类似,但通常用于显示函数曲线或平滑数据。
### 示例代码(正弦曲线):
```python
from PyQt5.QtWidgets import QApplication
from PyQt5.QtGui import QPen
from qcustomplot import QCustomPlot
import sys
import math
app = QApplication(sys.argv)
customPlot = QCustomPlot()
customPlot.setWindowTitle("曲线图示例")
customPlot.setGeometry(100, 100, 800, 600)
# 添加图形
graph = customPlot.addGraph()
# 设置线条样式
graph.setPen(QPen(Qt.blue, 2))
# 生成正弦数据
x = [i/50.0 for i in range(500)]
y = [math.sin(xi) for xi in x]
# 设置数据
graph.setData(x, y)
# 设置坐标轴标签
customPlot.xAxis.setLabel("x")
customPlot.yAxis.setLabel("sin(x)")
# 设置坐标轴范围
customPlot.xAxis.setRange(0, 10)
customPlot.yAxis.setRange(-1.5, 1.5)
# 显示网格
customPlot.xAxis.grid().setVisible(True)
customPlot.yAxis.grid().setVisible(True)
# 显示图表
customPlot.show()
sys.exit(app.exec_())
```
## 5. 饼图 (Pie Chart)
虽然QCustomPlot本身不直接支持饼图,但可以通过QCPItemPie类实现。
### 示例代码:
```python
from PyQt5.QtWidgets import QApplication
from PyQt5.QtGui import QColor, QBrush
from qcustomplot import QCustomPlot, QCPItemPie
import sys
app = QApplication(sys.argv)
customPlot = QCustomPlot()
customPlot.setWindowTitle("饼图示例")
customPlot.setGeometry(100, 100, 800, 600)
# 创建饼图
pie = QCPItemPie(customPlot)
# 设置饼图位置和大小
pie.setPosition(400, 300) # 中心位置
pie.setRadius(150) # 半径
# 设置扇区
pie.setSizes([30, 20, 25, 25]) # 各扇区大小(比例)
# 设置扇区颜色
pie.setBrush(0, QBrush(QColor(255, 0, 0)))
pie.setBrush(1, QBrush(QColor(0, 255, 0)))
pie.setBrush(2, QBrush(QColor(0, 0, 255)))
pie.setBrush(3, QBrush(QColor(255, 255, 0)))
# 设置标签
pie.setLabelVisible(True)
pie.setLabel(0, "30%")
pie.setLabel(1, "20%")
pie.setLabel(2, "25%")
pie.setLabel(3, "25%")
# 设置坐标轴范围(确保饼图在视图中)
customPlot.xAxis.setRange(0, 800)
customPlot.yAxis.setRange(0, 600)
# 显示图表
customPlot.show()
sys.exit(app.exec_())
```
## 6. 误差棒图 (Error Bars)
误差棒图用于显示数据的不确定性范围。
### 示例代码:
```python
from PyQt5.QtWidgets import QApplication
from PyQt5.QtGui import QPen
from qcustomplot import QCustomPlot, QCPErrorBars
import numpy as np
import sys
app = QApplication(sys.argv)
customPlot = QCustomPlot()
customPlot.setWindowTitle("误差棒图示例")
customPlot.setGeometry(100, 100, 800, 600)
# 创建折线图
graph = customPlot.addGraph()
graph.setPen(QPen(Qt.blue))
graph.setLineStyle(QCPGraph.lsLine)
# 创建误差棒
error_bars = QCPErrorBars(customPlot.xAxis, customPlot.yAxis)
error_bars.setDataPlottable(graph) # 关联到折线图
# 生成数据
x = np.arange(10)
y = np.sin(x)
x_err = np.full(10, 0.2) # x方向误差
y_err = np.abs(np.cos(x)) # y方向误差
# 设置数据
graph.setData(x, y)
error_bars.setData(x_err, y_err) # 设置误差值
# 设置坐标轴标签
customPlot.xAxis.setLabel("x")
customPlot.yAxis.setLabel("y")
# 自动调整坐标轴范围
customPlot.rescaleAxes()
# 显示图表
customPlot.show()
sys.exit(app.exec_())
```
## 总结
QCustomPlot支持多种图形类型,包括:
- 折线图 (Line Graph)
- 柱状图 (Bar Chart)
- 散点图 (Scatter Plot)
- 曲线图 (Curve Plot)
- 饼图 (Pie Chart)
- 误差棒图 (Error Bars)
以上示例代码展示了如何使用这些图形类型。更多详细用法可以参考QCustomPlot的官方文档[^4]。
§§相关问题§§
1. 如何在QCustomPlot中添加图例和标题?
2. 如何实现QCustomPlot图表的实时数据更新?
3. 如何保存QCustomPlot图表为图片?
4. QCustomPlot支持哪些交互功能(如缩放、平移)?</think># PyQt5 QCustomPlot 常见图形类型及使用方法
QCustomPlot 是一个强大的PyQt5绘图库,支持多种图形类型。下面我将详细介绍常见图形类型及其使用方法,并提供完整示例代码。
## 一、常见图形类型
### 1. 折线图 (Line Graph)
最基础的图形类型,用于显示数据随时间或连续变量的变化趋势。
**关键特性**:
- 支持多条曲线同时显示
- 可设置不同线型(实线、虚线、点线等)
- 可填充曲线与坐标轴之间的区域
- 支持数据点标记
### 2. 柱状图 (Bar Chart)
用于比较不同类别的数据值,支持垂直和水平方向。
**关键特性**:
- 可设置柱子宽度和间距
- 支持堆叠柱状图
- 支持分组柱状图
- 可自定义柱子颜色和边框
### 3. 散点图 (Scatter Plot)
展示两个变量之间的关系,每个点代表一个数据项。
**关键特性**:
- 可自定义点形状(圆形、方形、三角形等)
- 可设置点大小和颜色
- 支持不同数据系列使用不同标记
### 4. 饼图 (Pie Chart)
用于显示各部分占总体的比例关系。
**关键特性**:
- 可设置扇区颜色
- 支持扇区突出显示
- 可添加标签显示百分比
- 支持3D效果
### 5. 箱线图 (Box Plot)
展示数据分布情况,包括中位数、四分位数和异常值。
**关键特性**:
- 显示数据分布范围
- 标识异常值
- 比较多个数据集分布
- 显示数据偏态
### 6. 误差棒图 (Error Bars)
显示数据的不确定性或误差范围。
**关键特性**:
- 可设置对称或非对称误差
- 支持水平和垂直误差棒
- 可自定义误差棒样式
## 二、完整示例代码
### 1. 折线图示例
```python
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPen, QBrush, QColor
from qcustomplot import QCustomPlot, QCPGraph
import numpy as np
class LineChartDemo(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("折线图示例")
self.setGeometry(100, 100, 800, 600)
central_widget = QWidget()
self.setCentralWidget(central_widget)
layout = QVBoxLayout(central_widget)
self.custom_plot = QCustomPlot()
layout.addWidget(self.custom_plot)
# 创建三条折线
self.graph1 = self.custom_plot.addGraph()
self.graph2 = self.custom_plot.addGraph()
self.graph3 = self.custom_plot.addGraph()
# 设置线条样式
self.graph1.setPen(QPen(Qt.blue, 2))
self.graph2.setPen(QPen(Qt.red, 2, Qt.DashLine))
self.graph3.setPen(QPen(Qt.green, 2, Qt.DotLine))
# 填充第一条曲线下方区域
self.graph1.setBrush(QBrush(QColor(0, 0, 255, 30)))
# 生成数据
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
y3 = np.sin(x) * np.cos(x)
# 设置数据
self.graph1.setData(x, y1)
self.graph2.setData(x, y2)
self.graph3.setData(x, y3)
# 设置坐标轴
self.custom_plot.xAxis.setLabel("时间 (秒)")
self.custom_plot.yAxis.setLabel("振幅")
self.custom_plot.xAxis.setRange(0, 10)
self.custom_plot.yAxis.setRange(-1.5, 1.5)
# 添加图例
self.custom_plot.legend.setVisible(True)
self.graph1.setName("正弦波")
self.graph2.setName("余弦波")
self.graph3.setName("混合波")
# 添加网格
self.custom_plot.xAxis.grid().setVisible(True)
self.custom_plot.yAxis.grid().setVisible(True)
# 重绘图表
self.custom_plot.replot()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = LineChartDemo()
window.show()
sys.exit(app.exec_())
```
### 2. 柱状图示例
```python
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QColor
from qcustomplot import QCustomPlot, QCPBars
class BarChartDemo(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("柱状图示例")
self.setGeometry(100, 100, 800, 600)
central_widget = QWidget()
self.setCentralWidget(central_widget)
layout = QVBoxLayout(central_widget)
self.custom_plot = QCustomPlot()
layout.addWidget(self.custom_plot)
# 准备数据
categories = ["第一季度", "第二季度", "第三季度", "第四季度"]
values1 = [25, 40, 30, 50]
values2 = [20, 35, 25, 45]
# 创建柱状图
self.bars1 = QCPBars(self.custom_plot.xAxis, self.custom_plot.yAxis)
self.bars2 = QCPBars(self.custom_plot.xAxis, self.custom_plot.yAxis)
# 设置柱子宽度
self.bars1.setWidth(0.35)
self.bars2.setWidth(0.35)
# 设置柱子位置(分组显示)
x1 = [0.5, 1.5, 2.5, 3.5]
x2 = [0.85, 1.85, 2.85, 3.85]
# 设置数据
self.bars1.setData(x1, values1)
self.bars2.setData(x2, values2)
# 设置柱子颜色
self.bars1.setPen(QColor(0, 0, 0))
self.bars1.setBrush(QColor(79, 129, 189, 180))
self.bars2.setPen(QColor(0, 0, 0))
self.bars2.setBrush(QColor(192, 80, 77, 180))
# 设置坐标轴
self.custom_plot.xAxis.setLabel("季度")
self.custom_plot.yAxis.setLabel("销售额 (万元)")
self.custom_plot.xAxis.setRange(0, 4.5)
self.custom_plot.yAxis.setRange(0, 60)
# 设置刻度标签
self.custom_plot.xAxis.setTickVector([0.675, 1.675, 2.675, 3.675])
self.custom_plot.xAxis.setTickVectorLabels(categories)
# 添加图例
self.custom_plot.legend.setVisible(True)
self.bars1.setName("2022年")
self.bars2.setName("2023年")
# 添加网格
self.custom_plot.xAxis.grid().setVisible(True)
self.custom_plot.yAxis.grid().setVisible(True)
# 重绘图表
self.custom_plot.replot()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = BarChartDemo()
window.show()
sys.exit(app.exec_())
```
### 3. 散点图示例
```python
import sys
import numpy as np
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPen, QColor
from qcustomplot import QCustomPlot, QCPScatterStyle
class ScatterPlotDemo(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("散点图示例")
self.setGeometry(100, 100, 800, 600)
central_widget = QWidget()
self.setCentralWidget(central_widget)
layout = QVBoxLayout(central_widget)
self.custom_plot = QCustomPlot()
layout.addWidget(self.custom_plot)
# 创建三个散点图系列
self.graph1 = self.custom_plot.addGraph()
self.graph2 = self.custom_plot.addGraph()
self.graph3 = self.custom_plot.addGraph()
# 设置点样式
self.graph1.setScatterStyle(QCPScatterStyle(QCPScatterStyle.ssCircle, QPen(Qt.blue, 2), QBrush(Qt.blue), 10))
self.graph2.setScatterStyle(QCPScatterStyle(QCPScatterStyle.ssSquare, QPen(Qt.red, 2), QBrush(Qt.red), 10))
self.graph3.setScatterStyle(QCPScatterStyle(QCPScatterStyle.ssTriangle, QPen(Qt.green, 2), QBrush(Qt.green), 10))
# 不显示连接线
self.graph1.setLineStyle(QCPGraph.lsNone)
self.graph2.setLineStyle(QCPGraph.lsNone)
self.graph3.setLineStyle(QCPGraph.lsNone)
# 生成随机数据
np.random.seed(42)
x1 = np.random.normal(5, 1.5, 50)
y1 = np.random.normal(5, 1.5, 50)
x2 = np.random.normal(10, 1.5, 50)
y2 = np.random.normal(10, 1.5, 50)
x3 = np.random.normal(15, 1.5, 50)
y3 = np.random.normal(5, 1.5, 50)
# 设置数据
self.graph1.setData(x1, y1)
self.graph2.setData(x2, y2)
self.graph3.setData(x3, y3)
# 设置坐标轴
self.custom_plot.xAxis.setLabel("X 值")
self.custom_plot.yAxis.setLabel("Y 值")
self.custom_plot.xAxis.setRange(0, 20)
self.custom_plot.yAxis.setRange(0, 15)
# 添加图例
self.custom_plot.legend.setVisible(True)
self.graph1.setName("类别 A")
self.graph2.setName("类别 B")
self.graph3.setName("类别 C")
# 添加网格
self.custom_plot.xAxis.grid().setVisible(True)
self.custom_plot.yAxis.grid().setVisible(True)
# 重绘图表
self.custom_plot.replot()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = ScatterPlotDemo()
window.show()
sys.exit(app.exec_())
```
## 三、高级用法技巧
### 1. 实时数据更新
```python
from PyQt5.QtCore import QTimer
# 在初始化中添加
self.timer = QTimer()
self.timer.setInterval(100) # 更新间隔(毫秒)
self.timer.timeout.connect(self.update_data)
self.timer.start()
# 更新数据函数
def update_data(self):
# 获取新数据
new_x = current_time
new_y = get_current_value()
# 添加到图表
self.graph.addData(new_x, new_y)
# 移动X轴范围
self.custom_plot.xAxis.setRange(new_x - 10, new_x)
# 重绘
self.custom_plot.replot()
```
### 2. 添加交互功能
```python
# 启用拖拽和缩放
self.custom_plot.setInteractions(QCP.Interactions(
QCP.iRangeDrag | # 允许拖拽
QCP.iRangeZoom | # 允许缩放
QCP.iSelectPlottables # 允许选择图表元素
))
# 添加点击事件
self.custom_plot.mousePress.connect(self.on_mouse_press)
def on_mouse_press(self, event):
if event.button() == Qt.LeftButton:
# 获取点击位置坐标
x = self.custom_plot.xAxis.pixelToCoord(event.pos().x())
y = self.custom_plot.yAxis.pixelToCoord(event.pos().y())
print(f"Clicked at ({x:.2f}, {y:.2f})")
```
### 3. 保存图表为图片
```python
# 保存为PNG
self.custom_plot.savePng("chart.png", width=1920, height=1080)
# 保存为PDF
self.custom_plot.savePdf("chart.pdf", width=1920, height=1080)
# 保存为JPG
self.custom_plot.saveJpg("chart.jpg", width=1920, height=1080, quality=90)
```
### 4. 添加统计图例
```python
# 添加文本标签
text_label = QCPItemText(self.custom_plot)
text_label.position.setType(QCPItemPosition.ptAxisRectRatio)
text_label.position.setCoords(0.95, 0.05) # 右上角
text_label.setText("数据统计")
text_label.setTextAlignment(Qt.AlignRight|Qt.AlignTop)
text_label.setFont(QFont("Arial", 12))
# 添加统计值
stats_text = f"平均值: {mean_value:.2f}\n标准差: {std_dev:.2f}\n最大值: {max_value:.2f}"
text_label.setText(stats_text)
```
## 四、性能优化建议
1. **大数据集处理**:
```python
# 使用OpenGL加速
self.custom_plot.setOpenGl(True)
# 减少重绘次数
self.custom_plot.setNotAntialiasedElements(QCP.AE_All)
```
2. **数据采样**:
```python
# 当数据点过多时进行降采样
if len(x) > 10000:
indices = np.linspace(0, len(x)-1, 10000, dtype=int)
x = x[indices]
y = y[indices]
```
3. **异步更新**:
```python
from PyQt5.QtCore import QThread, pyqtSignal
class DataWorker(QThread):
data_ready = pyqtSignal(np.ndarray, np.ndarray)
def run(self):
while True:
# 获取数据
x, y = get_new_data()
self.data_ready.emit(x, y)
QThread.msleep(100)
```
QCustomPlot提供了丰富的图形类型和强大的定制能力,通过上述示例和技巧,您可以创建各种专业的数据可视化图表[^1][^2][^4]。
阅读全文
相关推荐



















