当前位置: 首页 > article >正文

Qt之基于QCustomPlot绘制直方图(Histogram),叠加正态分布曲线

文章目录

  • 任务目标
  • 理论知识
    • 1. 什么是统计直方图? 什么是正态分布曲线?两者有何关系与区别?
    • 参考案例:
    • 调用代码
    • 关键实现代码
  • 例程2

任务目标

在这里插入图片描述
在这里插入图片描述

封装一个图表库(PlotViewCtrl),基于QCustomPlot。

理论知识

1. 什么是统计直方图? 什么是正态分布曲线?两者有何关系与区别?

在这里插入图片描述

参考案例:

浅谈正态分布的起源与应用
【小结】常见血细胞分析仪的检测原理与直方图/散点图
在这里插入图片描述
在这里插入图片描述

调用代码

	// .h文件
	WidHistogram*			m_pWidHistogram = nullptr;
	
	// .cpp文件
	m_pWidHistogram = new WidHistogram(this);
	QHBoxLayout* pMainLayout = new QHBoxLayout(this);
	pMainLayout->addWidget(m_pWidHistogram);
	m_pWidHistogram->InitPlot_Histogram();

关键实现代码

void CstmPlot::InitPlot_Histogram()
{
	clearPlottables();
	legend->clearItems();
	setInteraction(QCP::iSelectPlottables, false);

	QVector<double> x(101), y(101);
	double mean = 0.0, stddev = 1.0;
	for (int i = 0; i < 101; ++i)
	{
		x[i] = -3 + i * 0.06;
		y[i] = exp(-0.5 * pow((x[i] - mean) / stddev, 2)) / (stddev * sqrt(2 * M_PI));
	}

	QCPBars* pBars = new QCPBars(xAxis, yAxis);
	pBars->setWidth(0.06);
	pBars->setData(x, y);
	pBars->setName("直方图");
	// 设置笔的颜色为蓝色
	pBars->setPen(QPen(QColor("#33A5FF"))); // Qt::gray
	// 设置画刷的颜色为蓝色,即实心
	pBars->setBrush(QBrush(Qt::blue));
#if 0
	// 使用 QCPCurve
	QCPCurve* pCurve = new QCPCurve(xAxis, yAxis);
	pCurve->setData(x, y);
	pCurve->setPen(QPen(Qt::red));
	pCurve->setName("正态曲线");
#else
	// 使用 QCPGraph
	QCPGraph* pGraph = addGraph(xAxis, yAxis);
	pGraph->setData(x, y);
	pGraph->setPen(QPen(QColor("#FF3333"), 1, Qt::SolidLine));
	pGraph->setName("正态曲线");
#endif

	rescaleAxes();
	replot();
}

例程2

// 引用头文件
#include <QApplication>
#include <QMainWindow>
#include <QChartView>
#include <QLineSeries> 
#include <QValueAxis>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QVector>
#include <QRandomGenerator>
#include <cmath>

#include "qcustomplot/qcustomplot.h"

