JKQTPlotter trunk/v5.0.0
an extensive Qt5+Qt6 Plotter framework (including a feature-richt plotter widget, a speed-optimized, but limited variant and a LaTeX equation renderer!), written fully in C/C++ and without external dependencies
Loading...
Searching...
No Matches
Example (JKQTPlotter): Plotting a Statistical Distribution of Data

This project (see test_distributionplot demonstrates how to combine several different graphs and geometric elements to show a set of random values and their statistics.

Note that this example explains how to generate the statistics plots by hand, i.e. by calculating all the statistical properties for the boxplots and then adding the necessary graphs. The internal JKQTPlotter Statistics Library offers methods to perform these calculations, which are explained in the tutorial Advanced 1-Dimensional Statistics with JKQTPDatastore in detail. Several examples give more details on boxplots: Boxplots, Styling different aspects of boxplots.

The source code of the main application is (see test_distributionplot.cpp.

After adding all necessary data to the JKQTDatastore:

// 1. create a plotter window and get a pointer to the internal datastore (for convenience)
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
// 2. now we create random values drawn from a gaussian distribution
QVector<double> RANDVAL; // will store the values themselves
std::map<int, double> hist; // is used to calculate the histogram of the data
for (int i=-5; i<=15; i++) hist[i]=0;
std::random_device rd; // random number generators:
std::mt19937 gen{rd()};
// draw 301 random values from a gaussian distribution around 5 with width 3
const double th_mean=5;
const double th_std=3;
std::normal_distribution<> d{th_mean,th_std};
size_t NDATA=301;
double sum=0;
double square_sum=0;
for (size_t i=0; i<NDATA; i++) {
const double v=d(gen);
RANDVAL<<v; // store data
++hist[std::round(v)]; // calculate histogram
// accumulate data for statistics:
sum+=v;
square_sum+=(v*v);
}
// normalize histogram
for (auto& hi: hist) {
hi.second=hi.second/static_cast<double>(NDATA);
}
// sort random data in order to calculate the statistical properties:
qSort(RANDVAL);
const double rndMean=sum/static_cast<double>(NDATA);
const double rndMin=RANDVAL.first();
const double rndMax=RANDVAL.last();
const double rndMedian=RANDVAL[RANDVAL.size()/2];
const double rndQ25=RANDVAL[RANDVAL.size()/4];
const double rndQ75=RANDVAL[RANDVAL.size()*3/4];
const double rndMedianConfidence=2.0*1.57*fabs(rndQ75-rndQ25)/sqrt(static_cast<double>(NDATA));
// 3. make data available to JKQTPlotter by adding it to the internal datastore.
size_t columnRANDVAL=ds->addCopiedColumn(RANDVAL, "RANDVAL"); // copy random values
std::pair<size_t,size_t> columnHIST = ds->addCopiedMap(hist, "HIST_X", "HIST_Y"); // copy histogram
// 4. create a graph of horizontal boxplots:
graphRANDVALS->setDataColumn(columnRANDVAL);
// draw data as symbols at (x,y)=(data,-0.07):
graphRANDVALS->setPosition(-0.07);
// data should scatter around position=-0.07 with a width=0.08 (i.e. from position-width/2 ... position+width/2)
//graphRANDVALS->setWidth(0.08);
//graphRANDVALS->setPositionScatterStyle(JKQTPSingleColumnSymbolsGraph::RandomScatter);
// data should scatter around position=-0.07 in a BeeSwarmScatter-Plot
// choose small filled circles as symbols, JKQTPGraphSymbols::set their color:
graphRANDVALS->setSymbolSize(5);
graphRANDVALS->setColor(QColor("red"));
graphRANDVALS->setFillColor(graphRANDVALS->getColor().lighter(180));
// set title:
graphRANDVALS->setTitle("Random Data");
// 5. draw the histogram as barchart:
graphHIST->setXColumn(columnHIST.first);
graphHIST->setYColumn(columnHIST.second);
// set title:
graphHIST->setTitle("Histogram");
// 6. draw the theoretical distribution as function graph:
// define the gaussian function used for the random number generator
graphTheoDist->setPlotFunctionFunctor([&th_mean,&th_std](double x) -> double {
return 1.0/(th_std*sqrt(2.0*M_PI))*exp(-0.5*(x-th_mean)*(x-th_mean)/th_std/th_std);
});
// set title:
graphTheoDist->setTitle(QString("Theoretical Distribution $\\mu=%1, \\sigma=%2$").arg(th_mean,0, 'f', 1).arg(th_std,0, 'f', 1));
// 7. create a graph of horizontal boxplots:
graphBoxPlot->setPos(0.15);
graphBoxPlot->setMin(rndMin);
graphBoxPlot->setPercentile25(rndQ25);
graphBoxPlot->setMean(rndMean);
graphBoxPlot->setMedian(rndMedian);
graphBoxPlot->setMedianConfidenceIntervalWidth(rndMedianConfidence);
graphBoxPlot->setPercentile75(rndQ75);
graphBoxPlot->setMax(rndMax);
graphBoxPlot->setBoxWidthAbsolute(24);
graphBoxPlot->setMeanSize(16);
graphBoxPlot->setLineWidth(2);
graphBoxPlot->setTitle("Statistical Properties");
graphBoxPlot->setBoxplotColor(QColor("blue"), plot.getPlotter());
// make fill collor a lighter shade of the outline color
graphBoxPlot->setFillColor(graphBoxPlot->getLineColor().lighter(180));
// make whiskers dashed
graphBoxPlot->setWhiskerLineStyle(Qt::DashLine);
// 8. add the graphs to the plot, so it is actually displayed
plot.addGraph(graphRANDVALS);
plot.addGraph(graphHIST);
plot.addGraph(graphTheoDist);
plot.addGraph(graphBoxPlot);
// 9. autoscale the plot so the graph is contained
plot.zoomToFit();
// 10. Move key to top-left
// 11. show plotter and make it a decent size
plot.show();
plot.resize(800,800);
void setUseAntiAliasingForSystem(bool __value)
specifies whether to use antialiasing for plotting the coordinate system
void setUseAntiAliasingForGraphs(bool __value)
specifies whether to use antialiasing for plotting the graphs
void setKeyPosition(const JKQTPKeyPosition &__value)
key position inside or besides the plot area, see JKQTPKeyPositions for details and examples
void setUseAntiAliasingForText(bool __value)
specifies whether to use antialiasing when drawing any text
This implements a vertical bar graph with bars between and .
Definition jkqtpbarchart.h:51
void setMin(double __value)
the minimum value to be used for the boxplot
void setMedianConfidenceIntervalWidth(double __value)
the width of the confidence interval around the median
void setPos(double __value)
the position of the boxplot on the "other" axis
void setMedian(double __value)
the median value to be used for the boxplot
void setMax(double __value)
the maximum value to be used for the boxplot
void setMean(double __value)
the mean value to be used for the boxplot
void setPercentile75(double __value)
the 75% percentile value to be used for the boxplot
void setPercentile25(double __value)
the 25% percentile value to be used for the boxplot
This implements a horizontal (notched) boxplot where the data is directly given to the object and not...
Definition jkqtpboxplot.h:229
This class manages data columns (with entries of type double ), used by JKQTPlotter/JKQTBasePlotter t...
Definition jkqtpdatastorage.h:282
size_t addCopiedColumn(TIterator first, TIterator last, const QString &name=QString(""))
add one column to the datastore. It will be filled with the values from first ... last
Definition jkqtpdatastorage.h:871
std::pair< size_t, size_t > addCopiedMap(TIterator first, TIterator last, const QString &nameKey=QString("map_key"), const QString &nameValue=QString("map_value"))
copies the contents of the map-like container c into two columns of the datastore,...
Definition jkqtpdatastorage.h:1196
virtual void setPlotFunctionFunctor(jkqtpPlotFunctionType &&__value)
sets a functor to be plotted
void setBoxplotColor(QColor c, JKQTBasePlotter *parent)
set the color of the graph (colors all elements, based on the given color c )
void setBoxWidthAbsolute(double __value)
width of box in pt.
void setMeanSize(double __value)
set the size (=diameter in pt) of the symbol for the mean (in pt)
void setWhiskerLineStyle(Qt::PenStyle __value)
set the line style of whisker lines
void setFillColor(const QColor &__value)
set the color of the graph filling
void setLineWidth(double __value)
set the line width of the graph line (in pt)
QColor getLineColor() const
get the color of the graph line
void setSymbolSize(double __value)
set the size (=diameter in pt) of the graph symbol (in pt)
void setSymbolType(JKQTPGraphSymbols __value)
set the type of the graph symbol
virtual void setTitle(const QString &__value)
sets the title of the plot (for display in key!).
void setDataColumn(int __value)
the column that contains the datapoints
@ X
the data for a JKQTPSingleColumnGraph is data belonging to the x-axis of the plot
void setDataDirection(DataDirection __value)
interpret the data from dataColumn either as X- or Y-data
plots a 1-column set of data-values with symbols onto a JKQtPlotter/JKQtBasePlotter....
Definition jkqtpsinglecolumnsymbols.h:53
@ BeeSwarmScatter
missing coordinate scatters around position and the algorithm tries to prevent overlay of two symbols...
Definition jkqtpsinglecolumnsymbols.h:61
void setColor(QColor col)
set symbol color and fill color at the same time
void setPosition(double __value)
missing coordinate, i.e. if the data from dataColumn is interpreted as x-values, this is the y-positi...
void setPositionScatterStyle(ScatterStyle __value)
how to distribute the datapoints from dataColumn at the location position
This implements line plots where the data is taken from a user supplied function .
Definition jkqtpevaluatedfunction.h:289
void setYColumn(int __value)
the column that contains the y-component of the datapoints
void setXColumn(int __value)
the column that contains the x-component of the datapoints
plotter widget for scientific plots (uses JKQTBasePlotter to do the actual drawing)
Definition jkqtplotter.h:364
void zoomToFit(bool zoomX=true, bool zoomY=true, bool includeX0=false, bool includeY0=false, double scaleX=1.05, double scaleY=1.05)
this method zooms the graph so that all plotted datapoints are visible.
Definition jkqtplotter.h:1039
JKQTBasePlotter * getPlotter()
returns the JKQTBasePlotter object internally used for plotting
Definition jkqtplotter.h:404
void addGraph(JKQTPPlotElement *gr)
Definition jkqtplotter.h:784
JKQTPDatastore * getDatastore()
returns a pointer to the datastore used by this object
Definition jkqtplotter.h:611
@ JKQTPKeyInsideTopLeft
the key is positioned inside on the top-left
Definition jkqtptools.h:583
@ JKQTPFilledCircle
a filled circle
Definition jkqtpdrawingtools.h:149

The result looks like this:

test_distributionplot