Do you mean like in the
https://www.qcustomplot.com/index.php/demos/advancedaxesdemo
demo, the left axis? Or really on top of each other? you could try playing with the setOffset or perhaps modifying the QCPAxis to report a minimum margin of 0.
Thanks for the reply.
When adding a new valueAxis, the axes are horizontally layed out, allowing graphs to use the whole height of the axisRect.
I would like to lay out value axes vertically.
The closest examples of what i want to achieve are seismogram or F1 lap telemetry plot.
I already tried to hack qcp and achieved to set the axis height and position, but before going further, just want to know if someone has faced this need and found a nice solution.
I managed to quickly do what i want.
Here is the result : https://postimg.cc/ZWRGQbFV/84b3bc7a
To do so, i create fake visible axes aligned vertically in a QCPLayoutGrid.
For each graph, we need to create specific hidden axis.
And after updating the layout, the ranges of hidden axes are calculated based on the range/height/position of the associated fake axis.
Code balow, based on the plot-examples project :
void MainWindow::setupStackedAxis(QCustomPlot *customPlot) { demoName = "Stacked Axes Demo"; customPlot->plotLayout()->clear(); // clear default axis rect so we can start from scratch QCPAxisRect *wideAxisRect = new QCPAxisRect(customPlot, false); wideAxisRect->setMinimumMargins(QMargins(15, 15, 5, 15)); wideAxisRect->setupFullAxesBox(true); wideAxisRect->axis(QCPAxis::atLeft)->setVisible(false); wideAxisRect->axis(QCPAxis::atTop)->setVisible(false); wideAxisRect->axis(QCPAxis::atRight)->grid()->setVisible(true); wideAxisRect->axis(QCPAxis::atBottom)->grid()->setVisible(true); QCPLayoutGrid *subLayout = new QCPLayoutGrid; subLayout->setFillOrder(QCPLayoutGrid::foRowsFirst); customPlot->plotLayout()->addElement(0, 0, wideAxisRect); // insert axis rect in first row customPlot->plotLayout()->addElement(0, 1, subLayout); // sub layout in second row (grid layout will grow accordingly) customPlot->plotLayout()->setColumnStretchFactor(0,1); customPlot->plotLayout()->setColumnStretchFactor(1, 0.001); // create fake axis QCPAxisRect *subRectTop = new QCPAxisRect(customPlot, false); auto topAxis = subRectTop->addAxis(QCPAxis::atRight); topAxis->setTickLabelColor(Qt::blue); topAxis->setTickPen(QPen(Qt::blue)); topAxis->setSubTickPen(QPen(Qt::blue)); topAxis->setBasePen(QPen(Qt::blue)); topAxis->ticker()->setTickCount(3); subRectTop->setMinimumSize(0,0); subRectTop->setMinimumMargins(QMargins(5, 15, 40, 5)); subLayout->addElement(subRectTop); //Create real axis - not visible auto firstAxis = wideAxisRect->addAxis(QCPAxis::atRight); firstAxis->setVisible(false); QCPAxisRect *subRectMiddle = new QCPAxisRect(customPlot, false); auto middleAxis = subRectMiddle->addAxis(QCPAxis::atRight); middleAxis->setTickLabelColor(Qt::red); middleAxis->setTickPen(QPen(Qt::red)); middleAxis->setSubTickPen(QPen(Qt::red)); middleAxis->setBasePen(QPen(Qt::red)); middleAxis->ticker()->setTickCount(3); subRectMiddle->setMinimumSize(0,0); subRectMiddle->setMinimumMargins(QMargins(5, 5, 40, 5)); subLayout->addElement(subRectMiddle); auto secondAxis = wideAxisRect->addAxis(QCPAxis::atRight); secondAxis->setVisible(false); QCPAxisRect *subRectBottom = new QCPAxisRect(customPlot, false); auto bottomAxis = subRectBottom->addAxis(QCPAxis::atRight); bottomAxis->setTickLabelColor(Qt::green); bottomAxis->setTickPen(QPen(Qt::green)); bottomAxis->setSubTickPen(QPen(Qt::green)); bottomAxis->setBasePen(QPen(Qt::green)); bottomAxis->ticker()->setTickCount(3); subRectBottom->setMinimumSize(0,0); subRectBottom->setMinimumMargins(QMargins(5, 5, 40, 15)); subLayout->addElement(subRectBottom); auto thirdAxis = wideAxisRect->addAxis(QCPAxis::atRight); thirdAxis->setVisible(false); foreach (QCPAxisRect *rect, customPlot->axisRects()) { foreach (QCPAxis *axis, rect->axes()) { axis->setLayer("axes"); axis->grid()->setLayer("grid"); } } QCPGraph *graphCosFirst = customPlot->addGraph(wideAxisRect->axis(QCPAxis::atBottom), firstAxis); graphCosFirst->setPen(QPen(Qt::blue)); QCPGraph *graphCosSecond = customPlot->addGraph(wideAxisRect->axis(QCPAxis::atBottom), secondAxis); graphCosSecond->setPen(QPen(Qt::red)); QCPGraph *graphCosThird = customPlot->addGraph(wideAxisRect->axis(QCPAxis::atBottom), thirdAxis); graphCosThird->setPen(QPen(Qt::green)); QVector<QCPGraphData> dataCos(51); for (int i=0; i<dataCos.size(); ++i) { auto key = i/(double)(dataCos.size()-1)*10-5.0; auto value = qCos(key); graphCosFirst->addData(key, value); graphCosSecond->addData(key, value); graphCosThird->addData(key, value); } wideAxisRect->axis(QCPAxis::atBottom)->rescale(); topAxis->setRange(0,1); middleAxis->setRange(-0.5,0.5); bottomAxis->setRange(-2,0); QCPMarginGroup *marginGroup = new QCPMarginGroup(customPlot); subRectTop->setMarginGroup(QCP::msTop, marginGroup); subRectBottom->setMarginGroup(QCP::msBottom, marginGroup); wideAxisRect->setMarginGroup(QCP::msTop | QCP::msBottom, marginGroup); connect(customPlot, &QCustomPlot::afterLayout, this, [=](){ { auto pixelRatio = topAxis->range().size() / (topAxis->coordToPixel(topAxis->range().lower) - topAxis->coordToPixel(topAxis->range().upper)); auto topOffset = (topAxis->coordToPixel(topAxis->range().upper) - wideAxisRect->rect().top()) * pixelRatio; auto bottomOffset = (wideAxisRect->rect().bottom() - topAxis->coordToPixel(topAxis->range().lower)) * pixelRatio; firstAxis->setRange(topAxis->range().lower - bottomOffset, topAxis->range().upper + topOffset); } { auto pixelRatio = middleAxis->range().size() / (middleAxis->coordToPixel(middleAxis->range().lower) - middleAxis->coordToPixel(middleAxis->range().upper)); auto topOffset = (middleAxis->coordToPixel(middleAxis->range().upper) - wideAxisRect->rect().top()) * pixelRatio; auto bottomOffset = (wideAxisRect->rect().bottom() - middleAxis->coordToPixel(middleAxis->range().lower)) * pixelRatio; secondAxis->setRange(middleAxis->range().lower - bottomOffset, middleAxis->range().upper + topOffset); } { auto pixelRatio = bottomAxis->range().size() / (bottomAxis->coordToPixel(bottomAxis->range().lower) - bottomAxis->coordToPixel(bottomAxis->range().upper)); auto topOffset = (bottomAxis->coordToPixel(bottomAxis->range().upper) - wideAxisRect->rect().top()) * pixelRatio; auto bottomOffset = (wideAxisRect->rect().bottom() - bottomAxis->coordToPixel(bottomAxis->range().lower)) * pixelRatio; thirdAxis->setRange(bottomAxis->range().lower - bottomOffset, bottomAxis->range().upper + topOffset); } }); }