Académique Documents
Professionnel Documents
Culture Documents
Qt Documentation
Qt 5.7
Qt Charts
LineChart Example
Reference
Development Tools
User Interfaces
Core Internals
Data Storage
Multimedia
Networking and Connectivity
Graphics
Mobile APIs
QML Applications
All Qt Overviews
LineChart Example
window.resize(400, 300);
window.show();
Files:
linechart/main.cpp
linechart/linechart.pro
Qt Documentation
Qt 5.7
Qt Charts
LineChart Example
Reference
Development Tools
User Interfaces
Core Internals
Data Storage
Multimedia
Networking and Connectivity
Graphics
Mobile APIs
QML Applications
All Qt Overviews
<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();
Qt Documentation
Qt 5.7
Qt Charts
LineChart Example
Reference
Development Tools
User Interfaces
Core Internals
Data Storage
Multimedia
Networking and Connectivity
Graphics
Mobile APIs
QML Applications
All Qt Overviews
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
3 Documentation
4 Basic usage
4.1 Changing the look
5 Examples
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.
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
Some random walks as a time series and date mode for bottom axis.
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
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.
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
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).
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
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.
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
// 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.
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
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.
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
6
7
8
9
10
11
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.
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
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.
Older Comments
Newer Comments
1.
Hi, When I run first graph,two windows opens.And how can I provide to open only one window? Thanks
When I run code,two window open.But I want to open only one window.I dont know how to do it.
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.
2.
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.
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.
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
option under certain circumnstances, hence the recommendation to detach the debugger.
3.
4.
Without a debug(). I get the list of added Items by : QCPAbstractItem *QCustomPlot::item(int index) const
Thanks in advance
item(i)->metaObject()->className()
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
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.
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.
Thanks.
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.
o
Another question
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.
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.
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.
9.
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.
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.
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.
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).
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.
The QCPGraph::data() method gives you a pointer to the QCPDataMap that contains the data, see the documentation.
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.
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.
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
o
Hi Michael,
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
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.
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.
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.
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.
o
Ive sent you an E-Mail.
15.
16.
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.
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
4)