JKQTPlotter trunk/v5.0.0
an extensive Qt5+Qt6 Plotter framework (including a feature-richt plotter widget, a speed-optimized, but limited variant and a LaTeX equation renderer!), written fully in C/C++ and without external dependencies
Loading...
Searching...
No Matches
Tutorial (JKQTPDatastore): Iterator-Based usage of JKQTPDatastore

This tutorial project (see ./examples/datastore_iterators/) explains how to use the iterator-based interface to JKQTPDatastore.

Note that there are additional tutorial explaining other aspects of data mangement in JKQTPDatastore:

The source code of the main application can be found in datastore_iterators.cpp. This tutorial cites parts of this code to demonstrate different ways of working with JKQTPDatastore's iterator-interface.

In every code-segment below, we will use these two declarations from the code to access the internal datastore of the JKQTPlotter instance:

// 1. create a plotter window and get a pointer to the internal datastore (for convenience)
JKQTPDatastore* datastore=plot.getDatastore();
This class manages data columns (with entries of type double ), used by JKQTPlotter/JKQTBasePlotter t...
Definition jkqtpdatastorage.h:282
plotter widget for scientific plots (uses JKQTBasePlotter to do the actual drawing)
Definition jkqtplotter.h:364
JKQTPDatastore * getDatastore()
returns a pointer to the datastore used by this object
Definition jkqtplotter.h:611

In the example Basic Usage of JKQTPDatastore we discussed how to copy data from external container into and explicitly access data in columns inside a JKQTPDatastore. This tutorial explains how to use the iterator interface of JKQTPDatastore to access the data, build columns and also interact with algorithms from the C++ standard template library (or other iterator-based libraries, like e.g. boost). Also have a look at the JKQTPlotter Statistics Library and Advanced 1-Dimensional Statistics with JKQTPDatastore, as these also use the iterator-interface of JKQTPDatastore.

Iterator-based Column Data Access To Existing Rows

In other tutorials we used e.g. JKQTPDatastore::set() to set values in data columns. Using this scheme, you can write code like shown below to draw a cose curve:

size_t XCol=datastore->addLinearColumn(50, 0, 4.0*M_PI, "cos curve: x-data");
size_t YCol=datastore->addColumn(datastore->getRows(XCol), "cos curve: y-data");
for (size_t i=0; i<datastore->getRows(XCol); i++) {
datastore->set(YCol, i, cos(datastore->get(XCol, i)));
}
size_t getRows(size_t column) const
returns the number of rows in the column column
Definition jkqtpdatastorage.h:2638
void set(size_t column, size_t row, double value)
sets the value at position (column, row). column is the logical column and will be mapped to the acco...
Definition jkqtpdatastorage.h:2700
size_t addLinearColumn(size_t rows, double start, double end, const QString &name=QString(""))
add a column to the datastore that contains rows rows with monotonely increasing value starting at st...
size_t addColumn(JKQTPColumn col)
add a new column to the datastore and return its ID
double get(size_t column, size_t row) const
returns the value at position (column, row). column is the logical column and will be mapped to the a...
Definition jkqtpdatastorage.h:2675

Here we added two columns with 50 entries. XCol contains linearly spaced values between 0 and 2*pi and YCol contains 50 uninitialized values. Then we iterate an index i over all these items (datastore->getRows(XCol) returns the rows in a column, i.e. 50 in the example above) and used JKQTPDatastore::set() to store the calculated values in the two columns. The current x-values is read from XCol using JKQTPDatastore::get(). The resulting plot looks like this:

datastore_iterators_cosine

The same loop can be written using iterators:

size_t XCol=datastore->addLinearColumn(50, 0, 4.0*M_PI, "cos curve: x-data");
size_t YCol=datastore->addColumn(datastore->getRows(XCol), "cos curve: y-data");
auto itY=datastore->begin(YCol);
for (auto itX=datastore->begin(XCol); itX!=datastore->end(XCol); ++itX, ++itY) {
*itY=cos(*itX);
}
ColumnIterator begin()
returns an iterator to the first column in the JKQTPDatastore
ColumnIterator end()
returns an iterator behind the last column in the JKQTPDatastore

Back-Inserter for Columns

Above we used two previously sized columns and accessed (read and writing) existing rows in them. But JKQTPDatastore also provides an iterator comparable to std::back_inserter, which allows to add rows at the end of an existing (here initially empty) column:

size_t XCol=datastore->addColumn("cos curve: x-data");
size_t YCol=datastore->addColumn("cos curve: y-data");
auto biXCol=datastore->backInserter(XCol);
auto biYCol=datastore->backInserter(YCol);
for (double x=0; x<4.0*M_PI; x+=4.0*M_PI/50.0) {
*++biXCol=x;
*++biYCol=cos(x);
}
JKQTPColumnBackInserter backInserter(int i)
returns a back-inserter iterator (JKQTPColumnBackInserter) to the i -th column in the JKQTPDatastore

Using C++ STL algorithms

You can write this a bit more compact, if you use JKQTPDatastore::addLinearColumn() and the C++ STL-algorithm std::transform():

size_t XCol=datastore->addLinearColumn(50, 0, 4.0*M_PI, "cos curve: x-data");
size_t YCol=datastore->addColumn("cos curve: y-data");
std::transform(datastore->begin(XCol), datastore->end(XCol), datastore->backInserter(YCol), &cos);

Of course you can now also interface other algorithms, like e.g. std::sort():

std::sort(datastore->begin(colY), datastore->end(colY));

With this line of code, the YCol is sorted in ascending order and the plot becomes:

datastore_iterators_cosine_ysorted

Another example would be to replace all value y<-0.5 with the value 1.0 using std::replace_if():

std::replace_if(datastore->begin(YCol), datastore->end(YCol), [](double v) { return v<-0.5; }, 1.0);

datastore_iterators_cosine_yreplaced

Finally also the erase-remove idiom (e.g. known from std::vector) is supported:

datastore->eraseFromColumn(std::remove_if(datastore->begin(YCol), datastore->end(YCol), [](double v) { return v<0; }), datastore->end(YCol));
void eraseFromColumn(const JKQTPColumnIterator &pos)
removes the entry pos
Definition jkqtpdatastorage.h:2727

Special Properties of the JKQTPDatastore-Iterators

Note that the iterator classes of JKQTPDatastore (namely JKQTPColumnIterator and JKQTPColumnConstIterator) provide additional function to access the properties of the data-column row they point to: