Vous êtes sur la page 1sur 29

1)

Qt Documentation

Qt 5.7

Qt Charts

LineChart Example

Reference

All Qt C++ Classes


All QML Types
All Qt Modules
Qt Creator Manual
All Qt Reference Documentation
Getting Started

Getting Started with Qt


What's New in Qt 5
Examples and Tutorials
Supported Platforms
Qt Licensing
Overviews

Development Tools
User Interfaces
Core Internals
Data Storage
Multimedia
Networking and Connectivity
Graphics
Mobile APIs
QML Applications
All Qt Overviews

LineChart Example

To create a line chart, a QLineSeries instance is needed. Let's create one.


QLineSeries *series = new QLineSeries();
Then we add data to the series. We can use the append() member function or use the stream operator.
series->append(0, 6);
series->append(2, 4);
series->append(3, 8);
series->append(7, 4);
series->append(10, 5);
*series << QPointF(11, 1) << QPointF(13, 3) << QPointF(17, 6) << QPointF(18, 3) <<
QPointF(20, 2);
To present the data on the chart we need a QChart instance. We add the series to it, create the default axes, and set the
title of the chart.
QChart *chart = new QChart();
chart->legend()->hide();
chart->addSeries(series);
chart->createDefaultAxes();
chart->setTitle("Simple line chart example");
Then we create a QChartView object with QChart as a parameter. This way we don't need to create aQGraphicsView scene
ourselves. We also set the Antialiasing on to have the rendered lines look nicer.
QChartView *chartView = new QChartView(chart);
chartView->setRenderHint(QPainter::Antialiasing);
The chart is ready to be shown.
QMainWindow window;
window.setCentralWidget(chartView);

window.resize(400, 300);
window.show();
Files:

linechart/main.cpp
linechart/linechart.pro

Qt Documentation

Qt 5.7

Qt Charts

LineChart Example

main.cpp Example File

Reference

All Qt C++ Classes


All QML Types
All Qt Modules
Qt Creator Manual
All Qt Reference Documentation
Getting Started

Getting Started with Qt


What's New in Qt 5
Examples and Tutorials
Supported Platforms
Qt Licensing
Overviews

Development Tools
User Interfaces
Core Internals
Data Storage
Multimedia
Networking and Connectivity
Graphics
Mobile APIs
QML Applications

All Qt Overviews

main.cpp Example File


linechart/main.cpp
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Charts module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 or (at your option) any later version
** approved by the KDE Free Qt Foundation. The licenses are as published by
** the Free Software Foundation and appearing in the file LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include
#include
#include
#include

<QtWidgets/QApplication>
<QtWidgets/QMainWindow>
<QtCharts/QChartView>
<QtCharts/QLineSeries>

QT_CHARTS_USE_NAMESPACE
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QLineSeries *series = new QLineSeries();
series->append(0, 6);
series->append(2, 4);
series->append(3, 8);
series->append(7, 4);
series->append(10, 5);
*series << QPointF(11, 1) << QPointF(13, 3) << QPointF(17, 6) << QPointF(18, 3) <<
QPointF(20, 2);
QChart *chart = new QChart();
chart->legend()->hide();
chart->addSeries(series);
chart->createDefaultAxes();

chart->setTitle("Simple line chart example");


QChartView *chartView = new QChartView(chart);
chartView->setRenderHint(QPainter::Antialiasing);
QMainWindow window;
window.setCentralWidget(chartView);
window.resize(400, 300);
window.show();
return a.exec();
}
2016 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is
licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks
of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.

Qt Documentation

Qt 5.7

Qt Charts

LineChart Example

linechart.pro Example File

Reference

All Qt C++ Classes


All QML Types
All Qt Modules
Qt Creator Manual
All Qt Reference Documentation
Getting Started

Getting Started with Qt


What's New in Qt 5
Examples and Tutorials
Supported Platforms
Qt Licensing
Overviews

Development Tools
User Interfaces
Core Internals
Data Storage

Multimedia
Networking and Connectivity
Graphics
Mobile APIs
QML Applications
All Qt Overviews

linechart.pro Example File


linechart/linechart.pro
!include( ../examples.pri ) {
error( "Couldn't find the examples.pri file!" )
}
TARGET = linechart
SOURCES += main.cpp

2016 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the
terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in
Finland and/or other countries worldwide. All other trademarks are property of their respective owners.

Download

2)

Qt plotting widget
Contents
1 Demo Screenshots
2 Setup

2.1 For QtCreator users

2.2 As shared library .so/.dll


2.3 Running the examples

3 Documentation
4 Basic usage
4.1 Changing the look

5 Examples

5.1 Simple plot of two graphs

5.2 Plotting with multiple axes and more advanced styling


5.3 Plotting date/time data

6 Beyond Graphs: Curves, Bar Charts, Statistical Box Plot,


7 Items
8 User interaction
9 Unfinished but planned features
10 Download
10.1 Older releases

11 Quo Vadis QCP?

So you just want a simple plotting widget for Qt.

QCustomPlot is a rather compact Qt widget for plotting, with the possibility of extension to your needs. It has no further dependencies and is fully
documented (including internal functions). If you use QtCreator you just drop a QWidget on your form as a placeholder and promote it to
a QCustomPlot, and it just works. All others can create QCustomPlot widgets like any other widget in their application.
This library concentrates on making good looking, publication quality 2D plots, and offering high performance for realtime visualization applications.

The default license is the GPL. If you need a different license like LGPL, please contact me via E-Mail, Im sure well find an arrangement.
Version 1.0.0-beta was released on 19.5.2013, see the news section.

Demo Screenshots
Here are some demo screenshots showing what can be achieved with QCustomPlot in only a few lines of code. You can get the code of all those plots in
the download section below, as an example project for QtCreator. People who dont use QtCreator can profit from them equally, just look at the
mainwindow.cpp file.

