87
Plot Screenshots: Simple Demo

Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

  • Upload
    others

  • View
    8

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

Plot Screenshots: Simple Demo

Page 2: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

// add two new graphs and set their look:customPlot->addGraph();customPlot->graph(0)->setPen(QPen(Qt::blue)); // line color blue for first graphcustomPlot->graph(0)->setBrush(QBrush(QColor(0, 0, 255, 20))); // first graph will be filled with translucent bluecustomPlot->addGraph();

Page 3: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph// generate some points of data (y0 for first, y1 for second graph):QVector<double> x(250), y0(250), y1(250);for(inti=0; i<250; ++i){

x[i] = i;y0[i] = qExp(-i/150.0)*qCos(i/10.0); // exponentially decaying cosiney1[i] = qExp(-i/150.0); // exponential envelope

}// configure right and top axis to show ticks but no labels:// (see QCPAxisRect::setupFullAxesBox for a quicker method to do this)customPlot->xAxis2->setVisible(true);customPlot->xAxis2->setTickLabels(false);customPlot->yAxis2->setVisible(true);customPlot->yAxis2->setTickLabels(false);// make left and bottom axes always transfer their ranges to right and top axes:connect(customPlot->xAxis, SIGNAL(rangeChanged(QCPRange)), customPlot->xAxis2, SLOT(setRange(QCPRange)));connect(customPlot->yAxis, SIGNAL(rangeChanged(QCPRange)), customPlot->yAxis2, SLOT(setRange(QCPRange)));// pass data points to graphs:customPlot->graph(0)->setData(x, y0);customPlot->graph(1)->setData(x, y1);// let the ranges scale themselves so graph 0 fits perfectly in the visible area:customPlot->graph(0)->rescaleAxes();// same thing for graph 1, but only enlarge ranges (in case graph 1 is smaller than graph 0):customPlot->graph(1)->rescaleAxes(true);// Note: we could have also just called customPlot->rescaleAxes(); instead

Page 4: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

// Allow user to drag axis ranges with mouse, zoom with mouse wheel and select graphs by clicking:customPlot->setInteractions(QCP::iRangeDrag| QCP::iRangeZoom| QCP::iSelectPlottables);

Page 5: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

Plot Screenshots: Sinc Scatter Demo

Page 6: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

customPlot->legend->setVisible(true);customPlot->legend->setFont(QFont("Helvetica",9));// set locale to english, so we get english decimal separator:customPlot->setLocale(QLocale(QLocale::English, QLocale::UnitedKingdom));// add confidence band graphs:customPlot->addGraph();QPenpen;pen.setStyle(Qt::DotLine);pen.setWidth(1);pen.setColor(QColor(180,180,180));customPlot->graph(0)->setName("Confidence Band 68%");customPlot->graph(0)->setPen(pen);customPlot->graph(0)->setBrush(QBrush(QColor(255,50,30,20)));customPlot->addGraph();customPlot->legend->removeItem(customPlot->legend->itemCount()-1); // don't show two confidence band graphs in legendcustomPlot->graph(1)->setPen(pen);customPlot->graph(0)->setChannelFillGraph(customPlot->graph(1));// add theory curve graph:customPlot->addGraph();pen.setStyle(Qt::DashLine);pen.setWidth(2);pen.setColor(Qt::red);customPlot->graph(2)->setPen(pen);customPlot->graph(2)->setName("Theory Curve");// add data point graph:customPlot->addGraph();

Page 7: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

customPlot->graph(3)->setPen(QPen(Qt::blue));customPlot->graph(3)->setLineStyle(QCPGraph::lsNone);customPlot->graph(3)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCross, 4));customPlot->graph(3)->setErrorType(QCPGraph::etValue);customPlot->graph(3)->setErrorPen(QPen(QColor(180,180,180)));customPlot->graph(3)->setName("Measurement");

// generate ideal sinc curve data and some randomly perturbed data for scatter plot:QVector<double> x0(250), y0(250);QVector<double> yConfUpper(250), yConfLower(250);for(inti=0; i<250; ++i){

x0[i] = (i/249.0-0.5)*30+0.01; // by adding a small offset we make sure not do divide by zero in next code liney0[i] = qSin(x0[i])/x0[i]; // sinc functionyConfUpper[i] = y0[i]+0.15;yConfLower[i] = y0[i]-0.15;x0[i] *= 1000;

}QVector<double> x1(50), y1(50), y1err(50);for(inti=0; i<50; ++i){

// generate a gaussian distributed random number:doubletmp1 = rand()/(double)RAND_MAX;doubletmp2 = rand()/(double)RAND_MAX;doubler = qSqrt(-2*qLn(tmp1))*qCos(2*M_PI*tmp2); // box-muller transform for gaussian distribution// set y1 to value of y0 plus a random gaussian pertubation:

Page 8: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

x1[i] = (i/50.0-0.5)*30+0.25;y1[i] = qSin(x1[i])/x1[i]+r*0.15;x1[i] *= 1000;y1err[i] = 0.15;

}// pass data to graphs and let QCustomPlot determine the axes ranges so the whole thing is visible:customPlot->graph(0)->setData(x0, yConfUpper);customPlot->graph(1)->setData(x0, yConfLower);customPlot->graph(2)->setData(x0, y0);customPlot->graph(3)->setDataValueError(x1, y1, y1err);customPlot->graph(2)->rescaleAxes();customPlot->graph(3)->rescaleAxes(true);// setup look of bottom tick labels:customPlot->xAxis->setTickLabelRotation(30);customPlot->xAxis->setAutoTickCount(9);customPlot->xAxis->setNumberFormat("ebc");customPlot->xAxis->setNumberPrecision(1);customPlot->xAxis->moveRange(-10);// make top right axes clones of bottom left axes. Looks prettier:customPlot->axisRect()->setupFullAxesBox();

Page 9: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

Plot Screenshots: Scatter Style Demo

Page 10: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

customPlot->legend->setVisible(true);customPlot->legend->setFont(QFont("Helvetica", 9));customPlot->legend->setRowSpacing(-3);QVector<QCPScatterStyle::ScatterShape> shapes;shapes << QCPScatterStyle::ssCross;shapes << QCPScatterStyle::ssPlus;shapes << QCPScatterStyle::ssCircle;shapes << QCPScatterStyle::ssDisc;shapes << QCPScatterStyle::ssSquare;shapes << QCPScatterStyle::ssDiamond;shapes << QCPScatterStyle::ssStar;shapes << QCPScatterStyle::ssTriangle;shapes << QCPScatterStyle::ssTriangleInverted;shapes << QCPScatterStyle::ssCrossSquare;shapes << QCPScatterStyle::ssPlusSquare;shapes << QCPScatterStyle::ssCrossCircle;shapes << QCPScatterStyle::ssPlusCircle;shapes << QCPScatterStyle::ssPeace;shapes << QCPScatterStyle::ssCustom;

QPenpen;// add graphs with different scatter styles:for(inti=0; i<shapes.size(); ++i){

customPlot->addGraph();

Page 11: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

pen.setColor(QColor(qSin(i*0.3)*100+100, qSin(i*0.6+0.7)*100+100, qSin(i*0.4+0.6)*100+100));// generate data:QVector<double> x(10), y(10);for(intk=0; k<10; ++k){

x[k] = k/10.0* 4*3.14+ 0.01;y[k] = 7*qSin(x[k])/x[k] + (shapes.size()-i)*5;

}customPlot->graph()->setData(x, y);customPlot->graph()->rescaleAxes(true);customPlot->graph()->setPen(pen);customPlot->graph()->setName(QCPScatterStyle::staticMetaObject.enumerator(QCPScatterStyle::staticMetaObject.inde

xOfEnumerator("ScatterShape")).valueToKey(shapes.at(i)));customPlot->graph()->setLineStyle(QCPGraph::lsLine);// set scatter style:if(shapes.at(i) != QCPScatterStyle::ssCustom){

customPlot->graph()->setScatterStyle(QCPScatterStyle(shapes.at(i), 10));}else{

QPainterPathcustomScatterPath;for(inti=0; i<3; ++i)

customScatterPath.cubicTo(qCos(2*M_PI*i/3.0)*9, qSin(2*M_PI*i/3.0)*9, qCos(2*M_PI*(i+0.9)/3.0)*9, qSin(2*M_PI*(i+0.9)/3.0)*9, 0, 0);

Page 12: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

customPlot->graph()->setScatterStyle(QCPScatterStyle(customScatterPath, QPen(Qt::black, 0), QColor(40, 70, 255, 50), 10));

}}// set blank axis lines:customPlot->rescaleAxes();customPlot->xAxis->setTicks(false);customPlot->yAxis->setTicks(false);customPlot->xAxis->setTickLabels(false);customPlot->yAxis->setTickLabels(false);// make top right axes clones of bottom left axes:customPlot->axisRect()->setupFullAxesBox();

Page 13: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

Plot Screenshots: Styled Plot Demo

Page 14: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

// prepare data:QVector<double> x1(20), y1(20);QVector<double> x2(100), y2(100);QVector<double> x3(20), y3(20);QVector<double> x4(20), y4(20);for(inti=0; i<x1.size(); ++i){

x1[i] = i/(double)x1.size()*10;y1[i] = qCos(x1[i]*0.8+qSin(x1[i]*0.16+1.0))*qSin(x1[i]*0.54)+1.4;

}for(inti=0; i<x2.size(); ++i){

x2[i] = i/(double)x2.size()*10;y2[i] = qCos(x2[i]*0.85+qSin(x2[i]*0.165+1.1))*qSin(x2[i]*0.50)+1.7;

}for(inti=0; i<x3.size(); ++i){

x3[i] = i/(double)x3.size()*10;y3[i] = 0.05+3*(0.5+qCos(x3[i]*x3[i]*0.2+2)*0.5)/(double)(x3[i]+0.7)+qrand()/(double)RAND_MAX*0.01;

}for(inti=0; i<x4.size(); ++i){

x4[i] = x3[i];y4[i] = (0.5-y3[i])+((x4[i]-2)*(x4[i]-2)*0.02);

}