int main(int argc, char* argv[])
{
	QApplication a(argc, argv);

	// 创建主窗口
	QMainWindow* mainWindow = new QMainWindow();
	QWidget* centralWidget = new QWidget(mainWindow);
	mainWindow->setCentralWidget(centralWidget);

	// 创建QCustomPlot对象
	//QCustomPlot* customPlot = new QCustomPlot(centralWidget);
	//customPlot->setMinimumSize(600, 400);

	// 创建折线图
	//QLineSeries* lineSeries = new QLineSeries();
	QVector<QPointF> points;
	for (int i = 0; i < 100; i++) {
		double x = i;
		double y = QRandomGenerator::global()->bounded(0, 100);
		points.append(QPointF(x, y));
	}
	//lineSeries->append(points);

	// 设置坐标轴
	//QValueAxis* axisX = new QValueAxis();
	//axisX->setLabelFormat("%d");
	//axisX->setTitleText("时间");
	//axisX->setRange(0, 100);
	//QValueAxis* axisY = new QValueAxis();
	//axisY->setLabelFormat("%d");
	//axisY->setTitleText("电压");
	//axisY->setRange(0, 100);

	// 添加折线图到QCustomPlot中
	//customPlot->addGraph();
	//customPlot->graph(0)->setData(points);
	//customPlot->graph(0)->setPen(QPen(Qt::blue));
	//customPlot->xAxis->setRange(0, 100);
	//customPlot->yAxis->setRange(0, 100);

	// 统计电压区间
	bool bFirstPt = true;

	QVector<double> count(10, 0);
	double maxVoltage = 0;
	double minVoltage = 100;
	for (int i = 0; i < points.size(); i++) {
		double voltage = points[i].y();
		if (voltage > maxVoltage) {
			maxVoltage = voltage;
		}
		if (voltage < minVoltage) {
			minVoltage = voltage;
		}
		if (bFirstPt)
		{
			bFirstPt = false;
		}
		else 
		{
			int index = (voltage - minVoltage) / (maxVoltage - minVoltage) * 10;
			if (index == 10) {
				index--;
			}
			count[index]++;
		}
	}

	// 绘制直方图
	QCustomPlot* histogram = new QCustomPlot(centralWidget);
	histogram->setMinimumSize(600, 400);
	QCPBars* bars = new QCPBars(histogram->xAxis, histogram->yAxis);
	QVector<double> ticks(10);
	QVector<QString> labels(10);
	for (int i = 0; i < 10; i++) {
		ticks[i] = i + 0.5;
		labels[i] = QString::number(minVoltage + (maxVoltage - minVoltage) / 10 * i, 'f', 2);
	}

	QSharedPointer<QCPAxisTicker> ticker(new QCPAxisTicker);
	histogram->xAxis->setTicker(ticker);
	histogram->xAxis->ticker()->setTickCount(10);


	//histogram->xAxis->setAutoTicks(false);
	//histogram->xAxis->setAutoTickLabels(false);
	//histogram->xAxis->setTickVector(ticks);
	//histogram->xAxis->setTickVectorLabels(labels);
	histogram->xAxis->setTickLabelRotation(60);
	bars->setData(ticks, count);
	histogram->rescaleAxes();
	histogram->xAxis->setRange(QCPRange(-0.1, 10.1));
	histogram->replot();

	// 绘制正态曲线图
	QCustomPlot* normalCurve = new QCustomPlot(centralWidget);
	normalCurve->setMinimumSize(600, 400);
	QVector<double> x(1000), y(1000);
	double mean = (maxVoltage + minVoltage) / 2;
	double stdDev = (maxVoltage - minVoltage) / 6;
	for (int i = 0; i < 1000; i++) {
		x[i] = minVoltage + (maxVoltage - minVoltage) / 1000 * i;
		y[i] = exp(-(x[i] - mean) * (x[i] - mean) / (2 * stdDev * stdDev)) / (stdDev * sqrt(2 * M_PI));
	}
	QCPGraph* graph = normalCurve->addGraph();
	graph->setData(x, y);
	normalCurve->rescaleAxes();
	normalCurve->replot();

	// 将QCustomPlot添加到主窗口中
	QHBoxLayout* layout = new QHBoxLayout();
	//layout->addWidget(customPlot);
	layout->addWidget(histogram);
	layout->addWidget(normalCurve);
	centralWidget->setLayout(layout);

	// 显示主窗口
	mainWindow->show();

	return a.exec();
}

http://www.kler.cn/a/162126.html

相关文章:

  • Python多进程间通讯(包含共享内存方式)
  • 【STM32】基于SPI协议读写SD,详解!
  • GitLab基于Drone搭建持续集成(CI/CD)
  • LeetCode【0014】最长公共前缀
  • 彻底理解ARXML中的PDU
  • 如何查看电脑关机时间
  • vmware安装centos7总结
  • VSCODE 运行C程序缓慢解决方法之一
  • Ubuntu22.04安装Mariadb
  • C语言printf的输出格式大全及颜色字体打印
  • 微信小程序中block和View组件的使用区别
  • AI发展下服务器的选择非常重要
  • mysql 链接超时的几个参数详解
  • 嵌入式总线技术学习(文章链接汇总)
  • C语言——指针(五)
  • 【C/PTA —— 15.结构体2(课内实践)】
  • 3D材质编辑:制作被火烧的木头
  • ERP数据仓库模型
  • 数学建模-二氧化碳排放及时空分布测度
  • Ubuntu安装nvidia GPU显卡驱动教程
  • SAP数据一键拉取!利用零代码ETL工具快速实现数据同步
  • 【C/PTA —— 15.结构体2(课外实践)】
  • CPU密集型和IO密集型与CPU内核之间的关系
  • Fabric 画布缩放、拖动、初始化大小
  • 人工智能_机器学习059_非线性核函数_poly核函数_rbf核函数_以及linear核函数效果对比---人工智能工作笔记0099
  • Docker快速入门(编译源码辅助技)