A simple decaying sine function with fill and its exponential envelope in red

sinc function with randomly (gaussian) perturbed data points, corresponding error bars and a 2-sigma confidence band.

A demonstration of all currently built-in scatter points (except pixmap scatters).

Pixmap scatter points and multi lined axis labeling as well as a plot title at the top

real time generated data srolling right and automatically adjusting vertical axis as it goes.

Multiple plot styles with different key/value axes and manual tick labeling (top axis)

Logarithmic axis scaling (here the y axis) with four functions. Note the sine function crossing zero in negative infinity

A demonstration of all currently built-in line styles.

Some random walks as a time series and date mode for bottom axis.

Parametric curves with translucent gradient filling

Three stacked bar charts with manual x axis tick labels

Statistical 5-parameter-box-plot with outliers

The interaction example showing the selection mechanism for graphs

Using items like text labels, arrows and a bracket. This is actually animated, see examples-project

QCustomPlot supports exporting its content as a vectorized PDF or PS file and rasterized image formats like PNG, JPG and BMP. All outputs look
identical and the generated PDF files can be imported and edited by vector editors like Inkscape, without trouble. So QCustomPlot is useful for both
displaying of e.g. realtime data inside the application as well as producing publication quality plots for other media.

Setup

Get the latest version of QCustomPlot from the download section at the bottom of this page.

Use the qcustomplot.h and .cpp file like any other ordinary class file

For QtCreator users

Right click on your root project directory in the left sidebar, click the Add existing file (or similar) menu item. In the appearing file dialog,
select the qcustomplot.h and .cpp file, to add them to your project

place a QWidget on your form in the desired location. Right click on it and promote it to QCustomPlot. You wont see any immediate visual
changes in QtCreator, but while running the application, you should see an empty plot with axis and grid.

As shared library .so/.dll


If you rather want to use QCustomPlot as a shared library, i.e. dont want to include the .h/.cpp file into your project directly but link with an external .so
or .dll file, this is possible, too. QCustomPlot is ready to be built as a shared library by setting the compiler
defineQCUSTOMPLOT_COMPILE_LIBRARY. To use the shared library, set the define QCUSTOMPLOT_USE_LIBRARY before including the header.
The sharedlib package (see download section) includes two projects that demonstrate this: one compiles the shared QCustomPlot library and the other
uses the shared library.

Running the examples


The QCustomPlot.tar.gz package in the download section contains the QCustomPlot source files and the example projects ready to be compiled. Just
extract the whole package to a new directory, navigate inside the example directories and run qmake; make. Alternatively you can of course open the
.pro files in QtCreator and run them from there.

Documentation
The complete API documentation is available either online, or as a package in the download section. The package contains the documentation as a HTML
hierarchy (the same you access online) and as a qch-help file for QtCreator/Assistant integration. If you use QtCreator or Assistant, you should definetly
consider using the qch-help file, its great!
The integration of the qch file is pretty straight forward: Copy the qcustomplot.qch file to a place where it should be stored (e.g. the local QtCreator
config directory). In QtCreator, go to the program settings and find the help section. In the tab Documentation or similar, you see a list of loaded
documentation modules and some buttons to add/remove modules. Click the add button and select the qcustomplot.qch file. Thats it!
Now, when you place the cursor on any QCustomPlot related class or function, press F1 and you find help just like you know it from Qt components.

Basic usage
Heres the concept: QCustomPlot has four axes: xAxis, yAxis, xAxis2, yAxis2 of type QCPAxis, corresponding to bottom, left, top and right axis.
You first create a graph (with QCustomPlot::addGraph), then you assign the graph some data points (e.g. as a pair of QVector<double> for x and y
values) and define the look of the graph (line style, scatter symbol, color, line pen, scatter size, filling).
finally, call QCustomPlot::replot. Note that replot will be called automatically when the widget is resized and when the built-in user interactions are
triggered (basically dragging axis ranges with mouse and zooming with mouse wheel).
Heres a minimal example, customPlot is a pointer to our QCustomPlot widget:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

// generate some data:


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
}
// create graph and assign data to it:
customPlot->addGraph();
customPlot->graph(0)->setData(x, y);
// give the axes some labels:
customPlot->xAxis->setLabel("x");
customPlot->yAxis->setLabel("y");
// set axes ranges, so we see all data:
customPlot->xAxis->setRange(-1, 1);
customPlot->yAxis->setRange(0, 1);
customPlot->replot();

16
17
The output should look something like shown below. Note that the choice at what x and y positions the tick marks are, is done automatically.
QCustomPlot takes into account, that multiples of two as well as numbers alternating between five and zero in the lowest digit are nice to look at. You can
take full control over the tick-step and even the single tick mark positions by calling setTickStep or setTickVector. For disabling/enabling the
automation, call setAutoTickStep or setAutoTicks. If you just want to change the approximate tick count in the visible range, while leaving the details to
the algorithm, use setAutoTickCount.

Youll see that the tick labels of the axes are not truncated even when the numbers get larger. This is due to the automatic margin calculation, which is
turned on by default. If you dont wish that the axis margin (the distance between the widget border and the axis base line) is determined automatically,
switch it off with QCustomPlot::setAutoMargin. Then you can adjust the margin manually via for example QCustomPlot::setMarginLeft. analog
functions exist for the top, right and bottom margins, or for all sides in one function as setMargin(left, right, top, bottom).

Changing the look


The look of the graph is characterized by many factors, all of which can be modified. Here are the most important ones:

Line style: Call QCPGraph::setLineStyle(QCPGraph::LineStyle ls). For all possible line styles, see the LineStyle documentation or the line
style demo screenshot above.

Scatter symbol style: Call QCPGraph::setScatterStyle(QCP::ScatterStyle ss). For all possible scatter styles, see
the ScatterStyledocumentation or the scatter style demo screenshot above (ssPixmap style not shown there).

Scatter symbol size: floating point pixel size of the scatter symbols. QCPGraph::setScatterSize(double size)

Line specifics: all pens the QPainter-framework provides are available, e.g. solid, dashed, dotted, different widths, colors, transparency, etc.
Set the configured pen via QCPGraph::setPen(const QPen &p)

Fills under graph or between two graphs: All brushes the QPainter-framework provides, solid, various patterns, textures, gradients,
colors, transpareny, etc. Set the configured brush via QCPGraph::setBrush(const QBrush &b)
The look of the axis and grid lines can also be modified by changing the pens they are painted with and the fonts their labels use. A look at
thedocumentation of QCPAxis should be self-explanatory now, heres a quick summary of the most important
properties: setBasePen, setGridPen,setSubGridPen, setZeroLinePen, setTickPen, setTickLength, setSubTickLength, setSubTickPen, setTickLabelFo
nt, setLabelFont,setTickLabelPadding, setLabelPadding.

You can reverse an axis (e.g. make the values decrease instead of increase from left to right on a horizontal axis) with setRangeReversed.

Examples
Simple plot of two graphs
Heres an example which creates the image of the decaying cosine function with its exponential envelope, as shown in the Demo Screenshots section.

1
2
3
4
5
6

// For simplicity we'll just setup all data and plotting options here
// add two new graphs and set their look:
customPlot->addGraph();
customPlot->graph(0)->setPen(QPen(Qt::blue)); // line color blue for first graph
customPlot->graph(0)->setBrush(QBrush(QColor(0, 0, 255, 20))); // first graph will be
filled with translucent blue
customPlot->addGraph();

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph


// generate some points of data (y0 for first, y1 for second graph):
QVector<double> x(250), y0(250), y1(250);
for (int i=0; i<250; ++i)
{
x[i] = i;
y0[i] = exp(-i/150.0)*cos(i/10.0); // exponentially decaying cosine
y1[i] = exp(-i/150.0);
// exponential envelope
}
// configure right and top axis to show ticks but no labels (could've also just
called customPlot->setupFullAxesBox):
customPlot->xAxis2->setVisible(true);
customPlot->xAxis2->setTickLabels(false);
customPlot->yAxis2->setVisible(true);
customPlot->yAxis2->setTickLabels(false);
// make left and bottom axes always transfer their ranges to right and top axes:
connect(customPlot->xAxis, SIGNAL(rangeChanged(QCPRange)), customPlot->xAxis2,
SLOT(setRange(QCPRange)));
connect(customPlot->yAxis, SIGNAL(rangeChanged(QCPRange)), customPlot->yAxis2,
SLOT(setRange(QCPRange)));
// pass data points to graphs:
customPlot->graph(0)->setData(x, y0);
customPlot->graph(1)->setData(x, y1);
// let the ranges scale themselves so graph 0 fits perfectly in the visible area:
customPlot->graph(0)->rescaleAxes();
// same thing for graph 1, but only enlarge ranges (in case graph 1 is smaller than
graph 0):
customPlot->graph(1)->rescaleAxes(true);
// Note: we could have also just called customPlot->rescaleAxes(); instead
// make range moveable by mouse interaction (click and drag):
customPlot->setRangeDrag(Qt::Horizontal | Qt::Vertical);
customPlot->setRangeZoom(Qt::Horizontal | Qt::Vertical);
customPlot->setInteraction(QCustomPlot::iSelectPlottables); // allow selection of
graphs via mouse click
customPlot->replot();

As you can see, applying a fill to a graph is as easy as setting a brush that is not Qt::NoBrush. The fill will go from the graph (here graph 0) to the zerovalue-line parallel to the key (here x) axis. If we wanted a channel fill between two graphs, we would additionally
callQCPGraph::setChannelFillGraph(otherGraph), where otherGraph is, you guessed it, the other graph ;). To remove the channel fill, just pass 0 as
other graph, and the fill will reach all the way to the zero-value-line as before. To remove the fill completely, call QCPGraph::setBrush(Qt::NoBrush).
For opaque channel fills you will get best looking results if the graph on which the setChannelFillGraph function is called, was created before the other
graph. Because then its guaranteed, the other graphs line is drawn above the border of the fill. Else, the fill might obscure half the line of the other
graph, which doesnt look very nice.

Plotting with multiple axes and more advanced styling


Now, lets look at a more complex example for creating the demo screenshot which contains the five graphs on four axes, textured filling, vertical error
bars, a legend, dots as decimal separators etc.

1
2
3
4
5
6
7
8
9
10
11

customPlot->setLocale(QLocale(QLocale::English, QLocale::UnitedKingdom)); // period as decim


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->setPositionStyle(QCPLegend::psBottomRight);
customPlot->legend->setBrush(QBrush(QColor(255,255,255,230)));
// setup for graph 0: key axis left, value axis bottom
// will contain left maxwell-like function
customPlot->addGraph(customPlot->yAxis, customPlot->xAxis);

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

customPlot->graph(0)->setPen(QPen(QColor(255, 100, 0)));