Page 15: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

// create and configure plottables:QCPGraph*graph1 = customPlot->addGraph();graph1->setData(x1, y1);graph1->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, QPen(Qt::black, 1.5), QBrush(Qt::white), 9));graph1->setPen(QPen(QColor(120, 120, 120), 2));

QCPGraph*graph2 = customPlot->addGraph();graph2->setData(x2, y2);graph2->setPen(Qt::NoPen);graph2->setBrush(QColor(200, 200, 200, 20));graph2->setChannelFillGraph(graph1);

QCPBars*bars1 = newQCPBars(customPlot->xAxis, customPlot->yAxis);customPlot->addPlottable(bars1);bars1->setWidth(9/(double)x3.size());bars1->setData(x3, y3);bars1->setPen(Qt::NoPen);bars1->setBrush(QColor(10, 140, 70, 160));

QCPBars*bars2 = newQCPBars(customPlot->xAxis, customPlot->yAxis);customPlot->addPlottable(bars2);bars2->setWidth(9/(double)x4.size());bars2->setData(x4, y4);bars2->setPen(Qt::NoPen);bars2->setBrush(QColor(10, 100, 50, 70));bars2->moveAbove(bars1);

Page 16: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

// move bars above graphs and grid below bars:customPlot->addLayer("abovemain", customPlot->layer("main"), QCustomPlot::limAbove);customPlot->addLayer("belowmain", customPlot->layer("main"), QCustomPlot::limBelow);graph1->setLayer("abovemain");customPlot->xAxis->grid()->setLayer("belowmain");customPlot->yAxis->grid()->setLayer("belowmain");

// set some pens, brushes and backgrounds:customPlot->xAxis->setBasePen(QPen(Qt::white, 1));customPlot->yAxis->setBasePen(QPen(Qt::white, 1));customPlot->xAxis->setTickPen(QPen(Qt::white, 1));customPlot->yAxis->setTickPen(QPen(Qt::white, 1));customPlot->xAxis->setSubTickPen(QPen(Qt::white, 1));customPlot->yAxis->setSubTickPen(QPen(Qt::white, 1));customPlot->xAxis->setTickLabelColor(Qt::white);customPlot->yAxis->setTickLabelColor(Qt::white);customPlot->xAxis->grid()->setPen(QPen(QColor(140, 140, 140), 1, Qt::DotLine));customPlot->yAxis->grid()->setPen(QPen(QColor(140, 140, 140), 1, Qt::DotLine));customPlot->xAxis->grid()->setSubGridPen(QPen(QColor(80, 80, 80), 1, Qt::DotLine));customPlot->yAxis->grid()->setSubGridPen(QPen(QColor(80, 80, 80), 1, Qt::DotLine));customPlot->xAxis->grid()->setSubGridVisible(true);customPlot->yAxis->grid()->setSubGridVisible(true);customPlot->xAxis->grid()->setZeroLinePen(Qt::NoPen);customPlot->yAxis->grid()->setZeroLinePen(Qt::NoPen);customPlot->xAxis->setUpperEnding(QCPLineEnding::esSpikeArrow);

Page 17: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

customPlot->yAxis->setUpperEnding(QCPLineEnding::esSpikeArrow);QLinearGradientplotGradient;plotGradient.setStart(0, 0);plotGradient.setFinalStop(0, 350);plotGradient.setColorAt(0, QColor(80, 80, 80));plotGradient.setColorAt(1, QColor(50, 50, 50));customPlot->setBackground(plotGradient);QLinearGradientaxisRectGradient;axisRectGradient.setStart(0, 0);axisRectGradient.setFinalStop(0, 350);axisRectGradient.setColorAt(0, QColor(80, 80, 80));axisRectGradient.setColorAt(1, QColor(30, 30, 30));customPlot->axisRect()->setBackground(axisRectGradient);

customPlot->rescaleAxes();customPlot->yAxis->setRange(0, 2);

Page 18: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

Plot Screenshots: Color Map Demo

Page 19: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

// configure axis rect:customPlot->setInteractions(QCP::iRangeDrag|QCP::iRangeZoom); // this will also allow rescaling the color scale by dragging/zoomingcustomPlot->axisRect()->setupFullAxesBox(true);customPlot->xAxis->setLabel("x");customPlot->yAxis->setLabel("y");

// set up the QCPColorMap:QCPColorMap*colorMap = newQCPColorMap(customPlot->xAxis, customPlot->yAxis);customPlot->addPlottable(colorMap);intnx = 200;intny = 200;colorMap->data()->setSize(nx, ny); // we want the color map to have nx * ny data pointscolorMap->data()->setRange(QCPRange(-4, 4), QCPRange(-4, 4)); // and span the coordinate range -4..4 in both key (x) and value (y) dimensions// now we assign some data, by accessing the QCPColorMapData instance of the color map:doublex, y, z;for(intxIndex=0; xIndex<nx; ++xIndex){

for(intyIndex=0; yIndex<ny; ++yIndex){

colorMap->data()->cellToCoord(xIndex, yIndex, &x, &y);doubler = 3*qSqrt(x*x+y*y)+1e-2;z = 2*x*(qCos(r+2)/r-qSin(r+2)/r); // the B field strength of dipole radiation (modulo physical constants)colorMap->data()->setCell(xIndex, yIndex, z);

}

Page 20: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

}

// add a color scale:QCPColorScale*colorScale = newQCPColorScale(customPlot);customPlot->plotLayout()->addElement(0, 1, colorScale); // add it to the right of the main axis rectcolorScale->setType(QCPAxis::atRight); // scale shall be vertical bar with tick/axis labels right (actually atRight is already the default)colorMap->setColorScale(colorScale); // associate the color map with the color scalecolorScale->axis()->setLabel("Magnetic Field Strength");

// set the color gradient of the color map to one of the presets:colorMap->setGradient(QCPColorGradient::gpPolar);// we could have also created a QCPColorGradient instance and added own colors to// the gradient, see the documentation of QCPColorGradient for what's possible.

// rescale the data dimension (color) such that all data points lie in the span visualized by the color gradient:colorMap->rescaleDataRange();

// make sure the axis rect and color scale synchronize their bottom and top margins (so they line up):QCPMarginGroup*marginGroup = newQCPMarginGroup(customPlot);customPlot->axisRect()->setMarginGroup(QCP::msBottom|QCP::msTop, marginGroup);colorScale->setMarginGroup(QCP::msBottom|QCP::msTop, marginGroup);

// rescale the key (x) and value (y) axes so the whole color map is visible:customPlot->rescaleAxes();

Page 21: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

Plot Screenshots: Scatter Pixmap Demo

Page 22: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

customPlot->axisRect()->setBackground(QPixmap("./solarpanels.jpg"));customPlot->addGraph();customPlot->graph()->setLineStyle(QCPGraph::lsLine);QPenpen;pen.setColor(QColor(255, 200, 20, 200));pen.setStyle(Qt::DashLine);pen.setWidthF(2.5);customPlot->graph()->setPen(pen);customPlot->graph()->setBrush(QBrush(QColor(255,200,20,70)));customPlot->graph()->setScatterStyle(QCPScatterStyle(QPixmap("./sun.png")));// set graph name, will show up in legend next to icon:customPlot->graph()->setName("Data from Photovoltaic\nenergy barometer 2011");// set data:QVector<double> year, value;year << 2005<< 2006<< 2007<< 2008 << 2009 << 2010;value << 2.17<< 3.42<< 4.94<< 10.38<< 15.86<< 29.33;customPlot->graph()->setData(year, value);

// set title of plot:customPlot->plotLayout()->insertRow(0);customPlot->plotLayout()->addElement(0, 0, newQCPPlotTitle(customPlot, "Regenerative Energies"));// set a fixed tick-step to one tick per year value:customPlot->xAxis->setAutoTickStep(false);customPlot->xAxis->setTickStep(1);customPlot->xAxis->setSubTickCount(3);// other axis configurations:

Page 23: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

customPlot->xAxis->setLabel("Year");customPlot->yAxis->setLabel("Installed Gigawatts of\nphotovoltaic in the European Union");customPlot->xAxis2->setVisible(true);customPlot->yAxis2->setVisible(true);customPlot->xAxis2->setTickLabels(false);customPlot->yAxis2->setTickLabels(false);customPlot->xAxis2->setTicks(false);customPlot->yAxis2->setTicks(false);customPlot->xAxis2->setSubTickCount(0);customPlot->yAxis2->setSubTickCount(0);customPlot->xAxis->setRange(2004.5, 2010.5);customPlot->yAxis->setRange(0, 30);// setup legend:customPlot->legend->setFont(QFont(font().family(), 7));customPlot->legend->setIconSize(50, 20);customPlot->legend->setVisible(true);

Page 24: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

Plot Screenshots: Realtime Data Demo

Page 25: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

Setup function: customPlot->addGraph(); // blue linecustomPlot->graph(0)->setPen(QPen(Qt::blue));customPlot->graph(0)->setBrush(QBrush(QColor(240, 255, 200)));customPlot->graph(0)->setAntialiasedFill(false);customPlot->addGraph(); // red linecustomPlot->graph(1)->setPen(QPen(Qt::red));customPlot->graph(0)->setChannelFillGraph(customPlot->graph(1));

customPlot->addGraph(); // blue dotcustomPlot->graph(2)->setPen(QPen(Qt::blue));customPlot->graph(2)->setLineStyle(QCPGraph::lsNone);customPlot->graph(2)->setScatterStyle(QCPScatterStyle::ssDisc);customPlot->addGraph(); // red dotcustomPlot->graph(3)->setPen(QPen(Qt::red));customPlot->graph(3)->setLineStyle(QCPGraph::lsNone);customPlot->graph(3)->setScatterStyle(QCPScatterStyle::ssDisc);

