2019-06-21 04:24:47 +08:00
|
|
|
/** \example boxplot.cpp
|
2019-01-20 23:15:10 +08:00
|
|
|
* Shows how to draw Boxplots with JKQTPlotter
|
|
|
|
*
|
|
|
|
* \ref JKQTPlotterBoxplotsGraphs
|
|
|
|
*/
|
2019-05-06 01:31:20 +08:00
|
|
|
|
2022-08-27 04:32:48 +08:00
|
|
|
#include "jkqtpexampleapplication.h"
|
2019-01-20 23:15:10 +08:00
|
|
|
#include <QApplication>
|
|
|
|
#include "jkqtplotter/jkqtplotter.h"
|
2019-06-20 22:06:31 +08:00
|
|
|
#include "jkqtplotter/graphs/jkqtpscatter.h"
|
|
|
|
#include "jkqtplotter/graphs/jkqtpboxplot.h"
|
2019-01-20 23:15:10 +08:00
|
|
|
|
|
|
|
int main(int argc, char* argv[])
|
|
|
|
{
|
2022-04-16 05:01:09 +08:00
|
|
|
|
2022-08-27 04:32:48 +08:00
|
|
|
JKQTPAppSettingController highDPIController(argc, argv);
|
|
|
|
JKQTPExampleApplication app(argc, argv);
|
2019-01-20 23:15:10 +08:00
|
|
|
|
2022-04-16 05:01:09 +08:00
|
|
|
|
2019-01-20 23:15:10 +08:00
|
|
|
// 1. create a plotter window and get a pointer to the internal datastore (for convenience)
|
|
|
|
JKQTPlotter plot;
|
2019-01-26 03:16:04 +08:00
|
|
|
plot.getPlotter()->setUseAntiAliasingForGraphs(true); // nicer (but slower) plotting
|
|
|
|
plot.getPlotter()->setUseAntiAliasingForSystem(true); // nicer (but slower) plotting
|
|
|
|
plot.getPlotter()->setUseAntiAliasingForText(true); // nicer (but slower) text rendering
|
2019-01-20 23:15:10 +08:00
|
|
|
JKQTPDatastore* ds=plot.getDatastore();
|
|
|
|
|
|
|
|
// 2. now we create data for the boxplots
|
|
|
|
QVector<double> POS, POSY, MEDIAN, MEAN, Q25, Q75, MIN, MAX, OUTLIERSX, OUTLIERSY;
|
|
|
|
POS << 1 << 4 << 7 << 10;
|
|
|
|
POSY << -1 << -2 << -3 << -4;
|
|
|
|
MIN << 2 << 3 << 2.5 << 6;
|
|
|
|
Q25 << 4 << 4.5 << 5 << 7;
|
|
|
|
MEDIAN << 5 << 6 << 7 << 9;
|
|
|
|
MEAN << 5.5 << 5.2 << 8 << 8;
|
|
|
|
Q75 << 6 << 7 << 9 << 11;
|
|
|
|
MAX << 8 << 7.5 << 11 << 12;
|
|
|
|
// ... and some outliers (as (x,y)-pairs)
|
|
|
|
OUTLIERSX << 4 << 4 << 4 << 4 << 4 << 10 << 10 << 10 << 10 << 10 << 10 << 10;
|
|
|
|
OUTLIERSY << 1 << 0.5 << 1.3 << 8 << 8.1 << 5 << 4 << 12.2 << 13 << 12.5 << 13.5 << 13.1;
|
|
|
|
|
|
|
|
// 3. make data available to JKQTPlotter by adding it to the internal datastore.
|
|
|
|
size_t columnPOS=ds->addCopiedColumn(POS, "POS");
|
|
|
|
size_t columnPOSY=ds->addCopiedColumn(POSY, "POSY");
|
|
|
|
size_t columnMIN=ds->addCopiedColumn(MIN, "MIN");
|
|
|
|
size_t columnQ25=ds->addCopiedColumn(Q25, "Q25");
|
|
|
|
size_t columnMEDIAN=ds->addCopiedColumn(MEDIAN, "MEDIAN");
|
|
|
|
size_t columnMEAN=ds->addCopiedColumn(MEAN, "MEAN");
|
|
|
|
size_t columnQ75=ds->addCopiedColumn(Q75, "Q75");
|
|
|
|
size_t columnMAX=ds->addCopiedColumn(MAX, "MAX");
|
|
|
|
size_t columnOUTLIERSX=ds->addCopiedColumn(OUTLIERSX, "OUTLIERSX");
|
|
|
|
size_t columnOUTLIERSY=ds->addCopiedColumn(OUTLIERSY, "OUTLIERSY");
|
|
|
|
|
|
|
|
// 4. create a graph of vertical boxplots:
|
|
|
|
JKQTPBoxplotVerticalGraph* graph=new JKQTPBoxplotVerticalGraph(&plot);
|
2019-04-22 23:19:52 +08:00
|
|
|
graph->setPositionColumn(columnPOS);
|
2019-01-26 20:00:40 +08:00
|
|
|
graph->setMinColumn(columnMIN);
|
|
|
|
graph->setPercentile25Column(columnQ25);
|
|
|
|
graph->setMedianColumn(columnMEDIAN);
|
|
|
|
graph->setMeanColumn(columnMEAN);
|
|
|
|
graph->setPercentile75Column(columnQ75);
|
|
|
|
graph->setMaxColumn(columnMAX);
|
|
|
|
graph->setTitle("vertical Boxplots");
|
2019-01-20 23:15:10 +08:00
|
|
|
|
|
|
|
// 5. outliers need to be drawn separately
|
|
|
|
JKQTPXYLineGraph* graphOutliers=new JKQTPXYLineGraph(&plot);
|
2019-01-26 20:00:40 +08:00
|
|
|
graphOutliers->setXColumn(columnOUTLIERSX);
|
|
|
|
graphOutliers->setYColumn(columnOUTLIERSY);
|
|
|
|
graphOutliers->setTitle("outliers");
|
2019-01-20 23:15:10 +08:00
|
|
|
// make the color a darker shade of the color of graph
|
2019-04-22 23:19:52 +08:00
|
|
|
graphOutliers->setColor(graph->getLineColor().darker());
|
2019-04-22 19:27:50 +08:00
|
|
|
graphOutliers->setSymbolFillColor(QColor("white"));
|
2019-01-20 23:15:10 +08:00
|
|
|
// draw outliers as small circles, without lines
|
2019-04-22 19:27:50 +08:00
|
|
|
graphOutliers->setSymbolType(JKQTPCircle);
|
2019-01-26 20:00:40 +08:00
|
|
|
graphOutliers->setDrawLine(false);
|
|
|
|
graphOutliers->setSymbolSize(7);
|
2019-01-20 23:15:10 +08:00
|
|
|
|
|
|
|
// 6. create a graph of horizontal boxplots:
|
|
|
|
JKQTPBoxplotHorizontalGraph* graphh=new JKQTPBoxplotHorizontalGraph(&plot);
|
2019-04-22 23:19:52 +08:00
|
|
|
graphh->setPositionColumn(columnPOSY);
|
2019-01-26 20:00:40 +08:00
|
|
|
graphh->setMinColumn(columnMIN);
|
|
|
|
graphh->setPercentile25Column(columnQ25);
|
|
|
|
graphh->setMedianColumn(columnMEDIAN);
|
|
|
|
graphh->setMeanColumn(columnMEAN);
|
|
|
|
graphh->setPercentile75Column(columnQ75);
|
|
|
|
graphh->setMaxColumn(columnMAX);
|
|
|
|
graphh->setTitle("horizontal Boxplots");
|
2019-01-20 23:15:10 +08:00
|
|
|
// 6.1 make fill collor a lighter shade of the outline color
|
2019-04-22 23:19:52 +08:00
|
|
|
graphh->setFillColor(graphh->getLineColor().lighter());
|
2019-01-20 23:15:10 +08:00
|
|
|
// 6.2 make whiskers dashed
|
2019-04-22 23:19:52 +08:00
|
|
|
graphh->setWhiskerLineStyle(Qt::DashLine);
|
2019-05-06 01:58:52 +08:00
|
|
|
graphh->setWhiskerLineColor(graphh->getLineColor().darker());
|
2019-05-11 21:56:11 +08:00
|
|
|
// 6.3 make whiskers caps solid and thick
|
|
|
|
graphh->setWhiskerCapLineStyle(Qt::SolidLine);
|
|
|
|
graphh->setWhiskerCapLineColor(graphh->getLineColor().darker());
|
|
|
|
graphh->setWhiskerCapLineWidth(graphh->getLineWidth()*2.5);
|
|
|
|
// 6.4 change mean symbol
|
|
|
|
graphh->setMeanSymbolType(JKQTPFilledStar);
|
|
|
|
graphh->setMeanFillColor(QColor("silver"));
|
|
|
|
// 6.5 change median line color
|
2019-05-06 01:58:52 +08:00
|
|
|
graphh->setMedianLineColor(QColor("darkgreen"));
|
2019-05-11 21:56:11 +08:00
|
|
|
// 6.6 change box width to 75% of distance
|
|
|
|
graphh->setBoxWidthRelative(0.75);
|
2019-01-20 23:15:10 +08:00
|
|
|
|
|
|
|
// 7. add the graphs to the plot, so it is actually displayed
|
|
|
|
plot.addGraph(graph);
|
|
|
|
plot.addGraph(graphOutliers);
|
|
|
|
plot.addGraph(graphh);
|
|
|
|
|
|
|
|
|
|
|
|
// 8. autoscale the plot so the graph is contained
|
|
|
|
plot.zoomToFit();
|
|
|
|
|
|
|
|
// 9. Move key to top-left
|
2019-01-26 03:16:04 +08:00
|
|
|
plot.getPlotter()->setKeyPosition(JKQTPKeyInsideTopLeft);
|
2019-01-20 23:15:10 +08:00
|
|
|
|
|
|
|
// show plotter and make it a decent size
|
|
|
|
plot.show();
|
2022-09-26 08:08:01 +08:00
|
|
|
plot.resize(600/plot.devicePixelRatioF(),600/plot.devicePixelRatioF());
|
2019-01-20 23:15:10 +08:00
|
|
|
|
2022-09-26 08:08:01 +08:00
|
|
|
app.addExportStepFunctor([&]() {
|
|
|
|
graph->setVisible(true);
|
|
|
|
graphOutliers->setVisible(false);
|
|
|
|
graphh->setVisible(false);
|
|
|
|
plot.zoomToFit();
|
|
|
|
});
|
|
|
|
app.addExportStepFunctor([&]() {
|
|
|
|
graph->setVisible(false);
|
|
|
|
graphOutliers->setVisible(false);
|
|
|
|
graphh->setVisible(true);
|
|
|
|
plot.zoomToFit();
|
|
|
|
});
|
2019-01-20 23:15:10 +08:00
|
|
|
return app.exec();
|
|
|
|
}
|