customPlot->graph(0)->setBrush(QBrush(QPixmap("./dali.png"))); // fill with texture of speci
customPlot->graph(0)->setLineStyle(QCPGraph::lsLine);
customPlot->graph(0)->setScatterStyle(QCP::ssDisc);
customPlot->graph(0)->setScatterSize(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 g
customPlot->graph(1)->setLineStyle(QCPGraph::lsStepCenter);
customPlot->graph(1)->setScatterStyle(QCP::ssCircle);
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(QCP::ssPlus);
customPlot->graph(4)->setScatterSize(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(50), y0(50);
QVector<double> x1(25), y1(25), y1err(25);
QVector<double> x2(250), y2(250);
QVector<double> x3(250), y3(250);
QVector<double> x4(250), y4(250);
for (int i=0; i<50; ++i) // data for graph 0
{
x0[i] = 5*i/50.0;
y0[i] = exp(-x0[i]*x0[i]*0.8)*(x0[i]*x0[i]+x0[i]);
}
for (int i=0; i<25; ++i) // data for graph 1
{
x1[i] = 5*i/25.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;

64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

x3[i]
x4[i]
y2[i]
y3[i]
y4[i]

=
=
=
=
=

x2[i];
i/250.0*100-50;
sin(x2[i]*12)*cos(x2[i])*10;
cos(x3[i])*10;
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("3");
customPlot->xAxis2->setAutoTicks(false);
customPlot->xAxis2->setAutoTickLabels(false);
customPlot->xAxis2->setTickVector(piTicks);
customPlot->xAxis2->setTickVectorLabels(piLabels);
// set labels:
customPlot->setTitle("Way too many graphs in one plot");
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);

As you can see, you can define freely which axis should play which role for a graph. Graph with index 0 for example uses the left axis ( yAxis) as its key
and the bottom axis (xAxis) as its value. Consequently the graph is standing upward against the left axis, see the screenshot from the gallery.
In order to apply error bars for graph 1, we need to enable the plotting of the corresponding error bars via QCPGraph::setErrorType which takes an
argument whether the error bars are for the value, the key, both or none dimensions. Then we call one of the many QCPGraph::setData functions which
take the arguments we want. Here they are keys (x1), values (y1) and value errors (y1err). For further explanation of the used methods, I once again
refer to the documentation.

Plotting date/time data


Next, well look at how to plot date and/or time related data, as shown in the screenshots section. It basically comes down to two additional function calls
to tell an axis, it should output the labels as dates/times in lines 28 and 29 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

// 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:
QVector<double> tickVector;
QVector<QString> tickLabels;
tickVector << 5 << 55;
tickLabels << "Not so\nhigh" << "Very\nhigh";
customPlot->yAxis->setAutoTicks(false);
customPlot->yAxis->setAutoTickLabels(false);
customPlot->yAxis->setTickVector(tickVector);
customPlot->yAxis->setTickVectorLabels(tickLabels);
// 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);

44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

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);
// activate legend and position it in top left corner:
customPlot->legend->setVisible(true);
customPlot->legend->setPositionStyle(QCPLegend::psTopLeft);

The string you pass to QCPAxis::setDateTimeFormat() has the same date formatting options as the string passed to QDateTime::toString(), see Qt docs.
All date/times are handled as seconds since midnight 1. January 1970, UTC. This is the format you use, when
calling QDateTime::toTime_t orsetTime_t on the Qt date/time classes. For sub-second accuracy, you can
use QDateTime::toMSecsSinceEpoch()/1000.0, which results in a double value representing the same timespan as toTime_t returns, but with
millisecond accuracy.
For more of those demo codes, see the examples package in the download section below.

Beyond Graphs: Curves, Bar Charts, Statistical Box Plot,


Up to now weve only looked at graphs. Since they are such a dominant use case, QCustomPlot offers a specialized interface for them. Weve been using it
all the time: QCustomPlot::addGraph, QCustomPlot::graph etc. But thats not the the whole story.
QCustomPlot has a more general interface for classes that draw data inside the plot, I call them Plottables. This interface is built around the abstract
base class QCPAbstractPlottable. All Plottables derive from this class, also our familiar QCPGraph class.
Currently, QCustomPlot offers four different plottable classes:

QCPGraph: Thats the plottable class weve been using. Displays a series of data points as a graph with different line styles, filling, scatters
and error bars.

QCPCurve: Similar to QCPGraph with the difference that its made for displaying parametric curves. Unlike function graphs, they may
haveloops.

QCPBars: A Bar Chart. Takes a series of data points and represents them with bars. If there are multiple QCPBars plottables in the plot, they
can be stacked on top of each other, as shown in the screenshot section.

QCPStatisticalBox: A Statistical Box Plot. Takes a five-number-summary (minimum, lower quartile, median, upper quartile, maximum) and
represents it as a statistical box. Outliers can also be displayed.
Unlike graphs, other plottables need to be created with new outside of QCustomPlot and then added with QCustomPlot::addPlottable. (I.e. there is
noaddCurve or addBars function as there is an addGraph function.) QCustomPlot takes ownership of the passed plottable. Existing plottables can be
accessed with QCustomPlot::plottable(int index), the total number of plottables in the plot (including graphs) can be retrieved
withQCustomPlot::plottableCount.
Heres a quick example that creates a bar chart with three bars:

1
2
3
4
5

QCPBars *myBars = new QCPBars(customPlot->xAxis, customPlot->yAxis);


customPlot->addPlottable(myBars);
// now we can modify properties of myBars:
myBars->setName("Pretty bars");
QVector<double> keyData;
QVector<double> valueData;

6
7
8
9
10
11

keyData << 1 << 2 << 3;


valueData << 2 << 4 << 8;
myBars->setData(keyData, valueData);
customPlot->rescaleAxes();
customPlot->replot();

More examples can be found in the example project. Further, each plottable type has a more detailed description on the documentation page of the
respective class.

Of course, its absolutely possible to write your own plottable to make any data look exactly the way you need it. You should look at
theQCPAbstractPlottable documentation for a guide how to start subclassing it. Further, you can look at the other plottables to see how they work. For
that purpose, I recommend QCPBars or QCPCurve for a start. QCPGraph is quite feature rich and thus probably not suitable as a starting point.

Items
QCustomPlot allows placing and anchoring of graphical elements such as text, arrows, lines, rectangles, arbitrary pixmaps etc. on the plot. Items of this
kind are based on the abstract base class QCPAbstractItem. A detailed description of the item mechanism and what built-in items are currently available
can be found in the documentation of QCPAbstractItem.
Heres a simple example showing how to create a text label that always is positioned at the top of the axis rect and an arrow that connects a point in plot
coordinates with that label.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

customPlot->setRangeDrag(Qt::Horizontal|Qt::Vertical);
customPlot->setRangeZoom(Qt::Horizontal|Qt::Vertical);
// add the text label at the top:
QCPItemText *textLabel = new QCPItemText(customPlot);
customPlot->addItem(textLabel);
textLabel->setPositionAlignment(Qt::AlignTop|Qt::AlignHCenter);
textLabel->position->setType(QCPItemPosition::ptAxisRectRatio);
textLabel->position->setCoords(0.5, 0); // place position at center/top of axis rect
textLabel->setText("Text Item Demo");
textLabel->setFont(QFont(font().family(), 16)); // make font a bit larger
textLabel->setPen(QPen(Qt::black)); // show black border around text
// add the arrow:
QCPItemLine *arrow = new QCPItemLine(customPlot);
customPlot->addItem(arrow);
arrow->start->setParentAnchor(textLabel->bottom);
arrow->end->setCoords(4, 1.6); // point to (4, 1.6) in x-y-plot coordinates
arrow->setHead(QCPLineEnding::esSpikeArrow);

As with plottables, it is easy to create own items, too, by making your own subclass of
QCPAbstractItem. See the subclassing section in the documentation there.

User interaction
QCustomPlot offers multiple built-in user interactions. They include axis range dragging as mentioned earlier, but also detecting clicks/double clicks on
objects as well as a complete selection mechanism for plottables, axes, axes ticks, axes labels, legend, legend items etc.

The availability of these interactions is controlled with QCustomPlot::setInteractions. For details about the interaction system, see the documentation
there. QCustomPlot always emits corresponding signals, when objects are clicked or double clicked. See the
signals plottableClick,plottableDoubleClick and axisClick for example.
The examples include one project which makes extensive use of various aspects of the interaction system, and explains how to fine tune the behaviour to
fit ones needs.

Unfinished but planned features

A Candlesticks plottable or other financial charting

Plottables for other data representation concepts, like bubble charts.

Plottables for two-dimensional data as color map, vector map and contour lines.
But the first and foremost aim of QCustomPlot is being easy and intuitive to use, as well as extendable by anybody who wants to. Because then its
versatility is much greater than by implementing every thinkable feature. If I ever feel a feature would conflict with this aim and make the library less
user-friendly, I wont implement it.

Download
If you would like to use the newest 1.0.0-beta version, see the news section for packages.
Release Date: 09.06.2012
QCustomPlot source and example files: QCustomPlot.tar.gz
QCustomPlot source only: QCustomPlot-source.tar.gz
QCustomPlot shared library: QCustomPlot-sharedlib.tar.gz
QCustomPlot documentation: QCustomPlot-doc.tar.gz
QCustomPlot change notes: changenotes.txt

Older releases
Release Date: 31.03.2012
QCustomPlot source and example files: QCustomPlot-12-03-31.tar.gz
QCustomPlot source only: QCustomPlot-source-12-03-31.tar.gz
QCustomPlot documentation: QCustomPlot-doc-12-03-31.tar.gz

Quo Vadis QCP?


The QCustomPlot library is maturing fast and is already being used by many companies, universities, research centers and individual developers.

The next release will concentrate on consolidation, expanding the unit tests, cleaning up and some refactoring. It will be QCustomPlot version 1.0.0,
replacing the previous versioning scheme following release dates. At the same time the code base will move from my local repository to a public
gitrepository on gitorious.

577 COMMENTS ON QT PLOTTING WIDGET


Comment navigation

Older Comments
Newer Comments

1.

Hasret Saryer on December 25, 2012 at 11:32 pm said:

Hi, When I run first graph,two windows opens.And how can I provide to open only one window? Thanks

DerManuon December 26, 2012 at 12:23 am said:

I dont understand what youre trying to say.

Hasret Saryeron December 26, 2012 at 3:23 am said:

When I run code,two window open.But I want to open only one window.I dont know how to do it.

DerManuon December 27, 2012 at 11:43 am said:

I guess youre having a general problem with Qt programming, not with QCustomPlot. When you create a new QWidget without a parent, its given a new floating window by
the window manager.

Hasret Saryeron December 29, 2012 at 6:02 pm said:

Yes,you are right! thank u

2.

Pavel Petrman on December 20, 2012 at 1:41 pm said:


Hi! Excellent work, Im amazed how well the whole thing is programmed and how fast it is! I display about half million points at once and the thing still goes almost
smoothly:-) One question though: why is deleting (removeDataAfter, removeDataBefore) so slow? Do I do something wrong or is it just caused by some inner workings? I load
the data from a database that is on another machine, and still the loading is at least one order of magnitude faster than unloading (also, when I close the window with the
QCustomPlot, i.e. delete it), it takes some noticeable time. It poses no problem to me, Im just curious, whether it is an expected behaviour or should I dig into what causes it.
If you need some more info or code excerpt, just email me. Thank you so much for your work, well done! Pavel

