PDA

View Full Version : QCustomPlot, changing graph scale and resizing data



Thibaut
2nd March 2020, 14:21
Hi!

I have a file with lots of data in it (for this example, 32 plots with several million points each). So to prevent long loading time, I want to just load the data that will be displayed on the graphs. If the user want to see the next page or change the scale of the plots, the new data are loaded.
I can display the graphs one below the other, and when changing the page, it works good (for example, the first page contain the points from 0 to 10000, the second from 10001 to 20000...).
But I have a problem when changing the scales, either on the x- or the y-axis.

Here's how I create my plots :



void CentralMiddleLayer::displayFirstLoading()
{
// Creation of the x axis
//--------------------
x.resize(scale);
for (int i = 0; i < scale; i++)
x[i] = i;

// Matrix dimensions resize
//--------------------
matrix.resize(channelNb); // First dimension
for (int i = 0; i < channelNb; i ++)
matrix[i].resize(scale); // Second dimension

// Get data from file, put into the matrix
//--------------------
FileReader::yAxisData(filename, matrix, actualRange.lower, scale); // This is the function that will read the file and put the data of interest in the matrix



plot = new QCustomPlot;
nbGraph = 32;

// Offset the data so they're not on top of each other
//----------------------------------------
QCPRange defaultRange(-100., 100.); // y-axis range
for (int i = 0; i < nbGraph; i++)
{
QCPAxis *axis = plot->axisRect()->addAxis(QCPAxis::atLeft);
axis->setRange(defaultRange.lower - (nbGraph - 1 - i) * defaultRange.size(), defaultRange.upper + i * defaultRange.size()); // I don't really understand why this work to be honest...
axis->setVisible(false);

QCPGraph *graph = new QCPGraph(plot->xAxis, axis);
}


// Set the data to the plot
//----------------------------------------
for(int i = 0; i < plot->graphCount(); i++)
{
plot->graph(i)->setData(x, matrix[i], true);
}


// Set plot characteristics
//----------------------------------------
plot->xAxis->setRange(0, 10000.0); // Number of point per page

plot->xAxis->setVisible(false);
plot->yAxis->setVisible(false);

plot->axisRect()->setAutoMargins(QCP::msNone);
plot->axisRect()->setMargins(QMargins(0, 10, 0, 0));
plot->setStyleSheet(("background:hsva(255, 255, 255, 0%);"));
plot->setBackground(QBrush(Qt::NoBrush));

plot->setFixedHeight(700);
}



Now, I don't see how to change the scales.

For the x-axis (time scale), if I rescale it when the application is running (for example I want 15000 points per graph instead of 10000), I get this error message :
void QCPGraph::addData(const QVector<double>&, const QVector<double>&, bool) keys and values have different sizes: 10000 15000
Here's the code I use for this :



void CentralMiddleLayer::timeScaleChange(double time)
{
scale = time; // the new time scale = how many point displayed per page and per graph

for (int i = 0; i < channelNb; i ++)
matrix[i].resize(scale); // the data matrix get its new size

setActualRange(actualRange.lower);
FileReader::yAxisData(filename, matrix, actualRange.lower, actualRange.upper); // the new data are read, the data corresponding to the new range are put inside the matrix

for(int i = 0; i< plot->graphCount(); i++)
plot->graph(i)->setData(x, matrix[i]); // the graphs receives their new data. From the documentation, this should work fine...

plot->xAxis->setRange(0, scale);

plot->replot();
}


And for the y-axis, If I change the scale nothing happen...


If someone is used to QCustomPlot, do you have any advice ?
I think my problem comes from the way I construct my graph, but on important point that I can't ignore is that the graphs have to be able to overlap each other (if the datas requires it). And I only find this way to do it. Is there an other one ?

d_stranz
2nd March 2020, 17:11
For the x-axis (time scale), if I rescale it when the application is running (for example I want 15000 points per graph instead of 10000), I get this error message :

If you add data to the graph in vectors, obviously both vectors have to be the same size. If you specify 10000 for x and 15000 for y, then what is the graph supposed to do for the extra 5000 points missing from the x vector? Make something up?


plot->graph(i)->setData(x, matrix[i]); // the graphs receives their new data. From the documentation, this should work fine...

I think you misunderstand the documentation. Where do you resize "x" to be the same size as "matrix[i]"? There has to be a one-to-one correspondence between the x and y vectors - every x value is matched to the corresponding y value (x[i], y[i]) when creating the point or line segment on the graph. So if you add 5000 more y points to the graph, you have to also specify the extra 5000 matching x coordinates.