Subplot Grid

2x2 grid with linked X-axes using AZPlotGrid.

Multi-Channel Display

Source Code

#include <QApplication>
#include <QWidget>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QCheckBox>
#include <QPushButton>
#include <cmath>

#include "AZPlotGrid.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    
    QWidget window;
    window.setWindowTitle("Subplot Grid Demo");
    window.resize(900, 650);
    
    QVBoxLayout *mainLayout = new QVBoxLayout(&window);
    mainLayout->setContentsMargins(10, 10, 10, 10);
    
    // Control bar
    QHBoxLayout *controlLayout = new QHBoxLayout();
    
    QCheckBox *linkXCheck = new QCheckBox("Link X Axes");
    linkXCheck->setChecked(true);
    
    QCheckBox *linkYCheck = new QCheckBox("Link Y Axes");
    linkYCheck->setChecked(false);
    
    QPushButton *resetBtn = new QPushButton("Reset All");
    
    controlLayout->addWidget(linkXCheck);
    controlLayout->addWidget(linkYCheck);
    controlLayout->addStretch();
    controlLayout->addWidget(resetBtn);
    
    mainLayout->addLayout(controlLayout);
    
    // Create 2x2 grid
    AZPlotGrid *grid = new AZPlotGrid(2, 2, &window);
    grid->setSpacing(8);
    grid->linkXAxes(true);
    
    // Generate shared frequency data
    QVector<double> freq, mag1, mag2, phase1, phase2;
    for (double f = 1; f <= 500; f += 1) {
        freq.append(f);
        
        double peak1 = 10 * std::exp(-std::pow(f - 50, 2) / 100);
        double peak2 = 5 * std::exp(-std::pow(f - 120, 2) / 200);
        
        mag1.append(0.5 + peak1);
        mag2.append(0.3 + peak2);
        phase1.append(-std::atan2(f, 50) * 180 / M_PI);
        phase2.append(-std::atan2(f, 120) * 180 / M_PI);
    }
    
    // Top-left: Magnitude 1
    grid->plot(0, 0)->addDataSeries(freq, mag1, "Channel 1", Qt::blue);
    grid->plot(0, 0)->setTitle("Magnitude - Ch1");
    grid->plot(0, 0)->setXAxisLabel("Frequency (Hz)");
    grid->plot(0, 0)->setYAxisLabel("Amplitude");
    grid->plot(0, 0)->addVerticalLine(50, Qt::darkGreen, "50 Hz", 0.5);
    grid->plot(0, 0)->autoScaleAll();
    
    // Top-right: Magnitude 2
    grid->plot(0, 1)->addDataSeries(freq, mag2, "Channel 2", Qt::red);
    grid->plot(0, 1)->setTitle("Magnitude - Ch2");
    grid->plot(0, 1)->setXAxisLabel("Frequency (Hz)");
    grid->plot(0, 1)->setYAxisLabel("Amplitude");
    grid->plot(0, 1)->addVerticalLine(120, Qt::darkGreen, "120 Hz", 0.5);
    grid->plot(0, 1)->autoScaleAll();
    
    // Bottom-left: Phase 1
    grid->plot(1, 0)->addDataSeries(freq, phase1, "Phase 1", Qt::blue);
    grid->plot(1, 0)->setTitle("Phase - Ch1");
    grid->plot(1, 0)->setXAxisLabel("Frequency (Hz)");
    grid->plot(1, 0)->setYAxisLabel("Phase (deg)");
    grid->plot(1, 0)->autoScaleAll();
    
    // Bottom-right: Phase 2
    grid->plot(1, 1)->addDataSeries(freq, phase2, "Phase 2", Qt::red);
    grid->plot(1, 1)->setTitle("Phase - Ch2");
    grid->plot(1, 1)->setXAxisLabel("Frequency (Hz)");
    grid->plot(1, 1)->setYAxisLabel("Phase (deg)");
    grid->plot(1, 1)->autoScaleAll();
    
    // Apply styling to all
    grid->applyProfessionalStyle();
    grid->setAllInteractive(true, true);
    
    mainLayout->addWidget(grid, 1);
    
    // Connect controls
    QObject::connect(linkXCheck, &QCheckBox::toggled, [grid](bool checked) {
        grid->linkXAxes(checked);
    });
    
    QObject::connect(linkYCheck, &QCheckBox::toggled, [grid](bool checked) {
        grid->linkYAxes(checked);
    });
    
    QObject::connect(resetBtn, &QPushButton::clicked, [grid]() {
        for (int i = 0; i < grid->plotCount(); ++i) {
            grid->plot(i)->resetZoom();
            grid->plot(i)->autoScaleAll();
        }
    });
    
    window.show();
    return app.exec();
}