DerManuon December 20, 2012 at 10:08 pm said:

Interesting observation, Ive sent you an E-Mail.


(To everyone else reading this: Ill reply here to tell how things turn out)

DerManuon January 3, 2013 at 8:08 am said:

Ive added the data manipulation in question to my benchmarks and couldnt reproduce Pavels observation. Adding 500k points to 500k points takes ~140 ms, Removing
500k Points from 1M points takes ~50 ms. Since Pavels observation shows strong dependency on the build configuration (release/debug/profile), the problem might be
outside of QCP.

Pavel Petrmanon January 8, 2013 at 6:04 pm said:


And indeed it is. For reasons yet unclear to me, the performance drop is caused by the dev enviroment (MS Visual Studio 2010, 64 bit, MSVC++ 2010, Qt Add-in 1.1.10).
Today I got the chance to test the case on a Ubuntu 12.04 box and on a different Windows 7 toolchain as well and in both cases no performance drop was to be noticed. In

Studio everything works the opposite way it should in terms of performance during profiling the actual performance is much better than in standard debug build and that is
again faster than release build. If I discover what was the cause of this strange behavior, Ill report back.

Pavel Petrmanon January 29, 2013 at 1:14 pm said:

The final notice: the problem lies beyond the QCustomPlot library and beyond Qt its the VC++ 2008 tool chain, namely the debugger, that has a memory management issue
which hinders the performance of deletion in QMap. The quick workaround (not so much work as around) is to detach the debugger whenever the performance of deletion
is an important aspect.
Further reading: http://qt-project.org/forums/viewthread/19768

By the way, in the discussion thread under the link, its been commented not to use the VC++ compiler by a user called DerManu

That may not be an

option under certain circumnstances, hence the recommendation to detach the debugger.

3.

Mds5000 on December 19, 2012 at 9:07 am said:


Has anyone attempted a python binding? Would be interested in using this with PySide.

4.

bingo on December 18, 2012 at 8:44 am said:


Hello,
Great Work! but i have a small question:
When i get the list of added Items in the plot (QCPAbstractItem*) , how can i know before casting if its a QCPItemLine or QCPItemRect.
Greets.

bingoon December 18, 2012 at 8:48 am said:

Without a debug(). I get the list of added Items by : QCPAbstractItem *QCustomPlot::item(int index) const
Thanks in advance

bingoon December 19, 2012 at 1:36 pm said:

item(i)->metaObject()->className()

DerManuon December 20, 2012 at 9:08 pm said:

o
Hi,

in object oriented programming (in C++), casting is the valid method to do what you want. And QCPAbstractItems are QObjects, so you can even use the fast qobject_cast
(instead of the slower dynamic_cast, which would be the normal C++ way for this situation).
The idiom is as follows:
QCPAbstractItem *baseClassPointer;
if (QCPItemLine *lineItem = qobject_cast<QCPItemLine*>(baseClassPointer))
{
// use lineItem here

} else if (QCPItemRect *rectItem = qobject_cast<QCPItemRect*>(baseClassPointer))


{
// use rectItem here
} ...

And it uses the fact that both qobject_cast and dynamic_cast return a zero-pointer when the object the base class pointer is pointing actually isnt of the specified subclass
type.

5.

Peter Lindener on December 10, 2012 at 3:36 am said:


Your Qt plotting widget, looks like just the ticket!, Thanks so much for having the vision to have implemented it.. Im a bit of a newbie to Qt5ss latest way of doing things with
QML..
I have a slider driven interactive plot, implemented in Python/MatPlotLib.and Im hoping to make things a bit more responsive using you Qt Plot widget It would be great
if there were a QtPlotWidget demo that was driven by way of Qt slider driven parameters.. I realize Im asking for help with a Jump start here. Then Ill do my best to make
up for the favorwith some realy cool interactive plot widgets sent back your way..
all the best
-Peter

DerManuon December 13, 2012 at 12:19 am said:

In the case of sliders, the way you control your function parameters should be independent of the way the function is then plotted. Thus the actual usage of QCustomPlot (with
C++) and the designing of the GUI (e.g. with QML) is not really related. For example, you might want to plot the function y(x) := ax^2+bx+c with free parameters a, b and c.
So you could add three sliders to your GUI which control these parameters. (I dont use QML, so youll have to figure out how to do that with the help of some QML tutorial or
documentation.) As soon as a slider changes its value (see the valueChanged signal of the slider), you should do the following:
calculate the x and y values of the function (x and y can be realized as QVectors) with a simple for-loop, in a discretization you find appropriate (the simplest would be a
fixed step size or sample count). Of course, taking into account the current setting of a, b and c.
pass the data to the designated graph in the plot (see QCPGraph::setData(x,y))
possibly call QCustomPlot::rescaleAxes() (or the corresponding functions on the QCPGraph) to make the axis ranges fit the data
replot (QCustomPlot::replot())
Thats all!
Make sure you set QSlider::setTracking(true), so the valueChanged signal gets emitted every time the user actually moves the slider and not only when he releases it, to get live
updates of the plot.
A more sophisticated (and slightly more performant) method would be to directly create a QCPDataMap, which is the container QCPGraph uses internally, on the heap. You
can then pass it to the QCPGraph via the overloaded setData method and keep a reference (or pointer), to manipulate the data at a later point in time. Beware that in this case,
QCPGraph takes ownership of the container though, so dont delete it manually after youve passed it to the graph.
The perfect way would be to subclass QCPGraph. One would need to add function parsing and discretization capability to it, hiding the data interface from the user and
instead exposing an interface for specifying analytical functions (either as a callback/functor class or a QString) and let the class handle the numerics/discretization for
plotting. But thats not in the scope of a comment or e-mail. A class like that might come some day with the QCustomPlot library, but Im not making

promises.
Hope this got you some starting ideas.

6.

Alex on December 5, 2012 at 12:01 pm said:


Dear DerManu,
What would be your recommendation for a histogram using QCustomPlot? Is it possible out of box or somehow in a different way?

Thanks.

DerManuon December 5, 2012 at 3:06 pm said:

The drawing of the histogram can be done out-of-the-box with either a QCPBars plottable (for separated bars, see demo screenshot), or a normal QCPGraph where youve set
the line style to e.g. center steps (setLineStyle).
The binning of the histogram (finding the height of the histogram data points by counting occurences) has to be done by your program though, since QCP is not a data analysis
library.

7.

Jack on December 4, 2012 at 3:39 am said:


The QCustomPlot is great and easily use!
But I have some problem in building the shared library for it.
Ive downloaded the sharelib and able to build the shared library using MinGW (.a and .dll is created) but not able to build using MSVC.
The issues shows a lot of LNK2001: unresolved external symbol.
I need to build it using MSVC to get .lib file.
Ive no experience on building shared library in Qt.
Can you please guide it?

Jackon December 4, 2012 at 7:46 am said:

o
Another question

I have 5 graph inside a QCustomPlot.


I can make either 1 of it being hidden.
But the legend item of that graph does not hidden.
What should I do to let that legend item hidden?

DerManuon December 4, 2012 at 8:00 am said:

To remove a graph from the legend, call QCPGraph::removeFromLegend(). When you want it back again, just call ::addToLegend().
About the linking problem: I dont own MSVC, so unfortunately I cant test it here. Does compiling other shared libraries (e.g. a mock one for testing) work on your system?
//EDIT: Are you using the example projects for creating/using the shared library in the sharedlib package of the download section? If not, make sure to define
QCUSTOMPLOT_COMPILE_LIBRARY when compiling the dll and QCUSTOMPLOT_USE_LIBRARY when including the header to your project that uses the dll.

Jackon December 5, 2012 at 1:14 am said:

TQ for your answer.

Yeah, Im using the example project for creating the shared library.
However, I found that Im able to create the library by using MinGW release and MSVC debug but not MSVC release.
What is the difference of library created by using debug mode and release mode?
If there is not much difference, I may use the .lib & .dll file created by MSVC debug.

DerManuon December 5, 2012 at 8:50 am said:

From the build process point of view, there isnt much difference between creating a debug and creating a release library. Just passing qmake the release or the debug flag in
the CONFIG variable. In the sharedlib.pro, you see both of this happen (via the debug_and_releaseflag), so both the debug and the release libraries will be built when using
that project file. To prevent overwriting the created libraries, the project file attaches a d to the library name when the debug library is built.
If you only want to build release, you could try removing the flags debug_and_release and build_all and adding release.
The error your msvc returns puzzles me, because Id expect that to happen when name mangling isnt handled correctly. But since its built from one single source pair (and
apart from that, I use the Qt macro Q_DECL_EXPORT to handle the calling convention), I cant see how this should create problems when compiling the shared library. By
the way: Was that the entire error message? Could you maybe send the entire output of the compile/link process via mail?

8.

Henning on December 3, 2012 at 2:44 pm said:


This is AWESOME!!! Thank you some much for the great work. I would never have thought that such an elaborate plotting framework would exist for QT. Its really well done
and even documented nicely! Thanks a lot!

9.

Boris Legradic on November 29, 2012 at 9:49 am said:


Hi, I am relatively new to C++/Qt, and I am trying to use your widget. I am using netbeans and qt designer, but I cant get my testfile to compile when using QCustomPlot. I
am promoting a QWidget to QCustomPlot. I put both qcustomplot.h and qcustomplot.cpp in the project folder, and include qcustomplot.h in my mainwindow.h file. But when
compiling (with mingw 4.6.2 and qt 4.8.3) I always get the error undefined reference to `QCustomPlot::QCustomPlot(QWidget*) for the .ui file that initializes
QCustomPlot: customPlot = new QCustomPlot(containerwidget);
Help?
Cheers, Boris

DerManuon November 29, 2012 at 9:54 am said:

Did you add qcustomplot.h and qcustomplot.cpp to the HEADERS and SOURCES variable in your project (.pro) file? Possibly NetBeans doesnt do that automatically when
you add source files. You should see a qcustomplot.o compiled object in your build directory.
//EDIT: And make sure that NetBeans creates the .ui files correctly so the ui-sources also include qcustomplot.h. Possibly the widget promition doesnt do that automatically
as in QtCreator.

Boris Legradicon November 29, 2012 at 10:00 am said:

I did now ;), but unfortunately I get the errors:


qcustomplot.cpp:12310:14: error: exception handling disabled, use -fexceptions to enable
and
error: dynamic_cast_will_always_fail_because_rtti_is_disabled is not a member of QCPItemPosition*
?

DerManuon November 29, 2012 at 10:11 am said:

Seems like your build environment has both RTTI and exceptions disabled. Find out how to configure your environment/netbeans to include the flags -frtti and -fexceptions.
You could also try to set it on a per-project-basis by adding something like QMAKE_CXXFLAGS += -frtti -fexceptions to your project.
If you dont want exceptions, you can also just comment out the try and catch lines in the code. They are used only in that one function for an out-of-memory exception that
gets thrown by some function inside Qt.

Boris Legradicon November 29, 2012 at 1:11 pm said:

Thanks so much for your help! You were right, I had to add a config+=rtti to Netbeans, this option is very well hidden in Project->Properties->Build->Qt->Expert->Custom
Definitions. Now everything works fine, and I will start plotting immediately, Cheers!

10.

Braian on November 28, 2012 at 2:13 pm said:


Good Work!
How can i get the source code for real time generated data srolling right and automatically adjusting vertical axis as it goes. . ?
Thanks,
Braian

DerManuon November 28, 2012 at 3:31 pm said:

The source codes to all demo screenshots is in the example project, see download section above. In your case, you should look at the method setupRealtimeDataDemo and the
slot realtimeDataSlot (which gets called repeatedly by a timer).

Braianon November 29, 2012 at 2:53 pm said:

Thanks. i `ve downloaded the example from git repository. Now, how can i get the data from a graph? i dont know how to retrieve data from a graph, with QCPGraph::data()
method.
i want to get data from a graph and set it to another graph or save it to a file.

DerManuon November 29, 2012 at 3:02 pm said:

The QCPGraph::data() method gives you a pointer to the QCPDataMap that contains the data, see the documentation.

Braianon November 29, 2012 at 7:20 pm said:

