QCustomPlot Discussion and Comments

Fixed 1:1 aspect ratio when zooming on a single axisReturn to overview

First of all: great work, this library is awesome!

How can I keep the aspect ratio of 1:1 in my plot even when zooming in or out?

As explained in the documentation, the QCPAxis::setScaleRatio changes the ranges only once.

Should I connect to some signal? Should I override some function?

I also checked this thread https://www.qcustomplot.com/index.php/support/forum/2198, which already provides a solution for the resizing of the window. I would like to obtain the same effect when zooming in or out on a single axis.

Thank you!

As you noticed, setScaleRatio only establishes the ratio once, and not permanently. This will be changed in future versions of QCustomPlot which will provide a new way to permanently connect axis ranges with defined scale factors.

For now, one solution is to use the rangeChanged signals. Due to floating point precision, you'll have to temporarily disconnect and re-connect the signals while setting the scales, to not cause infinite recursion.

For example

// Connect to rangeChanged signal for both the x and y axes
connect(ui->customPlot->xAxis, SIGNAL(rangeChanged(QCPRange)), this, SLOT(fixAxisRatioSlot(QCPRange)));
connect(ui->customPlot->yAxis, SIGNAL(rangeChanged(QCPRange)), this, SLOT(fixAxisRatioSlot(QCPRange)));

// Slot to rescale both axes to maintain a 1:1 aspect ratio
void MyWidget::fixAxisRatioSlot(const QCPRange &newRange)
{
    // Disconnect rangeChanged signals for the axes being rescaled
    disconnect(ui->customPlot->xAxis, SIGNAL(rangeChanged(QCPRange)), this, SLOT(fixAxisRatioSlot(QCPRange)));
    disconnect(ui->customPlot->yAxis, SIGNAL(rangeChanged(QCPRange)), this, SLOT(fixAxisRatioSlot(QCPRange)));

    ui->customPlot->xAxis->setScaleRatio(ui->customPlot->yAxis, 1.0);

    // Reconnect rangeChanged signals for the axes being rescaled
    connect(ui->customPlot->xAxis, SIGNAL(rangeChanged(QCPRange)), this, SLOT(fixAxisRatioSlot(QCPRange)));
    connect(ui->customPlot->yAxis, SIGNAL(rangeChanged(QCPRange)), this, SLOT(fixAxisRatioSlot(QCPRange)));
}


Thank you! This solution has the drawback of losing the nice feature of zooming on the mouse cursor when the zoom is performed on the main area of the plot, and not on a single axis. This is because when the user zooms in/out on the main area, two rangeChanged events are fired: one for the x axis and one for the y axis. Please consider this in the future implementation you mentioned!