customPlot->xAxis->setTickLabelType(QCPAxis::ltDateTime);customPlot->xAxis->setDateTimeFormat("hh:mm:ss");customPlot->xAxis->setAutoTickStep(false);customPlot->xAxis->setTickStep(2);customPlot->axisRect()->setupFullAxesBox();

// make left and bottom axes transfer their ranges to right and top axes:

Page 26: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

connect(customPlot->xAxis, SIGNAL(rangeChanged(QCPRange)), customPlot->xAxis2, SLOT(setRange(QCPRange)));connect(customPlot->yAxis, SIGNAL(rangeChanged(QCPRange)), customPlot->yAxis2, SLOT(setRange(QCPRange)));

// setup a timer that repeatedly calls MainWindow::realtimeDataSlot:connect(&dataTimer, SIGNAL(timeout()), this, SLOT(realtimeDataSlot()));dataTimer.start(0); // Interval 0 means to refresh as fast as possible

realtimeDataSlot , called by timer: // calculate two new data points:doublekey = QDateTime::currentDateTime().toMSecsSinceEpoch()/1000.0;staticdoublelastPointKey = 0;if(key-lastPointKey > 0.01) // at most add point every 10 ms{

doublevalue0 = qSin(key); //qSin(key*1.6+qCos(key*1.7)*2)*10 + qSin(key*1.2+0.56)*20 + 26;doublevalue1 = qCos(key); //qSin(key*1.3+qCos(key*1.2)*1.2)*7 + qSin(key*0.9+0.26)*24 + 26;// add data to lines:ui->customPlot->graph(0)->addData(key, value0);ui->customPlot->graph(1)->addData(key, value1);// set data of dots:ui->customPlot->graph(2)->clearData();ui->customPlot->graph(2)->addData(key, value0);

Page 27: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

ui->customPlot->graph(3)->clearData();ui->customPlot->graph(3)->addData(key, value1);// remove data of lines that's outside visible range:ui->customPlot->graph(0)->removeDataBefore(key-8);ui->customPlot->graph(1)->removeDataBefore(key-8);// rescale value (vertical) axis to fit the current data:ui->customPlot->graph(0)->rescaleValueAxis();ui->customPlot->graph(1)->rescaleValueAxis(true);lastPointKey = key;

}// make key axis range scroll with the data (at a constant range size of 8):ui->customPlot->xAxis->setRange(key+0.25, 8, Qt::AlignRight);ui->customPlot->replot();

// calculate frames per second:staticdoublelastFpsKey;staticintframeCount;++frameCount;if(key-lastFpsKey > 2) // average fps over 2 seconds{

ui->statusBar->showMessage(QString("%1 FPS, Total Data points: %2").arg(frameCount/(key-lastFpsKey), 0, 'f', 0).arg(ui->customPlot->graph(0)->data()->count()+ui->customPlot->graph(1)->data()->count()), 0);

lastFpsKey = key;

Page 28: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

frameCount = 0;}

Page 29: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

Plot Screenshots: Multiple Axes Demo

Page 30: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

customPlot->setLocale(QLocale(QLocale::English, QLocale::UnitedKingdom)); // period as decimal separator and comma as thousand separatorcustomPlot->legend->setVisible(true);QFontlegendFont = font(); // start out with MainWindow's font..legendFont.setPointSize(9); // and make a bit smaller for legendcustomPlot->legend->setFont(legendFont);customPlot->legend->setBrush(QBrush(QColor(255,255,255,230)));// by default, the legend is in the inset layout of the main axis rect. So this is how we access it to change legend placement:customPlot->axisRect()->insetLayout()->setInsetAlignment(0, Qt::AlignBottom|Qt::AlignRight);

// setup for graph 0: key axis left, value axis bottom// will contain left maxwell-like functioncustomPlot->addGraph(customPlot->yAxis, customPlot->xAxis);customPlot->graph(0)->setPen(QPen(QColor(255, 100, 0)));customPlot->graph(0)->setBrush(QBrush(QPixmap("./balboa.jpg"))); // fill with texture of specified imagecustomPlot->graph(0)->setLineStyle(QCPGraph::lsLine);customPlot->graph(0)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssDisc, 5));customPlot->graph(0)->setName("Left maxwell function");

// setup for graph 1: key axis bottom, value axis left (those are the default axes)// will contain bottom maxwell-like functioncustomPlot->addGraph();customPlot->graph(1)->setPen(QPen(Qt::red));customPlot->graph(1)->setBrush(QBrush(QPixmap("./balboa.jpg"))); // same fill as we used for graph 0customPlot->graph(1)->setLineStyle(QCPGraph::lsStepCenter);customPlot->graph(1)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, Qt::red, Qt::white, 7));

Page 31: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

customPlot->graph(1)->setErrorType(QCPGraph::etValue);customPlot->graph(1)->setName("Bottom maxwell function");

// setup for graph 2: key axis top, value axis right// will contain high frequency sine with low frequency beating:customPlot->addGraph(customPlot->xAxis2, customPlot->yAxis2);customPlot->graph(2)->setPen(QPen(Qt::blue));customPlot->graph(2)->setName("High frequency sine");

// setup for graph 3: same axes as graph 2// will contain low frequency beating envelope of graph 2customPlot->addGraph(customPlot->xAxis2, customPlot->yAxis2);QPenblueDotPen;blueDotPen.setColor(QColor(30, 40, 255, 150));blueDotPen.setStyle(Qt::DotLine);blueDotPen.setWidthF(4);customPlot->graph(3)->setPen(blueDotPen);customPlot->graph(3)->setName("Sine envelope");

// setup for graph 4: key axis right, value axis top// will contain parabolically distributed data points with some random perturbancecustomPlot->addGraph(customPlot->yAxis2, customPlot->xAxis2);customPlot->graph(4)->setPen(QColor(50, 50, 50, 255));customPlot->graph(4)->setLineStyle(QCPGraph::lsNone);customPlot->graph(4)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, 4));customPlot->graph(4)->setName("Some random data around\na quadratic function");

Page 32: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

// generate data, just playing with numbers, not much to learn here:QVector<double> x0(25), y0(25);QVector<double> x1(15), y1(15), y1err(15);QVector<double> x2(250), y2(250);QVector<double> x3(250), y3(250);QVector<double> x4(250), y4(250);for(inti=0; i<25; ++i) // data for graph 0{

x0[i] = 3*i/25.0;y0[i] = qExp(-x0[i]*x0[i]*0.8)*(x0[i]*x0[i]+x0[i]);

}for(inti=0; i<15; ++i) // data for graph 1{

x1[i] = 3*i/15.0;;y1[i] = qExp(-x1[i]*x1[i])*(x1[i]*x1[i])*2.6;y1err[i] = y1[i]*0.25;

}for(inti=0; i<250; ++i) // data for graphs 2, 3 and 4{

x2[i] = i/250.0*3*M_PI;x3[i] = x2[i];x4[i] = i/250.0*100-50;y2[i] = qSin(x2[i]*12)*qCos(x2[i])*10;y3[i] = qCos(x3[i])*10;y4[i] = 0.01*x4[i]*x4[i] + 1.5*( rand ()/(double)RAND_MAX-0.5) + 1.5*M_PI;

Page 33: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

}

// pass data points to graphs:customPlot->graph(0)->setData(x0, y0);customPlot->graph(1)->setDataValueError(x1, y1, y1err);customPlot->graph(2)->setData(x2, y2);customPlot->graph(3)->setData(x3, y3);customPlot->graph(4)->setData(x4, y4);// activate top and right axes, which are invisible by default:customPlot->xAxis2->setVisible(true);customPlot->yAxis2->setVisible(true);// set ranges appropriate to show data:customPlot->xAxis->setRange(0, 2.7);customPlot->yAxis->setRange(0, 2.6);customPlot->xAxis2->setRange(0, 3.0*M_PI);customPlot->yAxis2->setRange(-70, 35);// set pi ticks on top axis:QVector<double> piTicks;QVector<QString> piLabels;piTicks << 0 << 0.5*M_PI << M_PI << 1.5*M_PI << 2*M_PI << 2.5*M_PI << 3*M_PI;piLabels << "0"<< QString::fromUtf8("? π ") << QString::fromUtf8(" π") < < QString::fromUtf8("1? π") << QString::fromUtf8("2 π ") << QString::fromUtf8("2? π ") << QString::fromUtf8("3 π");customPlot->xAxis2->setAutoTicks(false);customPlot->xAxis2->setAutoTickLabels(false);customPlot->xAxis2->setTickVector(piTicks);customPlot->xAxis2->setTickVectorLabels(piLabels);

Page 34: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

// add title layout element:customPlot->plotLayout()->insertRow(0);customPlot->plotLayout()->addElement(0, 0, newQCPPlotTitle(customPlot, "Way too many graphs in one plot"));// set labels:customPlot->xAxis->setLabel("Bottom axis with outward ticks");customPlot->yAxis->setLabel("Left axis label");customPlot->xAxis2->setLabel("Top axis label");customPlot->yAxis2->setLabel("Right axis label");// make ticks on bottom axis go outward:customPlot->xAxis->setTickLength(0, 5);customPlot->xAxis->setSubTickLength(0, 3);// make ticks on right axis go inward and outward:customPlot->yAxis2->setTickLength(3, 3);customPlot->yAxis2->setSubTickLength(1, 1);

Page 35: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

Plot Screenshots: Logarithmic Axis Demo

customPlot->setNoAntialiasingOnDrag(true); // more performance/responsiveness during dragging

Page 36: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

customPlot->addGraph();QPenpen;pen.setColor(QColor(255,170,100));pen.setWidth(2);pen.setStyle(Qt::DotLine);customPlot->graph(0)->setPen(pen);customPlot->graph(0)->setName("x");

customPlot->addGraph();customPlot->graph(1)->setPen(QPen(Qt::red));customPlot->graph(1)->setBrush(QBrush(QColor(255, 0, 0, 20)));customPlot->graph(1)->setErrorType(QCPGraph::etBoth);customPlot->graph(1)->setName("-sin(x)exp(x)");

customPlot->addGraph();customPlot->graph(2)->setPen(QPen(Qt::blue));customPlot->graph(2)->setBrush(QBrush(QColor(0, 0, 255, 20)));customPlot->graph(2)->setName(" sin(x)exp(x)");

customPlot->addGraph();pen.setColor(QColor(0,0,0));pen.setWidth(1);pen.setStyle(Qt::DashLine);customPlot->graph(3)->setPen(pen);customPlot->graph(3)->setBrush(QBrush(QColor(0,0,0,15)));customPlot->graph(3)->setLineStyle(QCPGraph::lsStepCenter);

Page 37: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

customPlot->graph(3)->setName("x!");

QVector<double> x0(200), y0(200);QVector<double> x1(200), y1(200);QVector<double> x2(200), y2(200);QVector<double> x3(21), y3(21);for(inti=0; i<200; ++i){

x0[i] = i/10.0;y0[i] = x0[i];x1[i] = i/10.0;y1[i] = -qSin(x1[i])*qExp(x1[i]);x2[i] = i/10.0;y2[i] = qSin(x2[i])*qExp(x2[i]);

}for(inti=0; i<21; ++i){

x3[i] = i;y3[i] = 1;for(intk=1; k<=i; ++k) y3[i] *= k; // factorial

}customPlot->graph(0)->setData(x0, y0);customPlot->graph(1)->setData(x1, y1);customPlot->graph(2)->setData(x2, y2);customPlot->graph(3)->setData(x3, y3);

Page 38: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

customPlot->yAxis->grid()->setSubGridVisible(true);customPlot->xAxis->grid()->setSubGridVisible(true);customPlot->yAxis->setScaleType(QCPAxis::stLogarithmic);customPlot->yAxis->setScaleLogBase(100);customPlot->yAxis->setNumberFormat("eb"); // e = exponential, b = beautiful decimal powerscustomPlot->yAxis->setNumberPrecision(0); // makes sure "1*10^4" is displayed only as "10^4"customPlot->yAxis->setSubTickCount(10);customPlot->xAxis->setRange(0, 19.9);customPlot->yAxis->setRange(1e-2, 1e10);// make range draggable and zoomable:customPlot->setInteractions(QCP::iRangeDrag| QCP::iRangeZoom);

// make top right axes clones of bottom left axes:customPlot->axisRect()->setupFullAxesBox();// connect signals so top and right axes move in sync with bottom and left axes:connect(customPlot->xAxis, SIGNAL(rangeChanged(QCPRange)), customPlot->xAxis2, SLOT(setRange(QCPRange)));connect(customPlot->yAxis, SIGNAL(rangeChanged(QCPRange)), customPlot->yAxis2, SLOT(setRange(QCPRange)));

customPlot->legend->setVisible(true);customPlot->legend->setBrush(QBrush(QColor(255,255,255,150)));customPlot->axisRect()->insetLayout()->setInsetAlignment(0, Qt::AlignLeft|Qt::AlignTop); // make legend align in top left corner or axis rect

Page 39: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

Plot Screenshots: Line Style Demo

Page 40: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

customPlot->legend->setVisible(true);customPlot->legend->setFont(QFont("Helvetica", 9));QPenpen;QStringListlineNames;lineNames << "lsNone"<< "lsLine"<< "lsStepLeft"<< "lsStepRight"<< "lsStepCenter"<< "lsImpulse";// add graphs with different line styles:for(inti=QCPGraph::lsNone; i<=QCPGraph::lsImpulse; ++i){

customPlot->addGraph();pen.setColor(QColor(qSin(i*1+1.2)*80+80, qSin(i*0.3+0)*80+80, qSin(i*0.3+1.5)*80+80));customPlot->graph()->setPen(pen);customPlot->graph()->setName(lineNames.at(i-QCPGraph::lsNone));customPlot->graph()->setLineStyle((QCPGraph::LineStyle)i);customPlot->graph()->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, 5));// generate data:QVector<double> x(15), y(15);for(intj=0; j<15; ++j){

x[j] = j/15.0* 5*3.14+ 0.01;y[j] = 7*qSin(x[j])/x[j] - (i-QCPGraph::lsNone)*5+ (QCPGraph::lsImpulse)*5+ 2;

}customPlot->graph()->setData(x, y);customPlot->graph()->rescaleAxes(true);

}// zoom out a bit:customPlot->yAxis->scaleRange(1.1, customPlot->yAxis->range().center());

Page 41: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

customPlot->xAxis->scaleRange(1.1, customPlot->xAxis->range().center());// set blank axis lines:customPlot->xAxis->setTicks(false);customPlot->yAxis->setTicks(true);customPlot->xAxis->setTickLabels(false);customPlot->yAxis->setTickLabels(true);// make top right axes clones of bottom left axes:customPlot->axisRect()->setupFullAxesBox();

Page 42: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

Plot Screenshots: Date Axis Demo

Page 43: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

// set locale to english, so we get english month names:customPlot->setLocale(QLocale(QLocale::English, QLocale::UnitedKingdom));// seconds of current time, we'll use it as starting point in time for data:doublenow = QDateTime::currentDateTime().toTime_t();srand (8); // set the random seed, so we always get the same random data// create multiple graphs:for(intgi=0; gi<5; ++gi){

customPlot->addGraph();QPenpen;pen.setColor(QColor(0, 0, 255, 200));customPlot->graph()->setLineStyle(QCPGraph::lsLine);customPlot->graph()->setPen(pen);customPlot->graph()->setBrush(QBrush(QColor(255/4.0*gi,160,50,150)));// generate random walk data:QVector<double> time (250), value(250);for(inti=0; i<250; ++i){

time [i] = now + 24*3600*i;if(i == 0)

value[i] = (i/50.0+1)*( rand ()/(double)RAND_MAX-0.5);else

value[i] = qFabs(value[i-1])*(1+0.02/4.0*(4-gi)) + (i/50.0+1)*( rand()/(double)RAND_MAX-0.5);}customPlot->graph()->setData( time , value);

}

Page 44: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

// configure bottom axis to show date and time instead of number:customPlot->xAxis->setTickLabelType(QCPAxis::ltDateTime);customPlot->xAxis->setDateTimeFormat("MMMM\nyyyy");// set a more compact font size for bottom and left axis tick labels:customPlot->xAxis->setTickLabelFont(QFont(QFont().family(), 8));customPlot->yAxis->setTickLabelFont(QFont(QFont().family(), 8));// set a fixed tick-step to one tick per month:customPlot->xAxis->setAutoTickStep(false);customPlot->xAxis->setTickStep(2628000); // one month in secondscustomPlot->xAxis->setSubTickCount(3);// apply manual tick and tick label for left axis:customPlot->yAxis->setAutoTicks(false);customPlot->yAxis->setAutoTickLabels(false);customPlot->yAxis->setTickVector(QVector<double>() << 5<< 55);customPlot->yAxis->setTickVectorLabels(QVector<QString>() << "Not so\nhigh"<< "Very\nhigh");// set axis labels:customPlot->xAxis->setLabel("Date");customPlot->yAxis->setLabel("Random wobbly lines value");// make top and right axes visible but without ticks and labels:customPlot->xAxis2->setVisible(true);customPlot->yAxis2->setVisible(true);customPlot->xAxis2->setTicks(false);customPlot->yAxis2->setTicks(false);customPlot->xAxis2->setTickLabels(false);customPlot->yAxis2->setTickLabels(false);// set axis ranges to show all data:

Page 45: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

customPlot->xAxis->setRange(now, now+24*3600*249);customPlot->yAxis->setRange(0, 60);// show legend:customPlot->legend->setVisible(true);

Page 46: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

Plot Screenshots: Parametric Curves Demo

Page 47: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

// create empty curve objects and add them to customPlot:QCPCurve*fermatSpiral1 = newQCPCurve(customPlot->xAxis, customPlot->yAxis);QCPCurve*fermatSpiral2 = newQCPCurve(customPlot->xAxis, customPlot->yAxis);QCPCurve*deltoidRadial = newQCPCurve(customPlot->xAxis, customPlot->yAxis);customPlot->addPlottable(fermatSpiral1);customPlot->addPlottable(fermatSpiral2);customPlot->addPlottable(deltoidRadial);// generate the curve data points:intpointCount = 500;QVector<double> x1(pointCount), y1(pointCount);QVector<double> x2(pointCount), y2(pointCount);QVector<double> x3(pointCount), y3(pointCount);for(inti=0; i<pointCount; ++i){

doublephi = (i/(double)(pointCount-1))*8*M_PI;x1[i] = qSqrt(phi)*qCos(phi);y1[i] = qSqrt(phi)*qSin(phi);x2[i] = -x1[i];y2[i] = -y1[i];doublet = i/(double)(pointCount-1)*2*M_PI;x3[i] = 2*qCos(2*t)+qCos(1*t)+2*qSin(t);y3[i] = 2*qSin(2*t)-qSin(1*t);

}// pass the data to the curves:fermatSpiral1->setData(x1, y1);fermatSpiral2->setData(x2, y2);

Page 48: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

deltoidRadial->setData(x3, y3);// color the curves:fermatSpiral1->setPen(QPen(Qt::blue));fermatSpiral1->setBrush(QBrush(QColor(0, 0, 255, 20)));fermatSpiral2->setPen(QPen(QColor(255, 120, 0)));fermatSpiral2->setBrush(QBrush(QColor(255, 120, 0, 30)));QRadialGradientradialGrad(QPointF(310, 180), 200);radialGrad.setColorAt(0, QColor(170, 20, 240, 100));radialGrad.setColorAt(0.5, QColor(20, 10, 255, 40));radialGrad.setColorAt(1,QColor(120, 20, 240, 10));deltoidRadial->setPen(QPen(QColor(170, 20, 240)));deltoidRadial->setBrush(QBrush(radialGrad));// set some basic customPlot config:customPlot->setInteractions(QCP::iRangeDrag| QCP::iRangeZoom| QCP::iSelectPlottables);customPlot->axisRect()->setupFullAxesBox();customPlot->rescaleAxes();