i`ve seen the documentation, but, i still dont know how to get data from the graph.
Could you show me a code example for retrieve data an set/add data to a graph ?
Thanks again.

DerManuon November 30, 2012 at 5:45 pm said:

Well QCPDataMap is just a typedef for the map QMap<double, QCPData>. And QCPData is just a single data point container with memberskey, value, and respective error
values (for error bars). So you can use the QCPDataMap that the QCPGraph contains just like any other Qt QMap (thats a standard Qt container class). See the Qt
documentation for how to look up values in maps and loop over them etc. The key of QCPDataMap is the actual data key (e.g. x coordinate of the data point).

11.

Michael on November 27, 2012 at 3:05 pm said:


Hi DerManu,

I will just let you know about the project state of my qt android app using necessitas alpha 4. I am now able to pinch zoom in graphs and also use the pan gesture to move
graphs via touch screen. Qt Gesture Framework helped out.
At momeent I am using simple plots with a simple line style. My goal is to have 3 lines on a plot, one line representing data and 2 lines representing lower and upper bounds of
data. For changing the look of the line representing data, I used QPen as you show in demo applications.
Changing color is no problem but when I change the width of the Pen to 2 for example, then dragging the line is slowing down extremely. If I use QPen::setWidth(1), dragging
is smooth and really fast.
Do you have any suggestions? Should I slow down the triggers of receiving pan gesture events? I use raster drawing. And I have antialsing left on while dragging. Any
suggestion is really welcome.
Drawing 2 or three lines by the way does not make any problems.
Best Regards Michael

DerManuon November 27, 2012 at 4:49 pm said:

o
Hi Michael,

Great to hear your project is advancing!


The line drawing for linewidths > 1 is indeed alot slower than for lines with width 1. Thats a Qt thing I cant change. Drawing thicker lines is just inherently a more
complicated algorithm than a single line (Think of a thick line as a rotated rectangle and additional circles/curves for segment joins).
Here are the options I see: Disable antialiasing while dragging (see QCustomPlot::setNoAntialiasingOnDrag), Set all linewidths to one while dragging, use OpenGL as
graphicssystem.

Michaelon November 28, 2012 at 10:23 am said:

I just tested your suggestions. Setting linewidth to one has helped me out. Thank you very much! It os now really smooth to drag and zoom in and out! Very cool!
Michael

Michaelon December 3, 2012 at 12:55 pm said:

A little hint,

It would be nice, if you could set borders, where scrolling should end. You have a graph whith x-points, the user is scrolling through it and he can scroll beyond the graph. I
have done a little workaround, I check whether center is growing higher or lower than beginning/ending of datapoints, then i adjust the range of respective axis according to
beginning/end of data points.
Regards Michael

12.

John on November 26, 2012 at 6:28 pm said:


Is there a simple way to produce line graphs with missing datapoints, leaving line gaps where there is missing data, perhaps by supplying a distinguished missing data value
for keys with no data? The alternative appears to be adding separate graphs for each segment.

DerManuon November 26, 2012 at 8:20 pm said:

Currently, the way you describe is the way to go if you want missing line segments. The future will probably bring such a feature for QCPGraph/QCPCurve, but not in the next
release.

13.

Norbert on November 16, 2012 at 9:01 pm said:

Hi,
is there possibilty to alter the color of background for a specified range ?
E.g.
xrange of the plot is from 0 to 100. Set the backgound for the range 10 to 40 to a differend color.

Norberton November 17, 2012 at 12:13 am said:

In the meantime i tried to solve it by using QCPBars.


This works as long as I do not zoom out.
To resize the bar I use
bar->clearData();
h[0] = ui->customPlot->yAxis->range().lower;
h[1] = ui->customPlot->yAxis->range().upper;
bar->setData(x,h);
during the void MainWindow::mouseWheel() slot in interaction-example/mainwindow.cpp
This is always one step behind the actual zoom step.

DerManuon November 17, 2012 at 12:14 am said:

Hi, Id do that with a rect item (QCPItemRect) which you place on a layer (QCPLayer) below the grid (make a new layer for that). You can attach it to corresponding x/y
ranges. If you want the rect to always cover the entire y range, just adjust the position in the beforeReplot slot.

14.

Mian Kashif Ali on November 15, 2012 at 8:05 am said:


wonderful work for a qt enthusiast..
can i use it in commercial apps with LGPL?

DerManuon November 15, 2012 at 8:21 am said:

o
Ive sent you an E-Mail.

15.

Sam on November 10, 2012 at 10:30 am said:


Thats a great library. We wish to use it in a closed source app. What are the conditions to use it with LGPL ?
Thanks

DerManuon November 10, 2012 at 3:20 pm said:


Please notify me via the contact page (and include an E-Mail, so I can answer)

16.

michel on November 6, 2012 at 10:08 am said:

A question:
Do you plan to use model/view paradigm in the future?
Or in other word, do you plan to have an api that can simplify the code of an app that receive data in a worker thread and the widget code living in the gui thread?
regards

17.

michel on November 6, 2012 at 9:19 am said:


Hi,

very promising! very clean and easy to use


IMHO, killer features could be:
mouse cursor, to measure, a (X,Y) points or interval
colormap plot as you mention
colormap control to change the mapping, adapted to the kind of data
An interresting approch should be to be able to plot a big 2D matrix, using tiling method like google map.

ooppss. I stop here, Id like so much to see a great AND easy to use plot widget in Qt that I can speak all the day about
thanks a lot for your work
Michel
Comment navigation

Older Comments
Newer Comments

CHOOSE RESOURCE

Components

Qt plotting widget

Language Manager

Qt Cryptographic Hash Classes

XML classes for Qt


Non source code content of this website is licensed under creative commons license by-nc-sa.
Source codes and Software are licensed under the GNU GPL except as noted

4)

Vous aimerez peut-être aussi