https://blog.csdn.net/llq108/article/details/45603047
https://blog.csdn.net/llq108/article/details/45622285
介绍
QCustomPlot 是一个基于Qt的画图和数据可视化C++控件。QCustomPlot 致力于提供美观的界面,高质量的2D画图、图画和图表,同时为实时数据可视化应用提供良好的解决方案。
类相关
继承
获取
下载地址:http://qcustomplot.com/index.php/download,QCustomPlot.tar.gz,目前更新到1.3.1版本。
官网:http://qcustomplot.com/index.php/introduction
论坛:http://qcustomplot.com/index.php/support/forum
使用
在你的应用中使用QCustomPlot 有2种方法:
1、将下载下来的qcustomplot.h和qcustomplot.cpp加入你的工程中。在你要使用qcustomplot的文件中:
#include "qcustomplot.h"
然后像使用QWidget那样使用就行,因为QCustomPlot也是继承自QWidget的:
QCustomplot *myqcp = new QCustomPlot;
使用Qt Designer的话,在一个QWidget控件右键,提升为...,
然后在弹出的对话框中,在提升为类名那里输入QCustomPlot,然后头文件那里会自动填充为qcustomplot.h。单击添加按钮将QCustomPlot加入提升类列表中,最后单击提升就可以了。
注意:提升之后不会立即看到什么变化,但当你运行程序的时候,你就能看到控件具有坐标和网格了。
2、不用包含 qcustomplot.h和 qcustomplot.cpp,只需引入qcustomplot.so (GNU/Linux)或qcustomplot.dll(MSWindows) file。接下来说明如何编译qcustomplot库:首先,从下载地址下载QCustomPlot-sharedlib,然后拷贝qcustomplot.h和qcustomplot.cpp到与qcustomplot-sharedlib同级的目录下,然后在命令行模式进入sharedlib-compilation目录,运行qmake;mingw32-make;稍等片刻就会产生俩个文件夹debug和release,里面分别有qcustomplot库的debug和release版本,windows是.dll,linux是.a(而官网说的是.so,有点出入?)然后怎么使用qcustomplot很简单,我就不说了- -
注意:如果你使用的Qt版本在5.0以上,需要在.pro文件中的QT变量加上printsupport,
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport
这是因为Qt老版本不支持widgets和printsupport。
在QtCreator中使用帮助
在第二步下载的documentation文件夹下有个qcustomplot.qch文件,将它拷贝某个目录下,例如QtCreator的安装目录下,然后在QtCreator ,工具,选项,帮助,文档,添加,选择qcustomplot.qch文件,确定,以后按F1就能跳转到QCustomPlot的帮助文档了。
效果
好了,第一篇,主要介绍QCustomPlot和它的搭建。
一、基本画图
首先,给个简单的例子:
-
// 生成数据,画出的是抛物线
-
QVector<double> x(101), y(101);
// initialize with entries 0..100
-
for (
int i=
0; i<
101; ++i)
-
{
-
x[i] = i/
50.0 -
1;
// x goes from -1 to 1
-
y[i] = x[i]*x[i];
// let's plot a quadratic function
-
}
-
// 添加数据曲线(一个图像可以有多个数据曲线)
-
customPlot->addGraph();
-
// graph(0);可以获取某个数据曲线(按添加先后排序)
-
// setData();为数据曲线关联数据
-
customPlot->graph(
0)->setData(x, y);
-
// 为坐标轴添加标签
-
customPlot->xAxis->setLabel(
"x");
-
customPlot->yAxis->setLabel(
"y");
-
// 设置坐标轴的范围,以看到所有数据
-
customPlot->xAxis->setRange(
-1,
1);
-
customPlot->yAxis->setRange(
0,
1);
-
// 重画图像
-
customPlot->replot();
上面代码生成的结果大致是这样的:
外观
QCustomPlot的外观由很多方面特性组成,都可以改变:
坐标轴:
QCustomPlot有四个QCPAxis成员变量,分别代表四个坐标轴:xAxis(下)yAxis(左)xAxis2(上)yAxis2(右)
QCPAxis有相应的函数可以设置坐标轴的刻度、间距、范围等:
-
setTickStep(
double step);
//设置刻度间距
-
setTickVector(
const QVector<
double> &vec);
//将坐标轴刻度设置为vec
-
setAutoTickStep(
bool on);
//设置是否自动分配刻度间距
-
setAutoTicks(
bool on);
//设置是否自动分配刻度
-
setAutoTickCount(
int approximateCount);
//设置是否自动分配刻度数量
还有setBasePen、setTickPen、setTickLength、setSubTickLength、setSubTickPen、setTickLabelFont、setLabelFont、setTickLabelPadding、setLabelPadding、setRangeReversed等
等后面专门讲QCPAxis的时候再详细介绍
曲线风格:
QCPGraph::setPen(const QPen &pen);
曲线画笔:
QCPGraph::setLineStyle(LineStyle ls);
可以设置颜色、宽度、实虚等
曲线形状:
QCPGraph::setScatterStyle(QCPScatterStyle &style);
曲线形状像*、+、x、o等等
填充曲线方式:
QCPGraph::setBrush(const QBrush &brush);
QCPGraph::setChannelFillGraph(otherGraph);//设置与某之间曲线填充
QCPGraph::setBrush(Qt::NoBrush);//移除填充
以上会等到专门将QCPGraph和QCPScatterStyle类的时候再细讲网格:
customPlot->yAxis->grid();
setPen、setZeroLinePen、setSubGridVisible等
等讲QCPGrid类再细讲
二、高级画图
1、多曲线与多风格
-
<pre name=
"code" class=
"cpp">customPlot->setLocale(QLocale(QLocale::English, QLocale::UnitedKingdom));
// period as decimal separator and comma as thousand separator
-
customPlot->legend->setVisible(
true);
-
QFont legendFont = font();
// start out with MainWindow's font..
-
legendFont.setPointSize(
9);
// and make a bit smaller for legend
-
customPlot->legend->setFont(legendFont);
-
customPlot->legend->setBrush(QBrush(QColor(
255,
255,
255,
230)));
-
// by default, the legend is in the inset layout of the main axis rect. So this is how we access it to change legend placement:
-
customPlot->axisRect()->insetLayout()->setInsetAlignment(
0, Qt::AlignBottom|Qt::AlignRight);
-
-
// setup for graph 0: key axis left, value axis bottom
-
// will contain left maxwell-like function
-
customPlot->addGraph(customPlot->yAxis, customPlot->xAxis);
-
customPlot->graph(
0)->setPen(QPen(QColor(
255,
100,
0)));
-
customPlot->graph(
0)->setBrush(QBrush(QPixmap(
"./dali.png")));
// fill with texture of specified png-image
-
customPlot->graph(
0)->setLineStyle(QCPGraph::lsLine);
-
customPlot->graph(
0)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssDisc,
5));
-
customPlot->graph(
0)->setName(
"Left maxwell function");
-
-
// setup for graph 1: key axis bottom, value axis left (those are the default axes)
-
// will contain bottom maxwell-like function
-
customPlot->addGraph();
-
customPlot->graph(
1)->setPen(QPen(Qt::red));
-
customPlot->graph(
1)->setBrush(QBrush(QPixmap(
"./dali.png")));
// same fill as we used for graph 0
-
customPlot->graph(
1)->setLineStyle(QCPGraph::lsStepCenter);
-
customPlot->graph(
1)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, Qt::red, Qt::white,
7));
-
customPlot->graph(
1)->setErrorType(QCPGraph::etValue);
-
customPlot->graph(
1)->setName(
"Bottom maxwell function");
-
-
// setup for graph 2: key axis top, value axis right
-
// will contain high frequency sine with low frequency beating:
-
customPlot->addGraph(customPlot->xAxis2, customPlot->yAxis2);
-
customPlot->graph(
2)->setPen(QPen(Qt::blue));
-
customPlot->graph(
2)->setName(
"High frequency sine");
-
-
// setup for graph 3: same axes as graph 2
-
// will contain low frequency beating envelope of graph 2
-
customPlot->addGraph(customPlot->xAxis2, customPlot->yAxis2);
-
QPen blueDotPen;
-
blueDotPen.setColor(QColor(
30,
40,
255,
150));
-
blueDotPen.setStyle(Qt::DotLine);
-
blueDotPen.setWidthF(
4);
-
customPlot->graph(
3)->setPen(blueDotPen);
-
customPlot->graph(
3)->setName(
"Sine envelope");
-
-
// setup for graph 4: key axis right, value axis top
-
// will contain parabolically distributed data points with some random perturbance
-
customPlot->addGraph(customPlot->yAxis2, customPlot->xAxis2);
-
customPlot->graph(
4)->setPen(QColor(
50,
50,
50,
255));
-
customPlot->graph(
4)->setLineStyle(QCPGraph::lsNone);
-
customPlot->graph(
4)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle,
4));
-
customPlot->graph(
4)->setName(
"Some random data around\na quadratic function");
-
-
// generate data, just playing with numbers, not much to learn here:
-
QVector<double> x0(25), y0(25);
-
QVector<double> x1(15), y1(15), y1err(15);
-
QVector<double> x2(250), y2(250);
-
QVector<double> x3(250), y3(250);
-
QVector<double> x4(250), y4(250);
-
for (
int i=
0; i<
25; ++i)
// data for graph 0
-
{
-
x0[i] =
3*i/
25.0;
-
y0[i] =
exp(-x0[i]*x0[i]*
0.8)*(x0[i]*x0[i]+x0[i]);
-
}
-
for (
int i=
0; i<
15; ++i)
// data for graph 1
-
{
-
x1[i] =
3*i/
15.0;;
-
y1[i] =
exp(-x1[i]*x1[i])*(x1[i]*x1[i])*
2.6;
-
y1err[i] = y1[i]*
0.25;
-
}
-
for (
int i=
0; i<
250; ++i)
// data for graphs 2, 3 and 4
-
{
-
x2[i] = i/
250.0*
3*M_PI;
-
x3[i] = x2[i];
-
x4[i] = i/
250.0*
100
-50;
-
y2[i] =
sin(x2[i]*
12)*
cos(x2[i])*
10;
-
y3[i] =
cos(x3[i])*
10;
-
y4[i] =
0.01*x4[i]*x4[i] +
1.5*(rand()/(
double)RAND_MAX
-0.5) +
1.5*M_PI;
-
}
-
-
// pass data points to graphs:
-
customPlot->graph(
0)->setData(x0, y0);
-
customPlot->graph(
1)->setDataValueError(x1, y1, y1err);
-
customPlot->graph(
2)->setData(x2, y2);
-
customPlot->graph(
3)->setData(x3, y3);
-
customPlot->graph(
4)->setData(x4, y4);
-
// activate top and right axes, which are invisible by default:
-
customPlot->xAxis2->setVisible(
true);
-
customPlot->yAxis2->setVisible(
true);
-
// set ranges appropriate to show data:
-
customPlot->xAxis->setRange(
0,
2.7);
-
customPlot->yAxis->setRange(
0,
2.6);
-
customPlot->xAxis2->setRange(
0,
3.0*M_PI);
-
customPlot->yAxis2->setRange(
-70,
35);
-
// set pi ticks on top axis:
-
QVector<
double> piTicks;
-
QVector<QString> piLabels;
-
piTicks <<
0 <<
0.5*M_PI << M_PI <<
1.5*M_PI <<
2*M_PI <<
2.5*M_PI <<
3*M_PI;
-
piLabels <<
"0" << QString::fromUtf8(
"½π") << QString::fromUtf8(
"π") << QString::fromUtf8(
"1½π") << QString::fromUtf8(
"2π") << QString::fromUtf8(
"2½π") << QString::fromUtf8(
"3π");
-
customPlot->xAxis2->setAutoTicks(
false);
-
customPlot->xAxis2->setAutoTickLabels(
false);
-
customPlot->xAxis2->setTickVector(piTicks);
-
customPlot->xAxis2->setTickVectorLabels(piLabels);
-
// add title layout element:
-
customPlot->plotLayout()->insertRow(
0);
-
customPlot->plotLayout()->addElement(
0,
0,
new QCPPlotTitle(customPlot,
"Way too many graphs in one plot"));
-
// set labels:
-
customPlot->xAxis->setLabel(
"Bottom axis with outward ticks");
-
customPlot->yAxis->setLabel(
"Left axis label");
-
customPlot->xAxis2->setLabel(
"Top axis label");
-
customPlot->yAxis2->setLabel(
"Right axis label");
-
// make ticks on bottom axis go outward:
-
customPlot->xAxis->setTickLength(
0,
5);
-
customPlot->xAxis->setSubTickLength(
0,
3);
-
// make ticks on right axis go inward and outward:
-
customPlot->yAxis2->setTickLength(
3,
3);
-
customPlot->yAxis2->setSubTickLength(
1,
1);
效果图:
2、日期和时间数据曲线
-
// set locale to english, so we get english month names:
-
customPlot->setLocale(QLocale(QLocale::English, QLocale::UnitedKingdom));
-
// seconds of current time, we'll use it as starting point in time for data:
-
double now = QDateTime::currentDateTime().toTime_t();
-
srand(
8);
// set the random seed, so we always get the same random data
-
// create multiple graphs:
-
for (
int gi=
0; gi<
5; ++gi)
-
{
-
customPlot->addGraph();
-
QPen pen;
-
pen.setColor(QColor(
0,
0,
255,
200));
-
customPlot->graph()->setLineStyle(QCPGraph::lsLine);
-
customPlot->graph()->setPen(pen);
-
customPlot->graph()->setBrush(QBrush(QColor(
255/
4.0*gi,
160,
50,
150)));
-
// generate random walk data:
-
QVector<double> time(250), value(250);
-
for (
int i=
0; i<
250; ++i)
-
{
-
time[i] = now +
24*
3600*i;
-
if (i ==
0)
-
value[i] = (i/
50.0+
1)*(rand()/(
double)RAND_MAX
-0.5);
-
else
-
value[i] =
fabs(value[i
-1])*(
1+
0.02/
4.0*(
4-gi)) + (i/
50.0+
1)*(rand()/(
double)RAND_MAX
-0.5);
-
}
-
customPlot->graph()->setData(time, value);
-
}
-
// configure bottom axis to show date and time instead of number:
-
customPlot->xAxis->setTickLabelType(QCPAxis::ltDateTime);
-
customPlot->xAxis->setDateTimeFormat(
"MMMM\nyyyy");
-
// set a more compact font size for bottom and left axis tick labels:
-
customPlot->xAxis->setTickLabelFont(QFont(QFont().family(),
8));
-
customPlot->yAxis->setTickLabelFont(QFont(QFont().family(),
8));
-
// set a fixed tick-step to one tick per month:
-
customPlot->xAxis->setAutoTickStep(
false);
-
customPlot->xAxis->setTickStep(
2628000);
// one month in seconds
-
customPlot->xAxis->setSubTickCount(
3);
-
// apply manual tick and tick label for left axis:
-
customPlot->yAxis->setAutoTicks(
false);
-
customPlot->yAxis->setAutoTickLabels(
false);
-
customPlot->yAxis->setTickVector(QVector<
double>() <<
5 <<
55);
-
customPlot->yAxis->setTickVectorLabels(QVector<QString>() <<
"Not so\nhigh" <<
"Very\nhigh");
-
// set axis labels:
-
customPlot->xAxis->setLabel(
"Date");
-
customPlot->yAxis->setLabel(
"Random wobbly lines value");
-
// make top and right axes visible but without ticks and labels:
-
customPlot->xAxis2->setVisible(
true);
-
customPlot->yAxis2->setVisible(
true);
-
customPlot->xAxis2->setTicks(
false);
-
customPlot->yAxis2->setTicks(
false);
-
customPlot->xAxis2->setTickLabels(
false);
-
customPlot->yAxis2->setTickLabels(
false);
-
// set axis ranges to show all data:
-
customPlot->xAxis->setRange(now, now+
24*
3600*
249);
-
customPlot->yAxis->setRange(
0,
60);
-
// show legend:
-
customPlot->legend->setVisible(
true);
效果图:
三、曲线、柱形图、统计图...
到目前为止,我们为图像添加曲线都是使用
其实,除了 QCPGraph ,QCustomPlot 还提供了多个画图类:
QCustomPlot::addGraph(); QCustomPlot::graph();
QCPCurve:与QCPGraph 类似,差别在于它是用于展示参数化曲线,可以有循环。
QCPBars:柱形图,如果有多个QCPBars ,可以依次重叠。
QCPStatisticalBox、QCPColorMap、QCPFinancial
与QCPGraph 不同的是,这些画图类在添加到QCustomPlot 的时候需要使用new创建一个实例,而不能直接
<span style="color: rgb(53, 53, 53); font-family: monospace; line-height: 19.5px; background-color: rgb(240, 240, 240);">addPlottable</span>();
简单例子如下:
-
QCPBars *myBars =
new QCPBars(customPlot->xAxis, customPlot->yAxis);
-
customPlot->addPlottable(myBars);
-
// now we can modify properties of myBars:
-
myBars->setName(
"Bars Series 1");
-
QVector<
double> keyData;
-
QVector<
double> valueData;
-
keyData <<
1 <<
2 <<
3;
-
valueData <<
2 <<
4 <<
8;
-
myBars->setData(keyData, valueData);
-
customPlot->rescaleAxes();
-
customPlot->replot();
好吧,这篇就到这里。水平有限,如有出错,敬请指出,互相学习。