Page 49: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

Plot Screenshots: Bar Chart Demo

Page 50: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

// create empty bar chart objects:QCPBars*regen = newQCPBars(customPlot->xAxis, customPlot->yAxis);QCPBars*nuclear = newQCPBars(customPlot->xAxis, customPlot->yAxis);QCPBars*fossil = newQCPBars(customPlot->xAxis, customPlot->yAxis);customPlot->addPlottable(regen);customPlot->addPlottable(nuclear);customPlot->addPlottable(fossil);// set names and colors:QPenpen;pen.setWidthF(1.2);fossil->setName("Fossil fuels");pen.setColor(QColor(255, 131, 0));fossil->setPen(pen);fossil->setBrush(QColor(255, 131, 0, 50));nuclear->setName("Nuclear");pen.setColor(QColor(1, 92, 191));nuclear->setPen(pen);nuclear->setBrush(QColor(1, 92, 191, 50));regen->setName("Regenerative");pen.setColor(QColor(150, 222, 0));regen->setPen(pen);regen->setBrush(QColor(150, 222, 0, 70));// stack bars ontop of each other:nuclear->moveAbove(fossil);regen->moveAbove(nuclear);

Page 51: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

// prepare x axis with country labels:QVector<double> ticks;QVector<QString> labels;ticks << 1<< 2<< 3<< 4<< 5<< 6<< 7;labels << "USA"<< "Japan"<< "Germany"<< "France"<< "UK"<< "Italy"<< "Canada";customPlot->xAxis->setAutoTicks(false);customPlot->xAxis->setAutoTickLabels(false);customPlot->xAxis->setTickVector(ticks);customPlot->xAxis->setTickVectorLabels(labels);customPlot->xAxis->setTickLabelRotation(60);customPlot->xAxis->setSubTickCount(0);customPlot->xAxis->setTickLength(0, 4);customPlot->xAxis->grid()->setVisible(true);customPlot->xAxis->setRange(0, 8);

// prepare y axis:customPlot->yAxis->setRange(0, 12.1);customPlot->yAxis->setPadding(5); // a bit more space to the left bordercustomPlot->yAxis->setLabel("Power Consumption in\nKilowatts per Capita (2007)");customPlot->yAxis->grid()->setSubGridVisible(true);QPengridPen;gridPen.setStyle(Qt::SolidLine);gridPen.setColor(QColor(0, 0, 0, 25));customPlot->yAxis->grid()->setPen(gridPen);gridPen.setStyle(Qt::DotLine);customPlot->yAxis->grid()->setSubGridPen(gridPen);

Page 52: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

// Add data:QVector<double> fossilData, nuclearData, regenData;fossilData << 0.86*10.5<< 0.83*5.5<< 0.84*5.5<< 0.52*5.8<< 0.89*5.2<< 0.90*4.2<< 0.67*11.2;nuclearData << 0.08*10.5<< 0.12*5.5<< 0.12*5.5<< 0.40*5.8<< 0.09*5.2<< 0.00*4.2<< 0.07*11.2;regenData << 0.06*10.5<< 0.05*5.5<< 0.04*5.5<< 0.06*5.8<< 0.02*5.2<< 0.07*4.2<< 0.25*11.2;fossil->setData(ticks, fossilData);nuclear->setData(ticks, nuclearData);regen->setData(ticks, regenData);

// setup legend:customPlot->legend->setVisible(true);customPlot->axisRect()->insetLayout()->setInsetAlignment(0, Qt::AlignTop|Qt::AlignHCenter);customPlot->legend->setBrush(QColor(255, 255, 255, 200));QPenlegendPen;legendPen.setColor(QColor(130, 130, 130, 200));customPlot->legend->setBorderPen(legendPen);QFontlegendFont = font();legendFont.setPointSize(10);customPlot->legend->setFont(legendFont);customPlot->setInteractions(QCP::iRangeDrag| QCP::iRangeZoom);

Page 53: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

Plot Screenshots: Statistical Box Demo

Page 54: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

// create empty statistical box plottables:QCPStatisticalBox*sample1 = newQCPStatisticalBox(customPlot->xAxis, customPlot->yAxis);QCPStatisticalBox*sample2 = newQCPStatisticalBox(customPlot->xAxis, customPlot->yAxis);QCPStatisticalBox*sample3 = newQCPStatisticalBox(customPlot->xAxis, customPlot->yAxis);customPlot->addPlottable(sample1);customPlot->addPlottable(sample2);customPlot->addPlottable(sample3);QBrushboxBrush(QColor(60, 60, 255, 100));boxBrush.setStyle(Qt::Dense6Pattern); // make it look oldschoolsample1->setBrush(boxBrush);sample2->setBrush(boxBrush);sample3->setBrush(boxBrush);

// set data:sample1->setKey(1);sample1->setMinimum(1.1);sample1->setLowerQuartile(1.9);sample1->setMedian(2.25);sample1->setUpperQuartile(2.7);sample1->setMaximum(4.2);

sample2->setKey(2);sample2->setMinimum(0.8);sample2->setLowerQuartile(1.6);sample2->setMedian(2.2);sample2->setUpperQuartile(3.2);

Page 55: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

sample2->setMaximum(4.9);sample2->setOutliers(QVector<double>() << 0.7<< 0.39<< 0.45<< 6.2<< 5.84);

sample3->setKey(3);sample3->setMinimum(0.2);sample3->setLowerQuartile(0.7);sample3->setMedian(1.1);sample3->setUpperQuartile(1.6);sample3->setMaximum(2.9);

// prepare manual x axis labels:customPlot->xAxis->setSubTickCount(0);customPlot->xAxis->setTickLength(0, 4);customPlot->xAxis->setTickLabelRotation(20);customPlot->xAxis->setAutoTicks(false);customPlot->xAxis->setAutoTickLabels(false);customPlot->xAxis->setTickVector(QVector<double>() << 1<< 2<< 3);customPlot->xAxis->setTickVectorLabels(QVector<QString>() << "Sample 1"<< "Sample 2"<< "Control Group");

// prepare axes:customPlot->yAxis->setLabel(QString::fromUtf8("O ? Absorption [mg]"));customPlot->rescaleAxes();customPlot->xAxis->scaleRange(1.7, customPlot->xAxis->range().center());customPlot->yAxis->setRange(0, 7);customPlot->setInteractions(QCP::iRangeDrag| QCP::iRangeZoom);

Page 56: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

Interaction Example

Page 57: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):
Page 58: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

#include "mainwindow.h"#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget*parent) :QMainWindow(parent),ui(newUi::MainWindow)

{srand (QDateTime::currentDateTime().toTime_t());ui->setupUi(this);

ui->customPlot->setInteractions(QCP::iRangeDrag| QCP::iRangeZoom| QCP::iSelectAxes|QCP::iSelectLegend| QCP::iSelectPlottables);

ui->customPlot->xAxis->setRange(-8, 8);ui->customPlot->yAxis->setRange(-5, 5);ui->customPlot->axisRect()->setupFullAxesBox();

ui->customPlot->plotLayout()->insertRow(0);ui->customPlot->plotLayout()->addElement(0, 0, newQCPPlotTitle(ui->customPlot, "Interaction Example"));

ui->customPlot->xAxis->setLabel("x Axis");ui->customPlot->yAxis->setLabel("y Axis");ui->customPlot->legend->setVisible(true);QFontlegendFont = font();legendFont.setPointSize(10);ui->customPlot->legend->setFont(legendFont);ui->customPlot->legend->setSelectedFont(legendFont);

Page 59: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

ui->customPlot->legend->setSelectableParts(QCPLegend::spItems); // legend box shall not be selectable, only legend items

addRandomGraph();addRandomGraph();addRandomGraph();addRandomGraph();

// connect slot that ties some axis selections together (especially opposite axes):connect(ui->customPlot, SIGNAL(selectionChangedByUser()), this, SLOT(selectionChanged()));// connect slots that takes care that when an axis is selected, only that direction can be dragged and zoomed:connect(ui->customPlot, SIGNAL(mousePress(QMouseEvent*)), this, SLOT(mousePress()));connect(ui->customPlot, SIGNAL(mouseWheel(QWheelEvent*)), this, SLOT(mouseWheel()));

// make bottom and left axes transfer their ranges to top and right axes:connect(ui->customPlot->xAxis, SIGNAL(rangeChanged(QCPRange)), ui->customPlot->xAxis2, SLOT(setRange(QCPRange)));connect(ui->customPlot->yAxis, SIGNAL(rangeChanged(QCPRange)), ui->customPlot->yAxis2, SLOT(setRange(QCPRange)));

// connect some interaction slots:connect(ui->customPlot, SIGNAL(titleDoubleClick(QMouseEvent*,QCPPlotTitle*)), this,

SLOT(titleDoubleClick(QMouseEvent*,QCPPlotTitle*)));connect(ui->customPlot, SIGNAL(axisDoubleClick(QCPAxis*,QCPAxis::SelectablePart,QMouseEvent*)), this,

SLOT(axisLabelDoubleClick(QCPAxis*,QCPAxis::SelectablePart)));connect(ui->customPlot, SIGNAL(legendDoubleClick(QCPLegend*,QCPAbstractLegendItem*,QMouseEvent*)), this,

SLOT(legendDoubleClick(QCPLegend*,QCPAbstractLegendItem*)));

Page 60: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

// connect slot that shows a message in the status bar when a graph is clicked:connect(ui->customPlot, SIGNAL(plottableClick(QCPAbstractPlottable*,QMouseEvent*)), this,

SLOT(graphClicked(QCPAbstractPlottable*)));

// setup policy and connect slot for context menu popup:ui->customPlot->setContextMenuPolicy(Qt::CustomContextMenu);connect(ui->customPlot, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuRequest(QPoint)));

}

MainWindow::~MainWindow(){

deleteui;}

voidMainWindow::titleDoubleClick(QMouseEvent* event, QCPPlotTitle* title){

Q_UNUSED(event)// Set the plot title by double clicking on itboolok;QStringnewTitle = QInputDialog::getText(this, "QCustomPlot example", "New plot title:", QLineEdit::Normal,

title->text(), &ok);if(ok){

title->setText(newTitle);ui->customPlot->replot();

}

Page 61: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

}

voidMainWindow::axisLabelDoubleClick(QCPAxis*axis, QCPAxis::SelectablePartpart){

// Set an axis label by double clicking on itif(part == QCPAxis::spAxisLabel) // only react when the actual axis label is clicked, not tick label or axis backbone{

boolok;QStringnewLabel = QInputDialog::getText(this, "QCustomPlot example", "New axis label:", QLineEdit::Normal,

axis->label(), &ok);if(ok){

axis->setLabel(newLabel);ui->customPlot->replot();

}}

}

voidMainWindow::legendDoubleClick(QCPLegend*legend, QCPAbstractLegendItem*item){

// Rename a graph by double clicking on its legend itemQ_UNUSED(legend)if(item) // only react if item was clicked (user could have clicked on border padding of legend where there is no

item, then item is 0){

QCPPlottableLegendItem*plItem = qobject_cast<QCPPlottableLegendItem*>(item);

Page 62: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

boolok;QStringnewName = QInputDialog::getText(this, "QCustomPlot example", "New graph name:", QLineEdit::Normal,

plItem->plottable()->name(), &ok);if(ok){

plItem->plottable()->setName(newName);ui->customPlot->replot();

}}

}

voidMainWindow::selectionChanged(){

/*normally, axis base line, axis tick labels and axis labels are selectable separately, but we wantthe user only to be able to select the axis as a whole, so we tie the selected states of the tick labelsand the axis base line together. However, the axis label shall be selectable individually.

The selection state of the left and right axes shall be synchronized as well as the state of thebottom and top axes.

Further, we want to synchronize the selection of the graphs with the selection state of the respectivelegend item belonging to that graph. So the user can select a graph by either clicking on the graph itselfor on its legend item.

*/

Page 63: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

// make top and bottom axes be selected synchronously, and handle axis and tick labels as one selectable object:if(ui->customPlot->xAxis->selectedParts().testFlag(QCPAxis::spAxis) ||

ui->customPlot->xAxis->selectedParts().testFlag(QCPAxis::spTickLabels) ||ui->customPlot->xAxis2->selectedParts().testFlag(QCPAxis::spAxis) ||

ui->customPlot->xAxis2->selectedParts().testFlag(QCPAxis::spTickLabels)){

ui->customPlot->xAxis2->setSelectedParts(QCPAxis::spAxis|QCPAxis::spTickLabels);ui->customPlot->xAxis->setSelectedParts(QCPAxis::spAxis|QCPAxis::spTickLabels);

}// make left and right axes be selected synchronously, and handle axis and tick labels as one selectable object:if(ui->customPlot->yAxis->selectedParts().testFlag(QCPAxis::spAxis) ||

ui->customPlot->yAxis->selectedParts().testFlag(QCPAxis::spTickLabels) ||ui->customPlot->yAxis2->selectedParts().testFlag(QCPAxis::spAxis) ||

ui->customPlot->yAxis2->selectedParts().testFlag(QCPAxis::spTickLabels)){

ui->customPlot->yAxis2->setSelectedParts(QCPAxis::spAxis|QCPAxis::spTickLabels);ui->customPlot->yAxis->setSelectedParts(QCPAxis::spAxis|QCPAxis::spTickLabels);

}

// synchronize selection of graphs with selection of corresponding legend items:for(inti=0; i<ui->customPlot->graphCount(); ++i){

QCPGraph*graph = ui->customPlot->graph(i);QCPPlottableLegendItem*item = ui->customPlot->legend->itemWithPlottable(graph);if(item->selected() || graph->selected()){

Page 64: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

item->setSelected(true);graph->setSelected(true);

}}

}

voidMainWindow::mousePress(){

// if an axis is selected, only allow the direction of that axis to be dragged// if no axis is selected, both directions may be dragged

if(ui->customPlot->xAxis->selectedParts().testFlag(QCPAxis::spAxis))ui->customPlot->axisRect()->setRangeDrag(ui->customPlot->xAxis->orientation());

elseif(ui->customPlot->yAxis->selectedParts().testFlag(QCPAxis::spAxis))ui->customPlot->axisRect()->setRangeDrag(ui->customPlot->yAxis->orientation());

elseui->customPlot->axisRect()->setRangeDrag(Qt::Horizontal|Qt::Vertical);

}

voidMainWindow::mouseWheel(){

// if an axis is selected, only allow the direction of that axis to be zoomed// if no axis is selected, both directions may be zoomed

if(ui->customPlot->xAxis->selectedParts().testFlag(QCPAxis::spAxis))ui->customPlot->axisRect()->setRangeZoom(ui->customPlot->xAxis->orientation());

Page 65: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

elseif(ui->customPlot->yAxis->selectedParts().testFlag(QCPAxis::spAxis))ui->customPlot->axisRect()->setRangeZoom(ui->customPlot->yAxis->orientation());

elseui->customPlot->axisRect()->setRangeZoom(Qt::Horizontal|Qt::Vertical);

}

voidMainWindow::addRandomGraph(){

intn = 50; // number of points in graphdoublexScale = ( rand ()/(double)RAND_MAX + 0.5)*2;doubleyScale = ( rand ()/(double)RAND_MAX + 0.5)*2;doublexOffset = ( rand ()/(double)RAND_MAX - 0.5)*4;doubleyOffset = ( rand ()/(double)RAND_MAX - 0.5)*5;doubler1 = ( rand()/(double)RAND_MAX - 0.5)*2;doubler2 = ( rand()/(double)RAND_MAX - 0.5)*2;doubler3 = ( rand()/(double)RAND_MAX - 0.5)*2;doubler4 = ( rand()/(double)RAND_MAX - 0.5)*2;QVector<double> x(n), y(n);for(inti=0; i<n; i++){

x[i] = (i/(double)n-0.5)*10.0*xScale + xOffset;y[i] = (qSin(x[i]*r1*5)*qSin(qCos(x[i]*r2)*r4*3)+r3*qCos(qSin(x[i])*r4*2))*yScale + yOffset;

}

ui->customPlot->addGraph();ui->customPlot->graph()->setName(QString("New graph %1").arg(ui->customPlot->graphCount()-1));

Page 66: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

ui->customPlot->graph()->setData(x, y);ui->customPlot->graph()->setLineStyle((QCPGraph::LineStyle)( rand ()%5+1));if( rand ()%100> 75)

ui->customPlot->graph()->setScatterStyle(QCPScatterStyle((QCPScatterStyle::ScatterShape)( rand ()%9+1)));QPengraphPen;graphPen.setColor(QColor( rand ()%245+10, rand ()%245+10, rand ()%245+10));graphPen.setWidthF( rand ()/(double)RAND_MAX*2+1);ui->customPlot->graph()->setPen(graphPen);ui->customPlot->replot();

}

voidMainWindow::removeSelectedGraph(){

if(ui->customPlot->selectedGraphs().size() > 0){

ui->customPlot->removeGraph(ui->customPlot->selectedGraphs().first());ui->customPlot->replot();

}}

voidMainWindow::removeAllGraphs(){

ui->customPlot->clearGraphs();ui->customPlot->replot();

}

Page 67: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

voidMainWindow::contextMenuRequest(QPointpos){

QMenu*menu = newQMenu(this);menu->setAttribute(Qt::WA_DeleteOnClose);

if(ui->customPlot->legend->selectTest(pos, false) >= 0) // context menu on legend requested{

menu->addAction("Move to top left", this, SLOT(moveLegend()))->setData((int)(Qt::AlignTop|Qt::AlignLeft));menu->addAction("Move to top center", this,

SLOT(moveLegend()))->setData((int)(Qt::AlignTop|Qt::AlignHCenter));menu->addAction("Move to top right", this, SLOT(moveLegend()))->setData((int)(Qt::AlignTop|Qt::AlignRight));menu->addAction("Move to bottom right", this,

SLOT(moveLegend()))->setData((int)(Qt::AlignBottom|Qt::AlignRight));menu->addAction("Move to bottom left", this,

SLOT(moveLegend()))->setData((int)(Qt::AlignBottom|Qt::AlignLeft));} else // general context menu on graphs requested{

menu->addAction("Add random graph", this, SLOT(addRandomGraph()));if(ui->customPlot->selectedGraphs().size() > 0)

menu->addAction("Remove selected graph", this, SLOT(removeSelectedGraph()));if(ui->customPlot->graphCount() > 0)

menu->addAction("Remove all graphs", this, SLOT(removeAllGraphs()));}

menu->popup(ui->customPlot->mapToGlobal(pos));}

Page 68: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

voidMainWindow::moveLegend(){

if(QAction* contextAction = qobject_cast<QAction*>(sender())) // make sure this slot is really called by a context menu action, so it carries the data we need

{boolok;intdataInt = contextAction->data().toInt(&ok);if(ok){

ui->customPlot->axisRect()->insetLayout()->setInsetAlignment(0, (Qt::Alignment)dataInt);ui->customPlot->replot();

}}

}

voidMainWindow::graphClicked(QCPAbstractPlottable*plottable){

ui->statusBar->showMessage(QString("Clicked on graph '%1'.").arg(plottable->name()), 1000);}

Plot Screenshots: Item Demo

Page 69: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):
Page 70: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

Setup function: customPlot->setInteractions(QCP::iRangeDrag| QCP::iRangeZoom);QCPGraph*graph = customPlot->addGraph();intn = 500;doublephase = 0;doublek = 3;QVector<double> x(n), y(n);for(inti=0; i<n; ++i){

x[i] = i/(double)(n-1)*34- 17;y[i] = qExp(-x[i]*x[i]/20.0)*qSin(k*x[i]+phase);

}graph->setData(x, y);graph->setPen(QPen(Qt::blue));graph->rescaleKeyAxis();customPlot->yAxis->setRange(-1.45, 1.65);customPlot->xAxis->grid()->setZeroLinePen(Qt::NoPen);

// add the bracket at the top:QCPItemBracket*bracket = newQCPItemBracket(customPlot);customPlot->addItem(bracket);bracket->left->setCoords(-8, 1.1);bracket->right->setCoords(8, 1.1);bracket->setLength(13);

Page 71: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

// add the text label at the top:QCPItemText*wavePacketText = newQCPItemText(customPlot);customPlot->addItem(wavePacketText);wavePacketText->position->setParentAnchor(bracket->center);wavePacketText->position->setCoords(0, -10); // move 10 pixels to the top from bracket center anchorwavePacketText->setPositionAlignment(Qt::AlignBottom|Qt::AlignHCenter);wavePacketText->setText("Wavepacket");wavePacketText->setFont(QFont(font().family(), 10));

// add the phase tracer (red circle) which sticks to the graph data (and gets updated in bracketDataSlot by timer event):QCPItemTracer*phaseTracer = newQCPItemTracer(customPlot);customPlot->addItem(phaseTracer);itemDemoPhaseTracer = phaseTracer; // so we can access it later in the bracketDataSlot for animationphaseTracer->setGraph(graph);phaseTracer->setGraphKey((M_PI*1.5-phase)/k);phaseTracer->setInterpolating(true);phaseTracer->setStyle(QCPItemTracer::tsCircle);phaseTracer->setPen(QPen(Qt::red));phaseTracer->setBrush(Qt::red);phaseTracer->setSize(7);

// add label for phase tracer:QCPItemText*phaseTracerText = newQCPItemText(customPlot);customPlot->addItem(phaseTracerText);phaseTracerText->position->setType(QCPItemPosition::ptAxisRectRatio);phaseTracerText->setPositionAlignment(Qt::AlignRight|Qt::AlignBottom);

Page 72: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

phaseTracerText->position->setCoords(1.0, 0.95); // lower right corner of axis rectphaseTracerText->setText("Points of fixed\nphase define\nphase velocity vp");phaseTracerText->setTextAlignment(Qt::AlignLeft);phaseTracerText->setFont(QFont(font().family(), 9));phaseTracerText->setPadding(QMargins(8, 0, 0, 0));

// add arrow pointing at phase tracer, coming from label:QCPItemCurve*phaseTracerArrow = newQCPItemCurve(customPlot);customPlot->addItem(phaseTracerArrow);phaseTracerArrow->start->setParentAnchor(phaseTracerText->left);phaseTracerArrow->startDir->setParentAnchor(phaseTracerArrow->start);phaseTracerArrow->startDir->setCoords(-40, 0); // direction 30 pixels to the left of parent anchor (tracerArrow->start)phaseTracerArrow->end->setParentAnchor(phaseTracer->position);phaseTracerArrow->end->setCoords(10, 10);phaseTracerArrow->endDir->setParentAnchor(phaseTracerArrow->end);phaseTracerArrow->endDir->setCoords(30, 30);phaseTracerArrow->setHead(QCPLineEnding::esSpikeArrow);phaseTracerArrow->setTail(QCPLineEnding(QCPLineEnding::esBar, (phaseTracerText->bottom->pixelPoint().y()-phaseTracerText->top->pixelPoint().y())*0.85));

// add the group velocity tracer (green circle):QCPItemTracer*groupTracer = newQCPItemTracer(customPlot);customPlot->addItem(groupTracer);groupTracer->setGraph(graph);groupTracer->setGraphKey(5.5);groupTracer->setInterpolating(true);

Page 73: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

groupTracer->setStyle(QCPItemTracer::tsCircle);groupTracer->setPen(QPen(Qt::green));groupTracer->setBrush(Qt::green);groupTracer->setSize(7);

// add label for group tracer:QCPItemText*groupTracerText = newQCPItemText(customPlot);customPlot->addItem(groupTracerText);groupTracerText->position->setType(QCPItemPosition::ptAxisRectRatio);groupTracerText->setPositionAlignment(Qt::AlignRight|Qt::AlignTop);groupTracerText->position->setCoords(1.0, 0.20); // lower right corner of axis rectgroupTracerText->setText("Fixed positions in\nwave packet define\ngroup velocity vg");groupTracerText->setTextAlignment(Qt::AlignLeft);groupTracerText->setFont(QFont(font().family(), 9));groupTracerText->setPadding(QMargins(8, 0, 0, 0));

// add arrow pointing at group tracer, coming from label:QCPItemCurve*groupTracerArrow = newQCPItemCurve(customPlot);customPlot->addItem(groupTracerArrow);groupTracerArrow->start->setParentAnchor(groupTracerText->left);groupTracerArrow->startDir->setParentAnchor(groupTracerArrow->start);groupTracerArrow->startDir->setCoords(-40, 0); // direction 30 pixels to the left of parent anchor (tracerArrow->start)groupTracerArrow->end->setCoords(5.5, 0.4);groupTracerArrow->endDir->setParentAnchor(groupTracerArrow->end);groupTracerArrow->endDir->setCoords(0, -40);groupTracerArrow->setHead(QCPLineEnding::esSpikeArrow);

Page 74: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

groupTracerArrow->setTail(QCPLineEnding(QCPLineEnding::esBar, (groupTracerText->bottom->pixelPoint().y()-groupTracerText->top->pixelPoint().y())*0.85));

// add dispersion arrow:QCPItemCurve*arrow = newQCPItemCurve(customPlot);customPlot->addItem(arrow);arrow->start->setCoords(1, -1.1);arrow->startDir->setCoords(-1, -1.3);arrow->endDir->setCoords(-5, -0.3);arrow->end->setCoords(-10, -0.2);arrow->setHead(QCPLineEnding::esSpikeArrow);

// add the dispersion arrow label:QCPItemText*dispersionText = newQCPItemText(customPlot);customPlot->addItem(dispersionText);dispersionText->position->setCoords(-6, -0.9);dispersionText->setRotation(40);dispersionText->setText("Dispersion with\nvp < vg");dispersionText->setFont(QFont(font().family(), 10));

// setup a timer that repeatedly calls MainWindow::bracketDataSlot:connect(&dataTimer, SIGNAL(timeout()), this, SLOT(bracketDataSlot()));dataTimer.start(0); // Interval 0 means to refresh as fast as possible

Page 75: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

bracketDataSlot , called by timer: doublesecs = QDateTime::currentDateTime().toMSecsSinceEpoch()/1000.0;// update data to make phase move:intn = 500;doublephase = secs*5;doublek = 3;QVector<double> x(n), y(n);for(inti=0; i<n; ++i){

x[i] = i/(double)(n-1)*34- 17;y[i] = qExp(-x[i]*x[i]/20.0)*qSin(k*x[i]+phase);

}ui->customPlot->graph()->setData(x, y);

itemDemoPhaseTracer->setGraphKey((8*M_PI+ fmod(M_PI*1.5-phase, 6*M_PI))/k);

ui->customPlot->replot();

// calculate frames per second:doublekey = secs;staticdoublelastFpsKey;staticintframeCount;++frameCount;if(key-lastFpsKey > 2) // average fps over 2 seconds{

Page 76: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

ui->statusBar->showMessage(QString("%1 FPS, Total Data points: %2").arg(frameCount/(key-lastFpsKey), 0, 'f', 0).arg(ui->customPlot->graph(0)->data()->count()), 0);

lastFpsKey = key;frameCount = 0;

}

Page 77: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

Plot Screenshots: Advanced Axes Demo

Page 78: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

// configure axis rect:customPlot->plotLayout()->clear(); // clear default axis rect so we can start from scratchQCPAxisRect*wideAxisRect = newQCPAxisRect(customPlot);wideAxisRect->setupFullAxesBox(true);wideAxisRect->axis(QCPAxis::atRight, 0)->setTickLabels(true);wideAxisRect->addAxis(QCPAxis::atLeft)->setTickLabelColor(QColor("#6050F8")); // add an extra axis on the left and color its numbersQCPLayoutGrid*subLayout = newQCPLayoutGrid;customPlot->plotLayout()->addElement(0, 0, wideAxisRect); // insert axis rect in first rowcustomPlot->plotLayout()->addElement(1, 0, subLayout); // sub layout in second row (grid layout will grow accordingly)//customPlot->plotLayout()->setRowStretchFactor(1, 2);// prepare axis rects that will be placed in the sublayout:QCPAxisRect*subRectLeft = newQCPAxisRect(customPlot, false); // false means to not setup default axesQCPAxisRect*subRectRight = newQCPAxisRect(customPlot, false);subLayout->addElement(0, 0, subRectLeft);subLayout->addElement(0, 1, subRectRight);subRectRight->setMaximumSize(150, 150); // make bottom right axis rect size fixed 150x150subRectRight->setMinimumSize(150, 150); // make bottom right axis rect size fixed 150x150// setup axes in sub layout axis rects:subRectLeft->addAxes(QCPAxis::atBottom| QCPAxis::atLeft);subRectRight->addAxes(QCPAxis::atBottom| QCPAxis::atRight);subRectLeft->axis(QCPAxis::atLeft)->setAutoTickCount(2);subRectRight->axis(QCPAxis::atRight)->setAutoTickCount(2);subRectRight->axis(QCPAxis::atBottom)->setAutoTickCount(2);subRectLeft->axis(QCPAxis::atBottom)->grid()->setVisible(true);// synchronize the left and right margins of the top and bottom axis rects:

Page 79: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

QCPMarginGroup*marginGroup = newQCPMarginGroup(customPlot);subRectLeft->setMarginGroup(QCP::msLeft, marginGroup);subRectRight->setMarginGroup(QCP::msRight, marginGroup);wideAxisRect->setMarginGroup(QCP::msLeft| QCP::msRight, marginGroup);// move newly created axes on "axes" layer and grids on "grid" layer:foreach(QCPAxisRect*rect, customPlot->axisRects()){

foreach(QCPAxis*axis, rect->axes()){

axis->setLayer("axes");axis->grid()->setLayer("grid");

}}

// prepare data:QVector<double> x1a(20), y1a(20);QVector<double> x1b(50), y1b(50);QVector<double> x2(100), y2(100);QVector<double> x3, y3;qsrand(3);for(inti=0; i<x1a.size(); ++i){

x1a[i] = i/(double)(x1a.size()-1)*10-5.0;y1a[i] = qCos(x1a[i]);

}for(inti=0; i<x1b.size(); ++i)

Page 80: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

{x1b[i] = i/(double)x1b.size()*10-5.0;y1b[i] = qExp(-x1b[i]*x1b[i]*0.2)*1000;

}for(inti=0; i<x2.size(); ++i){

x2[i] = i/(double)x2.size()*10;y2[i] = qrand()/(double)RAND_MAX-0.5+y2[qAbs(i-1)];

}x3 << 1<< 2<< 3<< 4;y3 << 2<< 2.5<< 4<< 1.5;

// create and configure plottables:QCPGraph*mainGraph1 = customPlot->addGraph(wideAxisRect->axis(QCPAxis::atBottom), wideAxisRect->axis(QCPAxis::atLeft));mainGraph1->setData(x1a, y1a);mainGraph1->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, QPen(Qt::black), QBrush(Qt::white), 6));mainGraph1->setPen(QPen(QColor(120, 120, 120), 2));QCPGraph*mainGraph2 = customPlot->addGraph(wideAxisRect->axis(QCPAxis::atBottom), wideAxisRect->axis(QCPAxis::atLeft, 1));mainGraph2->setData(x1b, y1b);mainGraph2->setPen(QPen(QColor("#8070B8"), 2));mainGraph2->setBrush(QColor(110, 170, 110, 30));mainGraph1->setChannelFillGraph(mainGraph2);mainGraph1->setBrush(QColor(255, 161, 0, 50));

Page 81: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

QCPGraph*graph2 = customPlot->addGraph(subRectLeft->axis(QCPAxis::atBottom), subRectLeft->axis(QCPAxis::atLeft));graph2->setData(x2, y2);graph2->setLineStyle(QCPGraph::lsImpulse);graph2->setPen(QPen(QColor("#FFA100"), 1.5));

QCPBars*bars1 = newQCPBars(subRectRight->axis(QCPAxis::atBottom), subRectRight->axis(QCPAxis::atRight));customPlot->addPlottable(bars1);bars1->setWidth(3/(double)x3.size());bars1->setData(x3, y3);bars1->setPen(QPen(Qt::black));bars1->setAntialiased(false);bars1->setAntialiasedFill(false);bars1->setBrush(QColor("#705BE8"));bars1->keyAxis()->setAutoTicks(false);bars1->keyAxis()->setTickVector(x3);bars1->keyAxis()->setSubTickCount(0);

// rescale axes according to graph's data:mainGraph1->rescaleAxes();mainGraph2->rescaleAxes();graph2->rescaleAxes();bars1->rescaleAxes();wideAxisRect->axis(QCPAxis::atLeft, 1)->setRangeLower(0);

Page 82: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

Plot Screenshots: Financial Chart Demo

Page 83: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

customPlot->legend->setVisible(true);

// generate two sets of random walk data (one for candlestick and one for ohlc chart):intn = 500;QVector<double> time (n), value1(n), value2(n);QDateTimestart = QDateTime(QDate(2014, 6, 11));start.setTimeSpec(Qt::UTC);doublestartTime = start.toTime_t();doublebinSize = 3600*24; // bin data in 1 day intervalstime [0] = startTime;value1[0] = 60;value2[0] = 20;qsrand(9);for(inti=1; i<n; ++i){

time [i] = startTime + 3600*i;value1[i] = value1[i-1] + (qrand()/(double)RAND_MAX-0.5)*10;value2[i] = value2[i-1] + (qrand()/(double)RAND_MAX-0.5)*3;

}

// create candlestick chart:QCPFinancial*candlesticks = newQCPFinancial(customPlot->xAxis, customPlot->yAxis);

Page 84: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

customPlot->addPlottable(candlesticks);QCPFinancialDataMapdata1 = QCPFinancial::timeSeriesToOhlc( time , value1, binSize, startTime);candlesticks->setName("Candlestick");candlesticks->setChartStyle(QCPFinancial::csCandlestick);candlesticks->setData(&data1, true);candlesticks->setWidth(binSize*0.9);candlesticks->setTwoColored(true);candlesticks->setBrushPositive(QColor(245, 245, 245));candlesticks->setBrushNegative(QColor(0, 0, 0));candlesticks->setPenPositive(QPen(QColor(0, 0, 0)));candlesticks->setPenNegative(QPen(QColor(0, 0, 0)));

// create ohlc chart:QCPFinancial*ohlc = newQCPFinancial(customPlot->xAxis, customPlot->yAxis);customPlot->addPlottable(ohlc);QCPFinancialDataMapdata2 = QCPFinancial::timeSeriesToOhlc( time , value2, binSize/3.0, startTime); // divide binSize by 3 just to make the ohlc bars a bit denserohlc->setName("OHLC");ohlc->setChartStyle(QCPFinancial::csOhlc);ohlc->setData(&data2, true);ohlc->setWidth(binSize*0.2);ohlc->setTwoColored(true);

// create bottom axis rect for volume bar chart:QCPAxisRect*volumeAxisRect = newQCPAxisRect(customPlot);customPlot->plotLayout()->addElement(1, 0, volumeAxisRect);

Page 85: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

volumeAxisRect->setMaximumSize(QSize(QWIDGETSIZE_MAX, 100));volumeAxisRect->axis(QCPAxis::atBottom)->setLayer("axes");volumeAxisRect->axis(QCPAxis::atBottom)->grid()->setLayer("grid");// bring bottom and main axis rect closer together:customPlot->plotLayout()->setRowSpacing(0);volumeAxisRect->setAutoMargins(QCP::msLeft|QCP::msRight|QCP::msBottom);volumeAxisRect->setMargins(QMargins(0, 0, 0, 0));// create two bar plottables, for positive (green) and negative (red) volume bars:QCPBars*volumePos = newQCPBars(volumeAxisRect->axis(QCPAxis::atBottom), volumeAxisRect->axis(QCPAxis::atLeft));QCPBars*volumeNeg = newQCPBars(volumeAxisRect->axis(QCPAxis::atBottom), volumeAxisRect->axis(QCPAxis::atLeft));for(inti=0; i<n/5; ++i){

intv = qrand()%20000+qrand()%20000+qrand()%20000-10000*3;(v < 0? volumeNeg : volumePos)->addData(startTime+3600*5.0*i, qAbs(v)); // add data to either volumeNeg or volumePos,

depending on sign of v}customPlot->setAutoAddPlottableToLegend(false);customPlot->addPlottable(volumePos);customPlot->addPlottable(volumeNeg);volumePos->setWidth(3600*4);volumePos->setPen(Qt::NoPen);volumePos->setBrush(QColor(100, 180, 110));volumeNeg->setWidth(3600*4);volumeNeg->setPen(Qt::NoPen);volumeNeg->setBrush(QColor(180, 90, 90));

Page 86: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):

// interconnect x axis ranges of main and bottom axis rects:connect(customPlot->xAxis, SIGNAL(rangeChanged(QCPRange)), volumeAxisRect->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange)));connect(volumeAxisRect->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), customPlot->xAxis, SLOT(setRange(QCPRange)));// configure axes of both main and bottom axis rect:volumeAxisRect->axis(QCPAxis::atBottom)->setAutoTickStep(false);volumeAxisRect->axis(QCPAxis::atBottom)->setTickStep(3600*24*4); // 4 day tickstepvolumeAxisRect->axis(QCPAxis::atBottom)->setTickLabelType(QCPAxis::ltDateTime);volumeAxisRect->axis(QCPAxis::atBottom)->setDateTimeSpec(Qt::UTC);volumeAxisRect->axis(QCPAxis::atBottom)->setDateTimeFormat("dd. MMM");volumeAxisRect->axis(QCPAxis::atBottom)->setTickLabelRotation(15);volumeAxisRect->axis(QCPAxis::atLeft)->setAutoTickCount(3);customPlot->xAxis->setBasePen(Qt::NoPen);customPlot->xAxis->setTickLabels(false);customPlot->xAxis->setTicks(false); // only want vertical grid in main axis rect, so hide xAxis backbone, ticks, and labelscustomPlot->xAxis->setAutoTickStep(false);customPlot->xAxis->setTickStep(3600*24*4); // 4 day tickstepcustomPlot->rescaleAxes();customPlot->xAxis->scaleRange(1.025, customPlot->xAxis->range().center());customPlot->yAxis->scaleRange(1.1, customPlot->yAxis->range().center());

// make axis rects' left side line up:QCPMarginGroup*group = newQCPMarginGroup(customPlot);customPlot->axisRect()->setMarginGroup(QCP::msLeft|QCP::msRight, group);volumeAxisRect->setMarginGroup(QCP::msLeft|QCP::msRight, group);

Page 87: Plot Screenshots: Simple Demo · customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph // generate some points of data (y0 for first, y1 for second graph):