QCustomPlot Discussion and Comments

Maximum and minimum zoom rangesReturn to overview
April 19, 2015, 14:51
by Bremenpl

Hello there,
What I am trying to do is to limit further zoom out of the plot. I have found the event->delta() adding trick. The problem is that after i reach a certain number (for example -1000) i cannot zoom in anymore because the zooming is blocked. I cannot zoom out but also cant zoom in back. I was wondering either theres an event more specific than MouseWheel (ie. MouseWheelIn, MouseWheelOut)? Or maybe there is another way of acomplishing this.

The second thing I was wondering is either it is possible to create a zooming locks separate for each axis- for example, if i reach the zoom out limit of axis Y, then the zooming would continue only on axis X.

I Would really aprichiate any help in here, i really enjoy QCustomPlot.

April 19, 2015, 14:56
by DerManu

Use the QCPAxis ::rangeChanged signal, of the axis you wish to limit.

You may manipulate/correct the range with setRange in a slot connected to this signal. This is useful if for example a maximum range span shall not be exceeded, or if the lower/upper range shouldn't go beyond certain values. For example, the following slot would limit the x axis to only positive ranges:

if (newRange.lower < 0)
 plot->xAxis->setRange(0, newRange.size());

In your case you simply limit both boundaries of the range like this. It will be best if you only perform one setRange call with a completely fixed range, so create a temporary QCPRange fixedRange, initialize it with the given newRange, manipulate the bounds, and then pass it to a setRange call.

April 19, 2015, 15:07
by Bremenpl

Could you only explain me how did you get newRange object?

April 19, 2015, 15:08
by DerManu
April 19, 2015, 15:36
by Bremenpl

Exacly what I needed, the code works now thank you!

April 19, 2015, 16:36
by DerManu

I'm in the process of implementing convenience functions for QCPRange that make their bounding for such cases very easy. And while doing that I noticed (once again) that writing code that limits the ranges is slightly more tricky than it seems at first glance, if you want to do it right. So I thought I'd just post it here in case other people (or you) are interested.

The following code can be placed in a slot connected to QCPAxis ::rangeChanged , and will limit the axis range to lowerBound and upperBound.

 double lowerBound = 0;
 double upperBound = 10; // note: code assumes lowerBound < upperBound
 QCPRange fixedRange(newRange);
 if (fixedRange.lower < lowerBound)
 {
 fixedRange.lower = lowerBound;
 fixedRange.upper = lowerBound + newRange.size();
 if (fixedRange.upper > upperBound || qFuzzyCompare(newRange.size(), upperBound-lowerBound))
 fixedRange.upper = upperBound;
 mCustomPlot->xAxis->setRange(fixedRange); // adapt this line to use your plot/axis
 } else if (fixedRange.upper > upperBound)
 {
 fixedRange.upper = upperBound;
 fixedRange.lower = upperBound - newRange.size();
 if (fixedRange.lower < lowerBound || qFuzzyCompare(newRange.size(), upperBound-lowerBound))
 fixedRange.lower = lowerBound;
 mCustomPlot->xAxis->setRange(fixedRange); // adapt this line to use your plot/axis
 }

September 1, 2016, 12:42
by Matthias Pospiech

How do I know the plot pointer?
I have a number of plots > 1 all dynamically created.
Thus I can not write a connect code and a function for each plot. I need this to work automatically.

I solved this using the Qt property function and included your code.
Why is such functionality not within the QCP code itsself?

void MainWindow::setupPlot(QCustomPlot *plot, QString title)
{
...
 connect(plot->xAxis, SIGNAL(rangeChanged(QCPRange)), this, SLOT(xAxisChanged(QCPRange)));
 connect(plot->yAxis, SIGNAL(rangeChanged(QCPRange)), this, SLOT(yAxisChanged(QCPRange)));
}
void MainWindow::updatePlotData(QCustomPlot *plot, vector<double> & y0, vector<double> & y1 )
{
...
 plot->replot();
 plot->setProperty("xmin", plot->xAxis->range().minRange());
 plot->setProperty("xmax", plot->xAxis->range().maxRange());
 plot->setProperty("ymin", plot->yAxis->range().lower);
 plot->setProperty("ymax", plot->yAxis->range().upper);
}
void MainWindow::xAxisChanged(const QCPRange & newRange)
{
 QCPAxis * axis = qobject_cast<QCPAxis *>(QObject::sender());
 QCustomPlot * plot = axis->parentPlot();
 QCPRange limitRange(plot->property("xmin").toDouble(), plot->property("xmax").toDouble());
 limitAxisRange(axis, newRange, limitRange);
}
void MainWindow::yAxisChanged(const QCPRange & newRange)
{
 QCPAxis * axis = qobject_cast<QCPAxis *>(QObject::sender());
 QCustomPlot * plot = axis->parentPlot();
 QCPRange limitRange(plot->property("ymin").toDouble(), plot->property("ymax").toDouble());
 limitAxisRange(axis, newRange, limitRange);
}
void MainWindow::limitAxisRange(QCPAxis * axis, const QCPRange & newRange, const QCPRange & limitRange)
{
 auto lowerBound = limitRange.lower;
 auto upperBound = limitRange.upper;
 // code assumes upperBound > lowerBound
 QCPRange fixedRange(newRange);
 if (fixedRange.lower < lowerBound)
 {
 fixedRange.lower = lowerBound;
 fixedRange.upper = lowerBound + newRange.size();
 if (fixedRange.upper > upperBound || qFuzzyCompare(newRange.size(), upperBound-lowerBound))
 fixedRange.upper = upperBound;
 axis->setRange(fixedRange); // adapt this line to use your plot/axis
 } else if (fixedRange.upper > upperBound)
 {
 fixedRange.upper = upperBound;
 fixedRange.lower = upperBound - newRange.size();
 if (fixedRange.lower < lowerBound || qFuzzyCompare(newRange.size(), upperBound-lowerBound))
 fixedRange.lower = lowerBound;
 axis->setRange(fixedRange); // adapt this line to use your plot/axis
 }
}

June 28, 2023, 19:43
by PavelSI

Code like this is blinking

if (fixedRange.lower < lowerBound)
 {
 fixedRange.lower = lowerBound;
 axis->setRange(fixedRange);

AltStyle によって変換されたページ (->オリジナル) /