diff --git a/JKQtPlotterBuildAllExamples.pro b/JKQtPlotterBuildAllExamples.pro
index f115ba8944..c9dffb0628 100644
--- a/JKQtPlotterBuildAllExamples.pro
+++ b/JKQtPlotterBuildAllExamples.pro
@@ -84,6 +84,7 @@ addSimpleTest(datastore_iterators)
addSimpleTest(datastore_statistics)
addSimpleTest(datastore_statistics_2d)
addSimpleTest(datastore_regression)
+addSimpleTest(datastore_groupedstat)
addSimpleTest(contourplot)
#addSimpleTest(rgbimageplot_opencv)
#addSimpleTest(imageplot_opencv)
diff --git a/doc/dox/examples_and_tutorials.dox b/doc/dox/examples_and_tutorials.dox
index bcbe5aa0dd..0d2a421b2b 100644
--- a/doc/dox/examples_and_tutorials.dox
+++ b/doc/dox/examples_and_tutorials.dox
@@ -162,6 +162,9 @@ All test-projects are Qt-projects that use qmake to build. You can load them int
\image html jkqtplotter_simpletest_datastore_statistics_2d_small.png
| \subpage JKQTPlotterBasicJKQTPDatastoreStatistics2D
| Advanced 2-Dimensional Statistical Computation with JKQTPDatastore using the internal statistics library (see \ref jkqtptools_math_statistics ) histograms kernel density estimates (KDE)
diff --git a/doc/dox/jkqtplotter.dox b/doc/dox/jkqtplotter.dox
index 1d357326a2..92ed87ccc2 100644
--- a/doc/dox/jkqtplotter.dox
+++ b/doc/dox/jkqtplotter.dox
@@ -37,7 +37,9 @@ This group assembles a basic set of linear algebra methods, including matrix inv
This group contains a statistics library, which offers several basic methods and is based on an iterator interface:
- \ref jkqtptools_math_statistics_basic
+ - \ref jkqtptools_math_statistics_grouped
- \ref jkqtptools_math_statistics_regression
+ - \ref jkqtptools_math_statistics_poly
- \ref jkqtptools_math_statistics_1dhist
- \ref jkqtptools_math_statistics_2dhist
- \ref jkqtptools_math_statistics_1dkde
@@ -67,9 +69,15 @@ All statistics functions use all values in the given range and convert each valu
\defgroup jkqtptools_math_statistics_basic Basic statistics
\ingroup jkqtptools_math_statistics
+\defgroup jkqtptools_math_statistics_grouped Grouped statistics
+\ingroup jkqtptools_math_statistics
+
\defgroup jkqtptools_math_statistics_regression Regression Analysis
\ingroup jkqtptools_math_statistics
+\defgroup jkqtptools_math_statistics_poly Polynomial Fits/Regression
+\ingroup jkqtptools_math_statistics
+
\defgroup jkqtptools_math_statistics_1dhist 1-dimensional Histograms
\ingroup jkqtptools_math_statistics
diff --git a/examples/README.md b/examples/README.md
index 71397b14da..79b9240699 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -66,6 +66,7 @@ All test-projects are Qt-projects that use qmake to build. You can load them int
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/simpletest_datastore_iterators_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_datastore_iterators) | [Tutorial: Iterator-based access to JKQTPDatastore](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_datastore_iterators) | Iterator-based Data Management with JKQTPDatastore |
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_datastore_statistics_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_datastore_statistics) | [Tutorial: Advanced 1-Dimensional Statistics with JKQTPDatastore](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_datastore_statistics) | Advanced 1-Dimensional Statistical Computation with JKQTPDatastore using the internal statistics library basic statistics (mean, standard deviation, ...) boxplots histograms kernel density estimates (KDE) |
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_datastore_regression_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_datastore_regression) | [Tutorial: Regression Analysis (with the Statistics Library)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_datastore_regression) | Advanced 1-Dimensional Statistical Computation with JKQTPDatastore using the internal statistics library Regression Analysis (with the Statistics Library) robust regression (IRLS) weighted regression non-linear regression polynomial fitting |
+| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_datastore_groupedstat_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_datastore_groupedstat) | [Tutorial: 1-Dimensional Group Statistics (with the Statistics Library)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_datastore_groupedstat) | Advanced 1-Dimensional Statistical Computation with JKQTPDatastore grouped statistics error indicators from data boxplots |
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_datastore_statistics_2d_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_datastore_statistics_2d) | [Tutorial: Advanced 2-Dimensional Statistics with JKQTPDatastore](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_datastore_statistics_2d) | Advanced 2-Dimensional Statistical Computation with JKQTPDatastore using the internal statistics library histograms kernel density estimates (KDE) |
diff --git a/examples/simpletest_boxplot/README.md b/examples/simpletest_boxplot/README.md
index 1f49cd5ed6..641e4b4b64 100644
--- a/examples/simpletest_boxplot/README.md
+++ b/examples/simpletest_boxplot/README.md
@@ -1,6 +1,13 @@
# Example (JKQTPlotter): Boxplots {#JKQTPlotterBoxplotsGraphs}
+
This project (see [`simpletest_boxplot`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_boxplot) demonstrates how to use JKQTPlotter to draw box plots using the classes `JKQTPBoxplotVerticalGraph` and `JKQTPBoxplotHorizontalGraph`.
+[JKQTPlotterBasicJKQTPDatastoreStatistics]: @ref JKQTPlotterBasicJKQTPDatastoreStatistics "Advanced 1-Dimensional Statistics with JKQTPDatastore"
+[statisticslibrary]: @ref jkqtptools_math_statistics "JKQTPlotter Statistics Library"
+[JKQTPlotterBoxplotStyling]: @ref JKQTPlotterBoxplotStyling "Styling different aspects of boxplots"
+
+***Note*** that this example explains how to add boxplots to a graph by hand, i.e. by calculating all the statistical properties for the boxplots by hand. The internal [statisticslibrary] offers methods to perform these calculations, which are explained in the tutorial [JKQTPlotterBasicJKQTPDatastoreStatistics] in detail. Additional advanced styling of boxplots is covered by the example [JKQTPlotterBoxplotStyling].
+
The source code of the main application is (see [`jkqtplotter_simpletest_boxplot.cpp`](jkqtplotter_simpletest_boxplot.cpp).
After adding all necessary data to the JKQTDatastore:
diff --git a/examples/simpletest_datastore/README.md b/examples/simpletest_datastore/README.md
index b23236a8a1..f862984fab 100644
--- a/examples/simpletest_datastore/README.md
+++ b/examples/simpletest_datastore/README.md
@@ -1,10 +1,10 @@
# Tutorial (JKQTPDatastore): Basic Usage of JKQTPDatastore {#JKQTPlotterBasicJKQTPDatastore}
-
[JKQTPlotterBasicJKQTPDatastore]: @ref JKQTPlotterBasicJKQTPDatastore "Basic Usage of JKQTPDatastore"
[JKQTPlotterBasicJKQTPDatastoreIterators]: @ref JKQTPlotterBasicJKQTPDatastoreIterators "Iterator-Based usage of JKQTPDatastore"
[JKQTPlotterBasicJKQTPDatastoreStatistics]: @ref JKQTPlotterBasicJKQTPDatastoreStatistics "Advanced 1-Dimensional Statistics with JKQTPDatastore"
[JKQTPlotterBasicJKQTPDatastoreRegression]: @ref JKQTPlotterBasicJKQTPDatastoreRegression "Regression Analysis (with the Statistics Library)"
+[JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat]: @ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat "1-Dimensional Group Statistics with JKQTPDatastore"
[JKQTPlotterBasicJKQTPDatastoreStatistics2D]: @ref JKQTPlotterBasicJKQTPDatastoreStatistics2D "Advanced 2-Dimensional Statistics with JKQTPDatastore"
[statisticslibrary]: @ref jkqtptools_math_statistics "JKQTPlotter Statistics Library"
@@ -14,8 +14,10 @@ This tutorial project (see `./examples/simpletest_datastore/`) explains several
- [JKQTPlotterBasicJKQTPDatastore]
- [JKQTPlotterBasicJKQTPDatastoreIterators]
- [JKQTPlotterBasicJKQTPDatastoreStatistics]
- - [JKQTPlotterBasicJKQTPDatastoreStatistics2D]
- [JKQTPlotterBasicJKQTPDatastoreRegression]
+ - [JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat]
+ - [JKQTPlotterBasicJKQTPDatastoreStatistics2D]
+
[TOC]
diff --git a/examples/simpletest_datastore_groupedstat/README.md b/examples/simpletest_datastore_groupedstat/README.md
new file mode 100644
index 0000000000..5c7c95c6ee
--- /dev/null
+++ b/examples/simpletest_datastore_groupedstat/README.md
@@ -0,0 +1,255 @@
+# Tutorial (JKQTPDatastore): 1-Dimensional Group Statistics with JKQTPDatastore {#JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat}
+
+[JKQTPlotterBasicJKQTPDatastore]: @ref JKQTPlotterBasicJKQTPDatastore "Basic Usage of JKQTPDatastore"
+[JKQTPlotterBasicJKQTPDatastoreIterators]: @ref JKQTPlotterBasicJKQTPDatastoreIterators "Iterator-Based usage of JKQTPDatastore"
+[JKQTPlotterBasicJKQTPDatastoreStatistics]: @ref JKQTPlotterBasicJKQTPDatastoreStatistics "Advanced 1-Dimensional Statistics with JKQTPDatastore"
+[JKQTPlotterBasicJKQTPDatastoreRegression]: @ref JKQTPlotterBasicJKQTPDatastoreRegression "Regression Analysis (with the Statistics Library)"
+[JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat]: @ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat "1-Dimensional Group Statistics with JKQTPDatastore"
+[JKQTPlotterBasicJKQTPDatastoreStatistics2D]: @ref JKQTPlotterBasicJKQTPDatastoreStatistics2D "Advanced 2-Dimensional Statistics with JKQTPDatastore"
+[statisticslibrary]: @ref jkqtptools_math_statistics "JKQTPlotter Statistics Library"
+
+This tutorial project (see `./examples/simpletest_datastore_groupedstat/`) explains several advanced functions of JKQTPDatastore in combination with the [[statisticslibrary]] conatined in JKQTPlotter.
+
+***Note*** that there are additional tutorial explaining other aspects of data mangement in JKQTPDatastore:
+ - [JKQTPlotterBasicJKQTPDatastore]
+ - [JKQTPlotterBasicJKQTPDatastoreIterators]
+ - [JKQTPlotterBasicJKQTPDatastoreStatistics]
+ - [JKQTPlotterBasicJKQTPDatastoreRegression]
+ - [JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat]
+ - [JKQTPlotterBasicJKQTPDatastoreStatistics2D]
+
+[TOC]
+
+The source code of the main application can be found in [`jkqtplotter_simpletest_datastore_groupedstat.cpp`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_datastore_groupedstat/jkqtplotter_simpletest_datastore_groupedstat.cpp).
+This tutorial cites only parts of this code to demonstrate different ways of working with data for the graphs.
+
+# Barcharts & Boxplots from categorized data
+
+## Generating a Dataset for Grouped Barcharts
+
+To demonstrate the grouped statistics, we first have to generate a dataset. The datapoints consist of pairs ``, where the groups are encoded by the numbers 1,2,3 and in each group, several measurements are taken:
+```.cpp
+ size_t colBarRawGroup=datastore1->addColumn("barchart, rawdata, group");
+ size_t colBarRawValue=datastore1->addColumn("barchart, rawdata, value");
+
+ // data for group 1
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 1, 1.1);
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 1, 1.5);
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 1, 0.8);
+ // ...
+
+ // data for group 2
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 2, 2.2);
+ // ...
+
+ // data for group 3
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 3, 4.1);
+ // ...
+
+```
+
+Note that the data does not have to be sorted. You can add the dataset in any order!
+
+This dataset can be visualized with a simple scatter plot:
+```.cpp
+ JKQTPXYLineGraph* gScatterForBar;
+ plotbarchart->addGraph(gScatterForBar=new JKQTPXYLineGraph(plotbarchart));
+ gScatterForBar->setXYColumns(colBarRawGroup, colBarRawValue);
+ gScatterForBar->setDrawLine(false);
+ gScatterForBar->setSymbolType(JKQTPCross);
+ gScatterForBar->setSymbolSize(5);
+ gScatterForBar->setSymbolColor(QColorWithAlphaF(QColor("red"), 0.5));
+```
+
+![jkqtplotter_simpletest_datastore_groupedstat_barchartrawdata](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_datastore_groupedstat_barchartrawdata.png)
+
+## Calculating Grouped Statistics for a Barchart
+
+Now we want to draw a barchart for every group, which indicates the average in each group. This is done using methods from the statistics library.
+First we need to group the data using `jkqtpstatGroupData()`, which assembles the data points in each group groupeddataBar
+```.cpp
+ std::map > groupeddataBar;
+ jkqtpstatGroupData(datastore1->begin(colBarRawGroup), datastore1->end(colBarRawGroup),
+ datastore1->begin(colBarRawValue), datastore1->end(colBarRawValue),
+ groupeddataBar);
+```
+Now we can calculate the statistics for each group separately: Data is collected in new columns `colBarGroup`, `colBarAverage` and `colBarStdDev`. The statistics is then calculated by simply iterating over `groupeddataBar` and calling functions like `jkqtpstatAverage()` for each group:
+```.cpp
+ size_t colBarGroup=datastore1->addColumn("barchart, group");
+ size_t colBarAverage=datastore1->addColumn("barchart, group-average");
+ size_t colBarStdDev=datastore1->addColumn("barchart, group-stddev");
+
+ for (auto it=groupeddataBar.begin(); it!=groupeddataBar.end(); ++it) {
+ datastore1->appendToColumn(colBarGroup, it->first);
+ datastore1->appendToColumn(colBarAverage, jkqtpstatAverage(it->second.begin(), it->second.end()));
+ datastore1->appendToColumn(colBarStdDev, jkqtpstatStdDev(it->second.begin(), it->second.end()));
+ }
+```
+
+Finally the calculated groups are drawn:
+```.cpp
+ JKQTPBarVerticalErrorGraph* gBar;
+ plotbarchart->addGraph(gBar=new JKQTPBarVerticalErrorGraph(plotbarchart));
+ gBar->setXYColumns(colBarGroup, colBarAverage);
+ gBar->setYErrorColumn(static_cast(colBarStdDev));
+```
+
+![jkqtplotter_simpletest_datastore_groupedstat_barchart](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_datastore_groupedstat_barchart.png)
+
+In order to safe yo the typing of the code above, shortcuts in the form of adaptors exist:
+```.cpp
+ jkqtpstatAddYErrorBarGraph(plotbarchart->getPlotter(),
+ datastore1->begin(colBarRawGroup), datastore1->end(colBarRawGroup),
+ datastore1->begin(colBarRawValue), datastore1->end(colBarRawValue));
+```
+Also other flavors exist that generate different graphs (see the JKQTPlotter documentation):
+ - `jkqtpstatAddYErrorLineGraph()` / `jkqtpstatAddXErrorLineGraph()`
+ - `jkqtpstatAddYErrorBarGraph()` / `jkqtpstatAddXErrorBarGraph()`
+ - `jkqtpstatAddYErrorImpulsesGraph()` / `jkqtpstatAddXErrorImpulsesGraph()`
+ - `jkqtpstatAddYErrorParametrizedScatterGraph()` / `jkqtpstatAddXErrorParametrizedScatterGraph()`
+ - `jkqtpstatAddYErrorFilledCurveGraph()` / `jkqtpstatAddXErrorFilledCurveGraph()`
+ - `jkqtpstatAddYErrorGraph()` / `jkqtpstatAddXErrorGraph()`
+
+
+## Calculating Grouped Statistics for a Boxplot
+
+With the methods above we can also calculate more advanced statistics, like e.g. boxplots:
+```.cpp
+ size_t colBarMedian=datastore1->addColumn("barchart, group-median");
+ size_t colBarMin=datastore1->addColumn("barchart, group-min");
+ size_t colBarMax=datastore1->addColumn("barchart, group-max");
+ size_t colBarQ25=datastore1->addColumn("barchart, group-Q25");
+ size_t colBarQ75=datastore1->addColumn("barchart, group-Q75");
+ for (auto it=groupeddataBar.begin(); it!=groupeddataBar.end(); ++it) {
+ datastore1->appendToColumn(colBarMedian, jkqtpstatMedian(it->second.begin(), it->second.end()));
+ datastore1->appendToColumn(colBarMin, jkqtpstatMinimum(it->second.begin(), it->second.end()));
+ datastore1->appendToColumn(colBarMax, jkqtpstatMaximum(it->second.begin(), it->second.end()));
+ datastore1->appendToColumn(colBarQ25, jkqtpstatQuantile(it->second.begin(), it->second.end(), 0.25));
+ datastore1->appendToColumn(colBarQ75, jkqtpstatQuantile(it->second.begin(), it->second.end(), 0.75));
+ }
+```
+The result can be plotted using JKQTPBoxplotVerticalGraph, which receives a column for each value class of the final plot:
+```.cpp
+ JKQTPBoxplotVerticalGraph* gBoxplot;
+ plotboxplot->addGraph(gBoxplot=new JKQTPBoxplotVerticalGraph(plotboxplot));
+ gBoxplot->setPositionColumn(colBarGroup);
+ gBoxplot->setMinColumn(colBarMin);
+ gBoxplot->setMaxColumn(colBarMax);
+ gBoxplot->setMedianColumn(colBarMedian);
+ gBoxplot->setPercentile25Column(colBarQ25);
+ gBoxplot->setPercentile75Column(colBarQ75);
+```
+
+![jkqtplotter_simpletest_datastore_groupedstat_boxplot](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_datastore_groupedstat_boxplot.png)
+
+In order to safe yo the typing of the code above, shortcuts in the form of adaptors exist:
+```.cpp
+ jkqtpstatAddHBoxplotsAndOutliers(plotboxplot->getPlotter(),
+ datastore1->begin(colBarRawGroup), datastore1->end(colBarRawGroup),
+ datastore1->begin(colBarRawValue), datastore1->end(colBarRawValue));
+```
+Also other flavors exist that generate different graphs (see the JKQTPlotter documentation):
+ - `jkqtpstatAddVBoxplotsAndOutliers()` / `jkqtpstatAddHBoxplotsAndOutliers()`
+ - `jkqtpstatVAddBoxplots()` / `jkqtpstatHAddBoxplots()`
+ - `jkqtpstatAddBoxplots()`
+
+
+# (Scatter-)Graphs with X/Y-errors from Categorized Data
+
+## Dataset for XY Scatter Graphs
+
+First we generate a second dataset, which is going to be used for a scaterplot. The datapoints consist of pairs ``, that are based on a parabula with random deviations, both in x- and y-direction:
+```.cpp
+ size_t colScatterRawX=datastore1->addColumn("scatterplot, rawdata, x");
+ size_t colScatterRawY=datastore1->addColumn("scatterplot, rawdata, y");
+ std::random_device rd; // random number generators:
+ std::mt19937 gen{rd()};
+ std::normal_distribution<> d1{0,0.5};
+ const size_t N=100;
+ const double xmax=3.5;
+ for (size_t i=0; i(i)-static_cast(N)/2.0)*xmax/(static_cast(N)/2.0);
+ const double y=jkqtp_sqr(x)+2.0;
+ datastore1->appendToColumns(colScatterRawX, colScatterRawY, x+d1(gen), y+d1(gen));
+ }
+```
+
+This dataset can be visualized:
+```.cpp
+ JKQTPXYParametrizedScatterGraph* gScatterRaw;
+ plotscattererrors->addGraph(gScatterRaw=new JKQTPXYParametrizedScatterGraph(plotscattererrors));
+ gScatterRaw->setXYColumns(colScatterRawX, colScatterRawY);
+ gScatterRaw->setDrawLine(false);
+ gScatterRaw->setSymbolType(JKQTPCross);
+ gScatterRaw->setSymbolSize(5);
+```
+
+![jkqtplotter_simpletest_datastore_groupedstat_scatterrawdata](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_datastore_groupedstat_scatterrawdata.png)
+
+## Calculating x- and y-Errors from Categorized Data
+
+Now we want to draw a scatterchart of the data, where data-points should be grouped together, in x-intervals of width 0.5. From all the points in each interval, we calculate the in both x- and y-direction the average and standard deviation. First we need to group the data using `jkqtpstatGroupData()`, which assembles the data points in each group groupeddataScatter. For the custom grouping of the datapoints we use the optional functor provided to `jkqtpstatGroupData()`: We use `jkqtpstatGroupingCustomRound1D()` with given parameters 0.25 for the (center) location of the first bin and bin width 0.5. The functor is not built by hand (which would be possible using std::bind), but with the generator function `jkqtpstatMakeGroupingCustomRound1D()`. In addition we use a variant of `jkqtpstatGroupData()`, which outputs a column with the category assigned to every data pair in the input data range:
+```.cpp
+ std::map,std::vector > > groupeddataScatter;
+ size_t colScatterRawGroup=datastore1->addColumn("scatterplot, rawdata, assigned-group");
+ jkqtpstatGroupData(datastore1->begin(colScatterRawX), datastore1->end(colScatterRawX),
+ datastore1->begin(colScatterRawY), datastore1->end(colScatterRawY),
+ datastore1->backInserter(colScatterRawGroup),
+ groupeddataScatter,
+ jkqtpstatMakeGroupingCustomRound1D(0.25, 0.5));
+```
+
+The column colScatterRawGroup can now be used to color the scatter graph:
+```.cpp
+ gScatterRaw->setColorColumn(colScatterRawGroup);
+```
+
+Now we can calculate the statistics for each group separately: Data is collected in two new columns. Then the statistics is calculated by simply iterating over `groupeddataScatter` and calling functions like `jkqtpstatAverage()` for each group:
+```.cpp
+ size_t colScatterXAvg=datastore1->addColumn("scatter, x, average");
+ size_t colScatterXStd=datastore1->addColumn("scatter, x, stddev");
+ size_t colScatterYAvg=datastore1->addColumn("scatter, y, average");
+ size_t colScatterYStd=datastore1->addColumn("scatter, y, stddev");
+
+ for (auto it=groupeddataScatter.begin(); it!=groupeddataScatter.end(); ++it) {
+ datastore1->appendToColumn(colScatterXAvg, jkqtpstatAverage(it->second.first.begin(), it->second.first.end()));
+ datastore1->appendToColumn(colScatterXStd, jkqtpstatStdDev(it->second.first.begin(), it->second.first.end()));
+ datastore1->appendToColumn(colScatterYAvg, jkqtpstatAverage(it->second.second.begin(), it->second.second.end()));
+ datastore1->appendToColumn(colScatterYStd, jkqtpstatStdDev(it->second.second.begin(), it->second.second.end()));
+ }
+```
+
+Finally the calculated groups are drawn
+```.cpp
+ JKQTPXYLineErrorGraph* gScatterErr;
+ plotscattererrors->addGraph(gScatterErr=new JKQTPXYLineErrorGraph(plotscattererrors));
+ gScatterErr->setXYColumns(colScatterXAvg, colScatterYAvg);
+ gScatterErr->setXErrorColumn(static_cast(colScatterXStd));
+ gScatterErr->setYErrorColumn(static_cast(colScatterYStd));
+ gScatterErr->setSymbolType(JKQTPFilledTriangle);
+ gScatterErr->setDrawLine(false);
+```
+
+![jkqtplotter_simpletest_datastore_groupedstat_scatter](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_datastore_groupedstat_scatter.png)
+
+
+In order to safe yo the typing of the code above, shortcuts in the form of adaptors exist:
+```.cpp
+ jkqtpstatAddXYErrorLineGraph(plotscattererrors->getPlotter(),
+ datastore1->begin(colScatterRawX), datastore1->end(colScatterRawX),
+ datastore1->begin(colScatterRawY), datastore1->end(colScatterRawY),
+ jkqtpstatMakeGroupingCustomRound1D(0.25, 0.5));
+```
+Also other flavors exist that generate different graphs (see the JKQTPlotter documentation):
+ - `jkqtpstatAddXYErrorLineGraph()`
+ - `jkqtpstatAddXYErrorParametrizedScatterGraph()`
+ - `jkqtpstatAddXYErrorGraph()`
+
+
+# Screenshot of the full Program
+
+The output of the full test program [`jkqtplotter_simpletest_datastore_groupedstat.cpp`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_datastore_groupedstat/jkqtplotter_simpletest_datastore_groupedstat.cpp) looks like this:
+
+![jkqtplotter_simpletest_datastore_groupedstat](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_datastore_groupedstat.png)
+
+
diff --git a/examples/simpletest_datastore_groupedstat/jkqtplotter_simpletest_datastore_groupedstat.cpp b/examples/simpletest_datastore_groupedstat/jkqtplotter_simpletest_datastore_groupedstat.cpp
new file mode 100644
index 0000000000..7fa8cedf6e
--- /dev/null
+++ b/examples/simpletest_datastore_groupedstat/jkqtplotter_simpletest_datastore_groupedstat.cpp
@@ -0,0 +1,265 @@
+/** \example jkqtplotter_simpletest_datastore_groupedstat.cpp
+ * Explains how to use the internal statistics library (see \ref jkqtptools_statistics ) together with JKQTPDatastore to generate grouped statistics (i.e. calculates errorbars or boxplots from groups of datapoints in a x/y-dataset).
+ *
+ * \ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat
+ */
+
+#include
+#include "jkqtplotter/jkqtplotter.h"
+#include "jkqtplotter/jkqtpgraphsscatter.h"
+#include "jkqtplotter/jkqtpgraphsbarchart.h"
+#include "jkqtplotter/jkqtpgraphsstatisticsadaptors.h"
+#include "jkqtcommon/jkqtpstatisticstools.h"
+#include "jkqtcommon/jkqtpstringtools.h"
+#include
+#include
+#include
+
+
+int main(int argc, char* argv[])
+{
+ QApplication app(argc, argv);
+
+
+ // 1. create a window with several plotters and get a pointer to the internal datastores (for convenience)
+ QWidget mainWidget;
+ QGridLayout* lay;
+ mainWidget.setLayout(lay=new QGridLayout);
+ JKQTPlotter* plotbarchart=new JKQTPlotter(&mainWidget);
+ plotbarchart->getPlotter()->setPlotLabel("Barcharts");
+ JKQTPDatastore* datastore1=plotbarchart->getDatastore();
+ lay->addWidget(plotbarchart,0,0);
+ JKQTPlotter* plotboxplot=new JKQTPlotter(datastore1, &mainWidget);
+ plotboxplot->getPlotter()->setPlotLabel("Boxplots");
+ lay->addWidget(plotboxplot,0,1);
+ JKQTPlotter* plotscattererrors=new JKQTPlotter(datastore1, &mainWidget);
+ plotscattererrors->getPlotter()->setPlotLabel("Scatter Plot with Error Indicators");
+ lay->addWidget(plotscattererrors,0,2);
+ lay->setColumnStretch(0,1);
+ lay->setColumnStretch(1,1);
+ lay->setColumnStretch(2,2);
+
+
+
+ // 2. Barcharts from categorized data:
+ // 2.1. First we generate a dataset, which is going to be used for a barchart
+ // The datapoints consist of pairs , where the groups are encoded
+ // by the numbers 1,2,3 and in each group, several measurements are taken
+ size_t colBarRawGroup=datastore1->addColumn("barchart, rawdata, group");
+ size_t colBarRawValue=datastore1->addColumn("barchart, rawdata, value");
+
+ // data for group 1
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 1, 1.1);
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 1, 1.5);
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 1, 0.8);
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 1, 1.2);
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 1, 1.4);
+ // data for group 2
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 2, 2.2);
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 2, 2.4);
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 2, 1.9);
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 2, 2.6);
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 2, 2.1);
+ // data for group 3
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 3, 4.1);
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 3, 4.4);
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 3, 3.8);
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 3, 4.5);
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 3, 3.7);
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 3, 4.0);
+ // now some more datapoint, in mixed order
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 1, 0.9);
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 2, 2.3);
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 2, 2.0);
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 1, 1.0);
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 3, 4.2);
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 1, 1.25);
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 2, 2.35);
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 3, 3.7);
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 1, 0.75);
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 2, 1.85);
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 3, 4.5);
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 1, 0.95);
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 2, 1.65);
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 3, 4.1);
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 1, 1.15);
+ datastore1->appendToColumns(colBarRawGroup, colBarRawValue, 2, 2.15);
+
+
+ // 2.2. This dataset can be visualized with a simple scatter plot:
+ JKQTPXYLineGraph* gScatterForBar;
+ plotbarchart->addGraph(gScatterForBar=new JKQTPXYLineGraph(plotbarchart));
+ gScatterForBar->setXYColumns(colBarRawGroup, colBarRawValue);
+ gScatterForBar->setDrawLine(false);
+ gScatterForBar->setSymbolType(JKQTPCross);
+ gScatterForBar->setSymbolSize(5);
+ gScatterForBar->setSymbolColor(QColorWithAlphaF(QColor("red"), 0.5));
+
+ // 2.3. Now we want to draw a barchart for every group, which indicates the
+ // average in each group. This is done using methods from the statistics
+ // library.
+ // First we need to group the data using jkqtpstatGroupData(), which assembles
+ // the data points in each group groupeddataBar
+ std::map > groupeddataBar;
+ jkqtpstatGroupData(datastore1->begin(colBarRawGroup), datastore1->end(colBarRawGroup),
+ datastore1->begin(colBarRawValue), datastore1->end(colBarRawValue),
+ groupeddataBar);
+ // now we can calculate the statistics for each group separately:
+ // Data is collected in two new columns
+ size_t colBarGroup=datastore1->addColumn("barchart, group");
+ size_t colBarAverage=datastore1->addColumn("barchart, group-average");
+ size_t colBarStdDev=datastore1->addColumn("barchart, group-stddev");
+ // Statistics is calculated by simply iterating over groupeddataBar
+ // and calling functions like jkqtpstatAverage() for each group
+ for (auto it=groupeddataBar.begin(); it!=groupeddataBar.end(); ++it) {
+ datastore1->appendToColumn(colBarGroup, it->first);
+ datastore1->appendToColumn(colBarAverage, jkqtpstatAverage(it->second.begin(), it->second.end()));
+ datastore1->appendToColumn(colBarStdDev, jkqtpstatStdDev(it->second.begin(), it->second.end()));
+ }
+
+ // 2.4. Finally the calculated groups are drawn
+ JKQTPBarVerticalErrorGraph* gBar;
+ plotbarchart->addGraph(gBar=new JKQTPBarVerticalErrorGraph(plotbarchart));
+ gBar->setXYColumns(colBarGroup, colBarAverage);
+ gBar->setYErrorColumn(static_cast(colBarStdDev));
+
+ // 2.5. With the methods above we can also calculate more advanced statistics, like e.g. boxplots:
+ size_t colBarMedian=datastore1->addColumn("barchart, group-median");
+ size_t colBarMin=datastore1->addColumn("barchart, group-min");
+ size_t colBarMax=datastore1->addColumn("barchart, group-max");
+ size_t colBarQ25=datastore1->addColumn("barchart, group-Q25");
+ size_t colBarQ75=datastore1->addColumn("barchart, group-Q75");
+ for (auto it=groupeddataBar.begin(); it!=groupeddataBar.end(); ++it) {
+ datastore1->appendToColumn(colBarMedian, jkqtpstatMedian(it->second.begin(), it->second.end()));
+ datastore1->appendToColumn(colBarMin, jkqtpstatMinimum(it->second.begin(), it->second.end()));
+ datastore1->appendToColumn(colBarMax, jkqtpstatMaximum(it->second.begin(), it->second.end()));
+ datastore1->appendToColumn(colBarQ25, jkqtpstatQuantile(it->second.begin(), it->second.end(), 0.25));
+ datastore1->appendToColumn(colBarQ75, jkqtpstatQuantile(it->second.begin(), it->second.end(), 0.75));
+ }
+ // 2.6. The result can be plotted using JKQTPBoxplotVerticalGraph, which receives a column for each value class of the final plot:
+ JKQTPBoxplotVerticalGraph* gBoxplot;
+ plotboxplot->addGraph(gBoxplot=new JKQTPBoxplotVerticalGraph(plotboxplot));
+ gBoxplot->setPositionColumn(colBarGroup);
+ gBoxplot->setMinColumn(colBarMin);
+ gBoxplot->setMaxColumn(colBarMax);
+ gBoxplot->setMedianColumn(colBarMedian);
+ gBoxplot->setPercentile25Column(colBarQ25);
+ gBoxplot->setPercentile75Column(colBarQ75);
+ // 2.7. In order to safe yo the typing of the code above, shortcuts in the form of adaptors exist:
+ /*
+ jkqtpstatAddYErrorBarGraph(plotbarchart->getPlotter(),
+ datastore1->begin(colBarRawGroup), datastore1->end(colBarRawGroup),
+ datastore1->begin(colBarRawValue), datastore1->end(colBarRawValue));
+ jkqtpstatAddHBoxplotsAndOutliers(plotboxplot->getPlotter(),
+ datastore1->begin(colBarRawGroup), datastore1->end(colBarRawGroup),
+ datastore1->begin(colBarRawValue), datastore1->end(colBarRawValue));
+ */
+
+
+
+
+
+ // 3. Scatterplots from categorized data:
+ // 3.1. First we generate a second dataset, which is going to be used for a scaterplot
+ // The datapoints consist of pairs , that are based on a parabula with random
+ // deviations, both in x- and y-direction
+ size_t colScatterRawX=datastore1->addColumn("scatterplot, rawdata, x");
+ size_t colScatterRawY=datastore1->addColumn("scatterplot, rawdata, y");
+ std::random_device rd; // random number generators:
+ std::mt19937 gen{rd()};
+ std::normal_distribution<> d1{0,0.5};
+ const size_t N=100;
+ const double xmax=3.5;
+ for (size_t i=0; i(i)-static_cast(N)/2.0)*xmax/(static_cast(N)/2.0);
+ const double y=jkqtp_sqr(x)+2.0;
+ datastore1->appendToColumns(colScatterRawX, colScatterRawY, x+d1(gen), y+d1(gen));
+ }
+ // 3.2. Now we can also add the raw dataset to the plot for visualization:
+ JKQTPXYParametrizedScatterGraph* gScatterRaw;
+ plotscattererrors->addGraph(gScatterRaw=new JKQTPXYParametrizedScatterGraph(plotscattererrors));
+ gScatterRaw->setXYColumns(colScatterRawX, colScatterRawY);
+ gScatterRaw->setDrawLine(false);
+ gScatterRaw->setSymbolType(JKQTPCross);
+ gScatterRaw->setSymbolSize(5);
+
+ // 3.3. Now we want to draw a scatterchart of the data, where data-points should be grouped
+ // together, in x-intervals of width 0.5. From all the points in each interval, we calculate the
+ // in both x- and y-direction the average and standard deviation.
+ // First we need to group the data using jkqtpstatGroupData(), which assembles
+ // the data points in each group groupeddataScatter. For the custom grouping of the datapoints
+ // we use the optional functor provided to jkqtpstatGroupData(): We use jkqtpstatGroupingCustomRound1D()
+ // with given parameters 0.25 for the (center) location of the first bin and bin width 0.5. The functor
+ // is not built by hand (which would be possible using std::bind), but with the generator function
+ // jkqtpstatMakeGroupingCustomRound1D().
+ // in addition we use a variant of jkqtpstatGroupData(), which outputs a column with the category
+ // assigned to every data pair in the input data range
+ std::map,std::vector > > groupeddataScatter;
+ size_t colScatterRawGroup=datastore1->addColumn("scatterplot, rawdata, assigned-group");
+ jkqtpstatGroupData(datastore1->begin(colScatterRawX), datastore1->end(colScatterRawX),
+ datastore1->begin(colScatterRawY), datastore1->end(colScatterRawY),
+ datastore1->backInserter(colScatterRawGroup),
+ groupeddataScatter,
+ jkqtpstatMakeGroupingCustomRound1D(0.25, 0.5));
+ // The column colScatterRawGroup can now be used to color the scatter graph:
+ gScatterRaw->setColorColumn(colScatterRawGroup);
+ // now we can calculate the statistics for each group separately:
+ // Data is collected in two new columns
+ size_t colScatterXAvg=datastore1->addColumn("scatter, x, average");
+ size_t colScatterXStd=datastore1->addColumn("scatter, x, stddev");
+ size_t colScatterYAvg=datastore1->addColumn("scatter, y, average");
+ size_t colScatterYStd=datastore1->addColumn("scatter, y, stddev");
+ // Statistics is calculated by simply iterating over groupeddataScatter
+ // and calling functions like jkqtpstatAverage() for each group
+ for (auto it=groupeddataScatter.begin(); it!=groupeddataScatter.end(); ++it) {
+ datastore1->appendToColumn(colScatterXAvg, jkqtpstatAverage(it->second.first.begin(), it->second.first.end()));
+ datastore1->appendToColumn(colScatterXStd, jkqtpstatStdDev(it->second.first.begin(), it->second.first.end()));
+ datastore1->appendToColumn(colScatterYAvg, jkqtpstatAverage(it->second.second.begin(), it->second.second.end()));
+ datastore1->appendToColumn(colScatterYStd, jkqtpstatStdDev(it->second.second.begin(), it->second.second.end()));
+ }
+
+ // 3.4. Finally the calculated groups are drawn
+ JKQTPXYLineErrorGraph* gScatterErr;
+ plotscattererrors->addGraph(gScatterErr=new JKQTPXYLineErrorGraph(plotscattererrors));
+ gScatterErr->setXYColumns(colScatterXAvg, colScatterYAvg);
+ gScatterErr->setXErrorColumn(static_cast(colScatterXStd));
+ gScatterErr->setYErrorColumn(static_cast(colScatterYStd));
+ gScatterErr->setSymbolType(JKQTPFilledTriangle);
+ gScatterErr->setDrawLine(false);
+
+ // 3.5. also here an adaptor exists, which makes the task easier:
+ /*
+ jkqtpstatAddXYErrorLineGraph(plotscattererrors->getPlotter(),
+ datastore1->begin(colScatterRawX), datastore1->end(colScatterRawX),
+ datastore1->begin(colScatterRawY), datastore1->end(colScatterRawY),
+ jkqtpstatMakeGroupingCustomRound1D(0.25, 0.5));
+ */
+
+
+
+
+ // autoscale the plot so the graph is contained
+ plotboxplot->synchronizeToMaster(plotbarchart, JKQTBasePlotter::sdXYAxes);
+ plotboxplot->zoomToFit();
+ plotboxplot->setGrid(false);
+ plotboxplot->setShowZeroAxes(false);
+ plotboxplot->getPlotter()->setKeyBackgroundColor(QColorWithAlphaF("white", 0.25), Qt::SolidPattern);
+ plotbarchart->setAbsoluteY(0,5);
+ plotboxplot->setAbsoluteY(0,5);
+ plotbarchart->zoomToFit();
+ plotbarchart->setGrid(false);
+ plotbarchart->setShowZeroAxes(false);
+ plotbarchart->getPlotter()->setKeyBackgroundColor(QColorWithAlphaF("white", 0.25), Qt::SolidPattern);
+ plotbarchart->moveGraphTop(gScatterForBar);
+ plotscattererrors->zoomToFit();
+ plotscattererrors->setGrid(false);
+ plotscattererrors->setShowZeroAxes(false);
+ plotscattererrors->getPlotter()->setKeyBackgroundColor(QColorWithAlphaF("white", 0.25), Qt::SolidPattern);
+
+
+ // show plotter and make it a decent size
+ mainWidget.show();
+ mainWidget.resize(1200,400);
+
+ return app.exec();
+}
diff --git a/examples/simpletest_datastore_groupedstat/jkqtplotter_simpletest_datastore_groupedstat.pro b/examples/simpletest_datastore_groupedstat/jkqtplotter_simpletest_datastore_groupedstat.pro
new file mode 100644
index 0000000000..817ebf4752
--- /dev/null
+++ b/examples/simpletest_datastore_groupedstat/jkqtplotter_simpletest_datastore_groupedstat.pro
@@ -0,0 +1,27 @@
+# source code for this simple demo
+SOURCES = jkqtplotter_simpletest_datastore_groupedstat.cpp
+
+# configure Qt
+CONFIG += link_prl qt
+QT += core gui xml svg
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport
+
+# output executable name
+TARGET = jkqtplotter_simpletest_datastore_groupedstat
+
+# include JKQTPlotter source headers and link against library
+DEPENDPATH += ../../lib ../../staticlib/jkqtplotterlib
+INCLUDEPATH += ../../lib
+CONFIG (debug, debug|release) {
+ LIBS += -L../../staticlib/jkqtplotterlib/debug -ljkqtplotterlib_debug
+} else {
+ LIBS += -L../../staticlib/jkqtplotterlib/release -ljkqtplotterlib
+}
+message("LIBS = $$LIBS")
+
+win32-msvc*: DEFINES += _USE_MATH_DEFINES
+win32-msvc*: DEFINES += NOMINMAX
+
+
+
+
diff --git a/examples/simpletest_datastore_groupedstat/jkqtplotter_simpletest_datastore_groupedstat_and_lib.pro b/examples/simpletest_datastore_groupedstat/jkqtplotter_simpletest_datastore_groupedstat_and_lib.pro
new file mode 100644
index 0000000000..f3d7e69339
--- /dev/null
+++ b/examples/simpletest_datastore_groupedstat/jkqtplotter_simpletest_datastore_groupedstat_and_lib.pro
@@ -0,0 +1,8 @@
+TEMPLATE = subdirs
+
+SUBDIRS += jkqtplotterlib jkqtplotter_simpletest_datastore_groupedstat
+
+jkqtplotterlib.file = ../../staticlib/jkqtplotterlib/jkqtplotterlib.pro
+
+jkqtplotter_simpletest_datastore_groupedstat.file=$$PWD/jkqtplotter_simpletest_datastore_groupedstat.pro
+jkqtplotter_simpletest_datastore_groupedstat.depends = jkqtplotterlib
diff --git a/examples/simpletest_datastore_iterators/README.md b/examples/simpletest_datastore_iterators/README.md
index e9d7f6537e..407f5e0e25 100644
--- a/examples/simpletest_datastore_iterators/README.md
+++ b/examples/simpletest_datastore_iterators/README.md
@@ -1,10 +1,10 @@
# Tutorial (JKQTPDatastore): Iterator-Based usage of JKQTPDatastore {#JKQTPlotterBasicJKQTPDatastoreIterators}
-
[JKQTPlotterBasicJKQTPDatastore]: @ref JKQTPlotterBasicJKQTPDatastore "Basic Usage of JKQTPDatastore"
[JKQTPlotterBasicJKQTPDatastoreIterators]: @ref JKQTPlotterBasicJKQTPDatastoreIterators "Iterator-Based usage of JKQTPDatastore"
[JKQTPlotterBasicJKQTPDatastoreStatistics]: @ref JKQTPlotterBasicJKQTPDatastoreStatistics "Advanced 1-Dimensional Statistics with JKQTPDatastore"
[JKQTPlotterBasicJKQTPDatastoreRegression]: @ref JKQTPlotterBasicJKQTPDatastoreRegression "Regression Analysis (with the Statistics Library)"
+[JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat]: @ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat "1-Dimensional Group Statistics with JKQTPDatastore"
[JKQTPlotterBasicJKQTPDatastoreStatistics2D]: @ref JKQTPlotterBasicJKQTPDatastoreStatistics2D "Advanced 2-Dimensional Statistics with JKQTPDatastore"
[statisticslibrary]: @ref jkqtptools_math_statistics "JKQTPlotter Statistics Library"
@@ -14,8 +14,10 @@ This tutorial project (see `./examples/simpletest_datastore_iterators/`) explain
- [JKQTPlotterBasicJKQTPDatastore]
- [JKQTPlotterBasicJKQTPDatastoreIterators]
- [JKQTPlotterBasicJKQTPDatastoreStatistics]
- - [JKQTPlotterBasicJKQTPDatastoreStatistics2D]
- [JKQTPlotterBasicJKQTPDatastoreRegression]
+ - [JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat]
+ - [JKQTPlotterBasicJKQTPDatastoreStatistics2D]
+
diff --git a/examples/simpletest_datastore_regression/README.md b/examples/simpletest_datastore_regression/README.md
index 4a98a9a1b3..d7d2aab14c 100644
--- a/examples/simpletest_datastore_regression/README.md
+++ b/examples/simpletest_datastore_regression/README.md
@@ -4,18 +4,19 @@
[JKQTPlotterBasicJKQTPDatastoreIterators]: @ref JKQTPlotterBasicJKQTPDatastoreIterators "Iterator-Based usage of JKQTPDatastore"
[JKQTPlotterBasicJKQTPDatastoreStatistics]: @ref JKQTPlotterBasicJKQTPDatastoreStatistics "Advanced 1-Dimensional Statistics with JKQTPDatastore"
[JKQTPlotterBasicJKQTPDatastoreRegression]: @ref JKQTPlotterBasicJKQTPDatastoreRegression "Regression Analysis (with the Statistics Library)"
+[JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat]: @ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat "1-Dimensional Group Statistics with JKQTPDatastore"
[JKQTPlotterBasicJKQTPDatastoreStatistics2D]: @ref JKQTPlotterBasicJKQTPDatastoreStatistics2D "Advanced 2-Dimensional Statistics with JKQTPDatastore"
[statisticslibrary]: @ref jkqtptools_math_statistics "JKQTPlotter Statistics Library"
-
This tutorial project (see `./examples/simpletest_datastore_statistics/`) explains several advanced functions of JKQTPDatastore in combination with the [[statisticslibrary]] conatined in JKQTPlotter.
***Note*** that there are additional tutorial explaining other aspects of data mangement in JKQTPDatastore:
- [JKQTPlotterBasicJKQTPDatastore]
- [JKQTPlotterBasicJKQTPDatastoreIterators]
- [JKQTPlotterBasicJKQTPDatastoreStatistics]
- - [JKQTPlotterBasicJKQTPDatastoreStatistics2D]
- [JKQTPlotterBasicJKQTPDatastoreRegression]
+ - [JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat]
+ - [JKQTPlotterBasicJKQTPDatastoreStatistics2D]
[TOC]
diff --git a/examples/simpletest_datastore_statistics/README.md b/examples/simpletest_datastore_statistics/README.md
index 1addbfbb48..1bacdbb887 100644
--- a/examples/simpletest_datastore_statistics/README.md
+++ b/examples/simpletest_datastore_statistics/README.md
@@ -1,22 +1,22 @@
# Tutorial (JKQTPDatastore): Advanced 1-Dimensional Statistics with JKQTPDatastore {#JKQTPlotterBasicJKQTPDatastoreStatistics}
-
[JKQTPlotterBasicJKQTPDatastore]: @ref JKQTPlotterBasicJKQTPDatastore "Basic Usage of JKQTPDatastore"
[JKQTPlotterBasicJKQTPDatastoreIterators]: @ref JKQTPlotterBasicJKQTPDatastoreIterators "Iterator-Based usage of JKQTPDatastore"
[JKQTPlotterBasicJKQTPDatastoreStatistics]: @ref JKQTPlotterBasicJKQTPDatastoreStatistics "Advanced 1-Dimensional Statistics with JKQTPDatastore"
[JKQTPlotterBasicJKQTPDatastoreRegression]: @ref JKQTPlotterBasicJKQTPDatastoreRegression "Regression Analysis (with the Statistics Library)"
+[JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat]: @ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat "1-Dimensional Group Statistics with JKQTPDatastore"
[JKQTPlotterBasicJKQTPDatastoreStatistics2D]: @ref JKQTPlotterBasicJKQTPDatastoreStatistics2D "Advanced 2-Dimensional Statistics with JKQTPDatastore"
[statisticslibrary]: @ref jkqtptools_math_statistics "JKQTPlotter Statistics Library"
-
This tutorial project (see `./examples/simpletest_datastore_statistics/`) explains several advanced functions of JKQTPDatastore in combination with the [[statisticslibrary]] conatined in JKQTPlotter.
***Note*** that there are additional tutorial explaining other aspects of data mangement in JKQTPDatastore:
- [JKQTPlotterBasicJKQTPDatastore]
- [JKQTPlotterBasicJKQTPDatastoreIterators]
- [JKQTPlotterBasicJKQTPDatastoreStatistics]
- - [JKQTPlotterBasicJKQTPDatastoreStatistics2D]
- [JKQTPlotterBasicJKQTPDatastoreRegression]
+ - [JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat]
+ - [JKQTPlotterBasicJKQTPDatastoreStatistics2D]
[TOC]
diff --git a/examples/simpletest_datastore_statistics_2d/README.md b/examples/simpletest_datastore_statistics_2d/README.md
index 5007a28edd..124ba0d450 100644
--- a/examples/simpletest_datastore_statistics_2d/README.md
+++ b/examples/simpletest_datastore_statistics_2d/README.md
@@ -1,22 +1,22 @@
# Tutorial (JKQTPDatastore): Advanced 2-Dimensional Statistics with JKQTPDatastore {#JKQTPlotterBasicJKQTPDatastoreStatistics2D}
-
[JKQTPlotterBasicJKQTPDatastore]: @ref JKQTPlotterBasicJKQTPDatastore "Basic Usage of JKQTPDatastore"
[JKQTPlotterBasicJKQTPDatastoreIterators]: @ref JKQTPlotterBasicJKQTPDatastoreIterators "Iterator-Based usage of JKQTPDatastore"
[JKQTPlotterBasicJKQTPDatastoreStatistics]: @ref JKQTPlotterBasicJKQTPDatastoreStatistics "Advanced 1-Dimensional Statistics with JKQTPDatastore"
[JKQTPlotterBasicJKQTPDatastoreRegression]: @ref JKQTPlotterBasicJKQTPDatastoreRegression "Regression Analysis (with the Statistics Library)"
+[JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat]: @ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat "1-Dimensional Group Statistics with JKQTPDatastore"
[JKQTPlotterBasicJKQTPDatastoreStatistics2D]: @ref JKQTPlotterBasicJKQTPDatastoreStatistics2D "Advanced 2-Dimensional Statistics with JKQTPDatastore"
[statisticslibrary]: @ref jkqtptools_math_statistics "JKQTPlotter Statistics Library"
-
This tutorial project (see `./examples/simpletest_datastore_statistics_2d/`) explains several advanced functions of JKQTPDatastore in combination with the [[statisticslibrary]] conatined in JKQTPlotter.
***Note*** that there are additional tutorial explaining other aspects of data mangement in JKQTPDatastore:
- [JKQTPlotterBasicJKQTPDatastore]
- [JKQTPlotterBasicJKQTPDatastoreIterators]
- [JKQTPlotterBasicJKQTPDatastoreStatistics]
- - [JKQTPlotterBasicJKQTPDatastoreStatistics2D]
- [JKQTPlotterBasicJKQTPDatastoreRegression]
+ - [JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat]
+ - [JKQTPlotterBasicJKQTPDatastoreStatistics2D]
[TOC]
diff --git a/examples/simpletest_errorbarstyles/README.md b/examples/simpletest_errorbarstyles/README.md
index e8d28528a1..5ab4aa8ba7 100644
--- a/examples/simpletest_errorbarstyles/README.md
+++ b/examples/simpletest_errorbarstyles/README.md
@@ -1,6 +1,11 @@
# Example (JKQTPlotter): Different Types of Errorindicators {#JKQTPlotterErrorBarStyles}
This project (see `./examples/simpletest_errorbarstyles/`) simply creates a JKQTPlotter widget (as a new window) and adds several curves show-casing different styles of error indicators. Data is initialized from two QVector objects.
+[JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat]: @ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat "1-Dimensional Group Statistics with JKQTPDatastore"
+[statisticslibrary]: @ref jkqtptools_math_statistics "JKQTPlotter Statistics Library"
+
+***Note:*** This examples explains how to plot graphs with error indicators, when the data has already been calculated. The tutorial [JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat] explains one way how to use the [statisticslibrary] in order to calculate the errors from data.
+
The source code of the main application can be found in [`jkqtplotter_simpletest_errorbarstyles.cpp`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_errorbarstyles/jkqtplotter_simpletest_errorbarstyles.cpp).
First some data is added to the internal datastore (mostly, like explained in several other examples, like e.g. [Line Graph with Different Symbols and Line Styles](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_symbols_and_styles)). The (in a loop) several graphs are added, each with a distinct style for its error indicators:
diff --git a/examples/test_distributionplot/README.md b/examples/test_distributionplot/README.md
index ffaca77491..c833b9b974 100644
--- a/examples/test_distributionplot/README.md
+++ b/examples/test_distributionplot/README.md
@@ -1,6 +1,19 @@
# Example (JKQTPlotter): Plotting a Statistical Distribution of Data {#JKQTPlotterDistributionPlot}
This project (see [`test_distributionplot`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/test_distributionplot) demonstrates how to combine several different graphs and geometric elements to show a set of random values and their statistics.
+
+[JKQTPlotterBasicJKQTPDatastore]: @ref JKQTPlotterBasicJKQTPDatastore "Basic Usage of JKQTPDatastore"
+[JKQTPlotterBasicJKQTPDatastoreIterators]: @ref JKQTPlotterBasicJKQTPDatastoreIterators "Iterator-Based usage of JKQTPDatastore"
+[JKQTPlotterBasicJKQTPDatastoreStatistics]: @ref JKQTPlotterBasicJKQTPDatastoreStatistics "Advanced 1-Dimensional Statistics with JKQTPDatastore"
+[JKQTPlotterBasicJKQTPDatastoreRegression]: @ref JKQTPlotterBasicJKQTPDatastoreRegression "Regression Analysis (with the Statistics Library)"
+[JKQTPlotterBasicJKQTPDatastoreStatistics2D]: @ref JKQTPlotterBasicJKQTPDatastoreStatistics2D "Advanced 2-Dimensional Statistics with JKQTPDatastore"
+[statisticslibrary]: @ref jkqtptools_math_statistics "JKQTPlotter Statistics Library"
+[JKQTPlotterBoxplotStyling]: @ref JKQTPlotterBoxplotStyling "Styling different aspects of boxplots"
+[JKQTPlotterBoxplotsGraphs]: @ref JKQTPlotterBoxplotsGraphs "Boxplots"
+
+***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 [statisticslibrary] offers methods to perform these calculations, which are explained in the tutorial [JKQTPlotterBasicJKQTPDatastoreStatistics] in detail. Several examples give more details on boxplots: [JKQTPlotterBoxplotsGraphs], [JKQTPlotterBoxplotStyling].
+
+
The source code of the main application is (see [`test_distributionplot.cpp`](test_distributionplot.cpp).
After adding all necessary data to the JKQTDatastore:
diff --git a/examples/test_styledboxplot/README.md b/examples/test_styledboxplot/README.md
index 6b967df6fe..0c8a782e64 100644
--- a/examples/test_styledboxplot/README.md
+++ b/examples/test_styledboxplot/README.md
@@ -1,6 +1,19 @@
# Example (JKQTPlotter): Styling different aspects of boxplots {#JKQTPlotterBoxplotStyling}
This project (see [`test_styledboxplot`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/test_styledboxplot) demonstrates how to style different aspects of boxplots and how to draw different types and styles of boxplots. For a simple introduction into how to use boxplots, see [Plotting Box Plots](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_boxplot) and [Plotting a Statistical Distribution of Data](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/test_distributionplot).
+[JKQTPlotterBasicJKQTPDatastore]: @ref JKQTPlotterBasicJKQTPDatastore "Basic Usage of JKQTPDatastore"
+[JKQTPlotterBasicJKQTPDatastoreIterators]: @ref JKQTPlotterBasicJKQTPDatastoreIterators "Iterator-Based usage of JKQTPDatastore"
+[JKQTPlotterBasicJKQTPDatastoreStatistics]: @ref JKQTPlotterBasicJKQTPDatastoreStatistics "Advanced 1-Dimensional Statistics with JKQTPDatastore"
+[JKQTPlotterBasicJKQTPDatastoreRegression]: @ref JKQTPlotterBasicJKQTPDatastoreRegression "Regression Analysis (with the Statistics Library)"
+[JKQTPlotterBasicJKQTPDatastoreStatistics2D]: @ref JKQTPlotterBasicJKQTPDatastoreStatistics2D "Advanced 2-Dimensional Statistics with JKQTPDatastore"
+[statisticslibrary]: @ref jkqtptools_math_statistics "JKQTPlotter Statistics Library"
+[JKQTPlotterBoxplotStyling]: @ref JKQTPlotterBoxplotStyling "Styling different aspects of boxplots"
+[JKQTPlotterBoxplotsGraphs]: @ref JKQTPlotterBoxplotsGraphs "Boxplots"
+
+***Note*** that this example explains how to style boxplots. The example [JKQTPlotterBoxplotsGraphs] explains basics of how to create boxplots. The internal [statisticslibrary] offers methods to calculate the statistical properties necessary for boxplots, which is explained in the tutorial [JKQTPlotterBasicJKQTPDatastoreStatistics] in detail.
+
+
+
The link http://vita.had.co.nz/papers/boxplots.pdf leads to a paper that described the history and different types of boxplots.
The source code of the main application can be found in [`test_styledboxplot.cpp`](test_styledboxplot.cpp).
diff --git a/lib/jkqtcommon/jkqtpstatbasics.h b/lib/jkqtcommon/jkqtpstatbasics.h
index 4021f38220..9ecf319ccd 100644
--- a/lib/jkqtcommon/jkqtpstatbasics.h
+++ b/lib/jkqtcommon/jkqtpstatbasics.h
@@ -40,9 +40,6 @@
#include "jkqtcommon/jkqtpdebuggingtools.h"
-
-
-
/*! \brief calculates the average of a given data range \a first ... \a last
\ingroup jkqtptools_math_statistics_basic
@@ -78,6 +75,8 @@ inline double jkqtpstatAverage(InputIt first, InputIt last, size_t* Noutput=null
+
+
/*! \brief calculates the weighted average of a given data range \a first ... \a last
\ingroup jkqtptools_math_statistics_basic
diff --git a/lib/jkqtcommon/jkqtpstatisticstools.cpp b/lib/jkqtcommon/jkqtpstatgrouped.cpp
similarity index 58%
rename from lib/jkqtcommon/jkqtpstatisticstools.cpp
rename to lib/jkqtcommon/jkqtpstatgrouped.cpp
index d9fccf079c..422ad0eadf 100644
--- a/lib/jkqtcommon/jkqtpstatisticstools.cpp
+++ b/lib/jkqtcommon/jkqtpstatgrouped.cpp
@@ -19,4 +19,22 @@
-#include "jkqtpstatisticstools.h"
+#include "jkqtpstatgrouped.h"
+
+double jkqtpstatGroupingIdentity1D(double v) {
+ return v;
+}
+
+double jkqtpstatGroupingRound1D(double v) {
+ return round(v);
+}
+
+double jkqtpstatGroupingCustomRound1D(double v, double firstGroupCenter, double groupWidth) {
+ return round((v-firstGroupCenter)/(2.0*groupWidth));
+}
+
+
+JKQTPStatGroupDefinitionFunctor1D jkqtpstatMakeGroupingCustomRound1D(double firstGroupCenter, double groupWidth)
+{
+ return std::bind(&jkqtpstatGroupingCustomRound1D, std::placeholders::_1, firstGroupCenter, groupWidth);
+}
diff --git a/lib/jkqtcommon/jkqtpstatgrouped.h b/lib/jkqtcommon/jkqtpstatgrouped.h
new file mode 100644
index 0000000000..4009a15e40
--- /dev/null
+++ b/lib/jkqtcommon/jkqtpstatgrouped.h
@@ -0,0 +1,237 @@
+/*
+ Copyright (c) 2008-2019 Jan W. Krieger ()
+
+ last modification: $LastChangedDate$ (revision $Rev$)
+
+ This software is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License (LGPL) as published by
+ the Free Software Foundation, either version 2.1 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License (LGPL) for more details.
+
+ You should have received a copy of the GNU Lesser General Public License (LGPL)
+ along with this program. If not, see .
+*/
+
+
+#ifndef JKQTPSTATGROUPED_H_INCLUDED
+#define JKQTPSTATGROUPED_H_INCLUDED
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "jkqtcommon/jkqtp_imexport.h"
+#include "jkqtcommon/jkqtplinalgtools.h"
+#include "jkqtcommon/jkqtparraytools.h"
+#include "jkqtcommon/jkqtpdebuggingtools.h"
+#include "jkqtcommon/jkqtpstatbasics.h"
+
+/*! \brief a functor \f$ f(x): \mathbb{R}\rightarrow\mathbb{R} \f$ which assignes a value \f$ x \f$ to a group center \f$ f(x) \f$
+ \ingroup jkqtptools_math_statistics_grouped
+
+ The simplest version are e.g.
+ - jkqtpstatGroupingIdentity1D()
+ - jkqtpstatGroupingRound1D()
+ - jkqtpstatGroupingCustomRound1D()
+ .
+
+ \see jkqtpstatGroupData
+*/
+typedef std::function JKQTPStatGroupDefinitionFunctor1D;
+
+
+
+/*! \brief use a column value as group ID directly
+ \ingroup jkqtptools_math_statistics_grouped
+
+ \see JKQTPStatGroupDefinitionFunctor1D
+*/
+double jkqtpstatGroupingIdentity1D(double v);
+/*! \brief use a rounded column value as group ID directly \f$ f(x)=\mbox{round}(x) \f$
+ \ingroup jkqtptools_math_statistics_grouped
+
+ \see JKQTPStatGroupDefinitionFunctor1D
+*/
+double jkqtpstatGroupingRound1D(double v);
+/*! \brief assign each value to groups \f$ \mbox{firstGroupCenter}, \mbox{firstGroupCenter}\pm\mbox{groupWidth}/2, \mbox{firstGroupCenter}\pm2\cdot\mbox{groupWidth}/2, , \mbox{firstGroupCenter}\pm3\cdot\mbox{groupWidth}/2, ... \f$
+ \ingroup jkqtptools_math_statistics_grouped
+
+ This is equivalent to \f$ \mbox{round}\left(\frac{x-\mbox{firstGroupCenter}}{\mbox{groupWidth}/2}\right) \f$
+
+ \see JKQTPStatGroupDefinitionFunctor1D, jkqtpstatMakeGroupingCustomRound1D() for a factory-function that returns a functor of this function bound to specific arguments.
+*/
+double jkqtpstatGroupingCustomRound1D(double v, double firstGroupCenter, double groupWidth);
+/*! \brief generates a functor of jkqtpstatGroupingCustomRound1D() with the two paramaters \a firstGroupCenter and \a groupWidth fixed to the given values
+ \ingroup jkqtptools_math_statistics_grouped
+
+ This is equivalent to \c std::bind(&jkqtpstatGroupingCustomRound1D,std::placeholders::_1,firstGroupCenter,groupWidth);
+
+ \see JKQTPStatGroupDefinitionFunctor1D, jkqtpstatGroupingCustomRound1D()
+*/
+JKQTPStatGroupDefinitionFunctor1D jkqtpstatMakeGroupingCustomRound1D(double firstGroupCenter, double groupWidth);
+
+
+
+/*! \brief groups data from an input range \a inFirstCat / \a inFirstValue ... \a inLastCat / \a outFirstCat representing pairs \f$ (c_i,v_i) \f$ of a
+ category value \f$ c_i \f$ and a group value \f$ v_i \f$ into groups \f$ V_j=\{v_{i}|c_i\equiv c_{\text{out},j}\} \f$ of data that were assigned
+ to the same group, i.e. \f$ c_i\equiv c_{\text{out},j} \f$ . A functor \a groupDefFunc assigns a group \f$ c_{\text{out},j} \f$ to each category value \f$ c_i \f$ .
+ \ingroup jkqtptools_math_statistics_grouped
+
+ \tparam InputCatIt standard iterator type of \a inFirstCat and \a inLastCat
+ \tparam InputValueIt standard iterator type of \a inFirstValue and \a inLastValue
+ \param inFirstCat iterator pointing to the first item in the category dataset to use \f$ c_1 \f$
+ \param inLastCat iterator pointing behind the last item in the category dataset to use \f$ c_N \f$
+ \param inFirstValue iterator pointing to the first item in the category dataset to use \f$ v_1 \f$
+ \param inLastValue iterator pointing behind the last item in the category dataset to use \f$ v_N \f$
+ \param[out] groupeddata receives the grouped data, each key in the map represents one group, each map-value contains a vector with the value data
+ \param groupDefFunc assigns a group \f$ c_{\text{out},j} \f$ to each category value \f$ c_i \f$ .
+
+ \note the contents of \a groupeddata is not cleared before usage, so you can also use this fucntion to append to a group!
+
+ \see JKQTPStatGroupDefinitionFunctor1D, \ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat
+*/
+template
+inline void jkqtpstatGroupData(InputCatIt inFirstCat, InputCatIt inLastCat, InputValueIt inFirstValue, InputValueIt inLastValue, std::map >& groupeddata, JKQTPStatGroupDefinitionFunctor1D groupDefFunc=&jkqtpstatGroupingIdentity1D) {
+ auto inCat=inFirstCat;
+ auto inVal=inFirstValue;
+ for (; inCat!=inLastCat && inVal!=inLastValue; ++inCat, ++inVal) {
+ const double c=jkqtp_todouble(*inCat);
+ const double v=jkqtp_todouble(*inVal);
+ if (JKQTPIsOKFloat(c) && JKQTPIsOKFloat(v)) {
+ const double g=groupDefFunc(c);
+ groupeddata[g].push_back(v);
+ }
+ }
+}
+
+/*! \brief groups data from an input range \a inFirstCat / \a inFirstValue ... \a inLastCat / \a outFirstCat representing pairs \f$ (c_i,v_i) \f$ of a
+ category value \f$ c_i \f$ and a group value \f$ v_i \f$ into groups \f$ V_j=\{v_{i}|c_i\equiv c_{\text{out},j}\} \f$ of data that were assigned
+ to the same group, i.e. \f$ c_i\equiv c_{\text{out},j} \f$ . A functor \a groupDefFunc assigns a group \f$ c_{\text{out},j} \f$ to each category value \f$ c_i \f$ .
+ \ingroup jkqtptools_math_statistics_grouped
+
+ \tparam InputCatIt standard iterator type of \a inFirstCat and \a inLastCat
+ \tparam InputValueIt standard iterator type of \a inFirstValue and \a inLastValue
+ \tparam OutputGroupIt standard output iterator type of \a outFirstCategory
+ \param inFirstCat iterator pointing to the first item in the category dataset to use \f$ c_1 \f$
+ \param inLastCat iterator pointing behind the last item in the category dataset to use \f$ c_N \f$
+ \param inFirstValue iterator pointing to the first item in the category dataset to use \f$ v_1 \f$
+ \param inLastValue iterator pointing behind the last item in the category dataset to use \f$ v_N \f$
+ \param[out] outFirstCategory for each element in the range \a inFirstCat / \a inFirstValue ... \a inLastCat / \a outFirstCat this receives the calculated category
+ \param[out] groupeddata receives the grouped data, each key in the map represents one group, each map-value contains a vector with the value data
+ \param groupDefFunc assigns a group \f$ c_{\text{out},j} \f$ to each category value \f$ c_i \f$ .
+
+ \note the contents of \a groupeddata is not cleared before usage, so you can also use this fucntion to append to a group!
+
+ \see JKQTPStatGroupDefinitionFunctor1D, \ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat
+*/
+template
+inline void jkqtpstatGroupData(InputCatIt inFirstCat, InputCatIt inLastCat, InputValueIt inFirstValue, InputValueIt inLastValue, OutputGroupIt outFirstCategory, std::map >& groupeddata, JKQTPStatGroupDefinitionFunctor1D groupDefFunc=&jkqtpstatGroupingIdentity1D) {
+ auto inCat=inFirstCat;
+ auto inVal=inFirstValue;
+ auto outCat=outFirstCategory;
+ for (; inCat!=inLastCat && inVal!=inLastValue; ++inCat, ++inVal) {
+ const double c=jkqtp_todouble(*inCat);
+ const double v=jkqtp_todouble(*inVal);
+ if (JKQTPIsOKFloat(c) && JKQTPIsOKFloat(v)) {
+ const double g=groupDefFunc(c);
+ groupeddata[g].push_back(v);
+ *outCat=g;
+ } else {
+ *outCat=JKQTP_DOUBLE_NAN;
+ }
+ ++outCat;
+ }
+}
+
+
+/*! \brief groups data from an input range \a inFirstCat / \a inFirstValue ... \a inLastCat / \a outFirstCat representing pairs \f$ (c_i,v_i) \f$ of a
+ category value \f$ c_i \f$ and a group value \f$ v_i \f$ into groups \f$ V_j=\{v_{i}|c_i\equiv c_{\text{out},j}\} \f$ of data that were assigned
+ to the same group, i.e. \f$ c_i\equiv c_{\text{out},j} \f$ . A functor \a groupDefFunc assigns a group \f$ c_{\text{out},j} \f$ to each category value \f$ c_i \f$ .
+ \ingroup jkqtptools_math_statistics_grouped
+
+ \tparam InputCatIt standard iterator type of \a inFirstCat and \a inLastCat
+ \tparam InputValueIt standard iterator type of \a inFirstValue and \a inLastValue
+ \param inFirstCat iterator pointing to the first item in the category dataset to use \f$ c_1 \f$
+ \param inLastCat iterator pointing behind the last item in the category dataset to use \f$ c_N \f$
+ \param inFirstValue iterator pointing to the first item in the category dataset to use \f$ v_1 \f$
+ \param inLastValue iterator pointing behind the last item in the category dataset to use \f$ v_N \f$
+ \param[out] groupeddata receives the grouped data, each key in the map represents one group, each map-value contains two vecors with the category and value data respectively
+ \param groupDefFunc assigns a group \f$ c_{\text{out},j} \f$ to each category value \f$ c_i \f$ .
+
+ \note the contents of \a groupeddata is not cleared before usage, so you can also use this fucntion to append to a group!
+
+ \see JKQTPStatGroupDefinitionFunctor1D, \ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat
+*/
+template
+inline void jkqtpstatGroupData(InputCatIt inFirstCat, InputCatIt inLastCat, InputValueIt inFirstValue, InputValueIt inLastValue, std::map,std::vector > >& groupeddata, JKQTPStatGroupDefinitionFunctor1D groupDefFunc=&jkqtpstatGroupingIdentity1D) {
+ auto inCat=inFirstCat;
+ auto inVal=inFirstValue;
+ for (; inCat!=inLastCat && inVal!=inLastValue; ++inCat, ++inVal) {
+ const double c=jkqtp_todouble(*inCat);
+ const double v=jkqtp_todouble(*inVal);
+ if (JKQTPIsOKFloat(c) && JKQTPIsOKFloat(v)) {
+ const double g=groupDefFunc(c);
+ groupeddata[g].first.push_back(c);
+ groupeddata[g].second.push_back(v);
+ }
+ }
+}
+
+
+/*! \brief groups data from an input range \a inFirstCat / \a inFirstValue ... \a inLastCat / \a outFirstCat representing pairs \f$ (c_i,v_i) \f$ of a
+ category value \f$ c_i \f$ and a group value \f$ v_i \f$ into groups \f$ V_j=\{v_{i}|c_i\equiv c_{\text{out},j}\} \f$ of data that were assigned
+ to the same group, i.e. \f$ c_i\equiv c_{\text{out},j} \f$ . A functor \a groupDefFunc assigns a group \f$ c_{\text{out},j} \f$ to each category value \f$ c_i \f$ .
+ \ingroup jkqtptools_math_statistics_grouped
+
+ \tparam InputCatIt standard iterator type of \a inFirstCat and \a inLastCat
+ \tparam InputValueIt standard iterator type of \a inFirstValue and \a inLastValue
+ \tparam OutputGroupIt standard output iterator type of \a outFirstCategory
+ \param inFirstCat iterator pointing to the first item in the category dataset to use \f$ c_1 \f$
+ \param inLastCat iterator pointing behind the last item in the category dataset to use \f$ c_N \f$
+ \param inFirstValue iterator pointing to the first item in the category dataset to use \f$ v_1 \f$
+ \param inLastValue iterator pointing behind the last item in the category dataset to use \f$ v_N \f$
+ \param[out] outFirstCategory for each element in the range \a inFirstCat / \a inFirstValue ... \a inLastCat / \a outFirstCat this receives the calculated category
+ \param[out] groupeddata receives the grouped data, each key in the map represents one group, each map-value contains two vecors with the category and value data respectively
+ \param groupDefFunc assigns a group \f$ c_{\text{out},j} \f$ to each category value \f$ c_i \f$ .
+
+ \note the contents of \a groupeddata is not cleared before usage, so you can also use this fucntion to append to a group!
+
+ \see JKQTPStatGroupDefinitionFunctor1D, \ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat
+*/
+template
+inline void jkqtpstatGroupData(InputCatIt inFirstCat, InputCatIt inLastCat, InputValueIt inFirstValue, InputValueIt inLastValue, OutputGroupIt outFirstCategory, std::map,std::vector > >& groupeddata, JKQTPStatGroupDefinitionFunctor1D groupDefFunc=&jkqtpstatGroupingIdentity1D) {
+ auto inCat=inFirstCat;
+ auto inVal=inFirstValue;
+ auto outCat=outFirstCategory;
+ for (; inCat!=inLastCat && inVal!=inLastValue; ++inCat, ++inVal) {
+ const double c=jkqtp_todouble(*inCat);
+ const double v=jkqtp_todouble(*inVal);
+ if (JKQTPIsOKFloat(c) && JKQTPIsOKFloat(v)) {
+ const double g=groupDefFunc(c);
+ groupeddata[g].first.push_back(c);
+ groupeddata[g].second.push_back(v);
+ *outCat=g;
+ } else {
+ *outCat=JKQTP_DOUBLE_NAN;
+ }
+ ++outCat;
+ }
+}
+
+#endif // JKQTPSTATGROUPED_H_INCLUDED
+
+
diff --git a/lib/jkqtcommon/jkqtpstatisticstools.h b/lib/jkqtcommon/jkqtpstatisticstools.h
index 3469177546..bc2f4527c0 100644
--- a/lib/jkqtcommon/jkqtpstatisticstools.h
+++ b/lib/jkqtcommon/jkqtpstatisticstools.h
@@ -27,6 +27,7 @@
#include "jkqtcommon/jkqtpstatkde.h"
#include "jkqtcommon/jkqtpstatpoly.h"
#include "jkqtcommon/jkqtpstatregression.h"
+#include "jkqtcommon/jkqtpstatgrouped.h"
#endif // JKQTPSTATISTICSTOOLS_H_INCLUDED
diff --git a/lib/jkqtcommon/jkqtpstatpoly.h b/lib/jkqtcommon/jkqtpstatpoly.h
index c2186918d1..d5f0774793 100644
--- a/lib/jkqtcommon/jkqtpstatpoly.h
+++ b/lib/jkqtcommon/jkqtpstatpoly.h
@@ -46,7 +46,6 @@
/*! \brief fits (in a least-squares sense) a polynomial \f$ f(x)=\sum\limits_{i=0}^Pp_ix^i \f$ of order P to a set of N data pairs \f$ (x_i,y_i) \f$
\ingroup jkqtptools_math_statistics_poly
- \ingroup jkqtptools_math_statistics_regression
\tparam InputItX standard iterator type of \a firstX and \a lastX.
\tparam InputItY standard iterator type of \a firstY and \a lastY.
diff --git a/lib/jkqtpcommon.pri b/lib/jkqtpcommon.pri
index 694a89ba68..e13646c465 100644
--- a/lib/jkqtpcommon.pri
+++ b/lib/jkqtpcommon.pri
@@ -35,7 +35,9 @@ isEmpty(JKQTP_COMMON_PRI_INCLUDED) {
$$PWD/jkqtcommon/jkqtpstathistogram.h \
$$PWD/jkqtcommon/jkqtpstatkde.h \
$$PWD/jkqtcommon/jkqtpstatregression.h \
- $$PWD/jkqtcommon/jkqtpstatpoly.h
+ $$PWD/jkqtcommon/jkqtpstatpoly.h \
+ $$PWD/jkqtcommon/jkqtpstatgrouped.h
+
SOURCES += $$PWD/jkqtcommon/jkqtpdebuggingtools.cpp \
@@ -51,12 +53,12 @@ isEmpty(JKQTP_COMMON_PRI_INCLUDED) {
$$PWD/jkqtcommon/jkqtpmathparser.cpp \
$$PWD/jkqtcommon/jkqttools.cpp \
$$PWD/jkqtcommon/jkqtparraytools.cpp \
- $$PWD/jkqtcommon/jkqtpstatisticstools.cpp \
$$PWD/jkqtcommon/jkqtpstatbasics.cpp \
$$PWD/jkqtcommon/jkqtpstathistogram.cpp \
$$PWD/jkqtcommon/jkqtpstatkde.cpp \
$$PWD/jkqtcommon/jkqtpstatregression.cpp \
- $$PWD/jkqtcommon/jkqtpstatpoly.cpp
+ $$PWD/jkqtcommon/jkqtpstatpoly.cpp \
+ $$PWD/jkqtcommon/jkqtpstatgrouped.cpp
INCLUDEPATH += $$PWD
diff --git a/lib/jkqtplotter/jkqtpgraphsbarchart.h b/lib/jkqtplotter/jkqtpgraphsbarchart.h
index ae64ac2daa..dd439061f0 100644
--- a/lib/jkqtplotter/jkqtpgraphsbarchart.h
+++ b/lib/jkqtplotter/jkqtpgraphsbarchart.h
@@ -54,7 +54,7 @@
You can use JKQTPlotter::addHorizontalBargraph() to add a series of bargraphs, where the width and shift are determined
automatically. The y-columns are given as a QVector to this function.
-
+ \see JKQTPBarHorizontalGraph, \ref JKQTPlotterBarcharts, jkqtpstatAddHHistogram1D(), jkqtpstatAddHHistogram1DAutoranged()
*/
class JKQTP_LIB_EXPORT JKQTPBarVerticalGraph: public JKQTPXYGraph, public JKQTPGraphLineStyleMixin, public JKQTPGraphFillStyleMixin {
Q_OBJECT
@@ -173,6 +173,7 @@ class JKQTP_LIB_EXPORT JKQTPBarVerticalGraph: public JKQTPXYGraph, public JKQTPG
* Draw stacked barcharts by connecting several plots by calling \c setStackedParent(belowPlot) for each plot
* \image html JKQTPBarVerticalGraphStacked.png
*
+ * \see JKQTPBarVerticalGraph, \ref JKQTPlotterStackedBarChart
*/
class JKQTP_LIB_EXPORT JKQTPBarVerticalStackableGraph: public JKQTPBarVerticalGraph {
Q_OBJECT
@@ -212,6 +213,7 @@ class JKQTP_LIB_EXPORT JKQTPBarVerticalStackableGraph: public JKQTPBarVerticalGr
* This works much the same as JKQTPBarHorizontalGraph. Here is an example output:
* \image html plot_bargraphverploterr.png
*
+ * \see jkqtpstatAddYErrorBarGraph(), JKQTPBarVerticalGraph, \ref JKQTPlotterBarcharts
*/
class JKQTP_LIB_EXPORT JKQTPBarVerticalErrorGraph: public JKQTPBarVerticalGraph, public JKQTPYGraphErrors {
Q_OBJECT
@@ -241,8 +243,11 @@ class JKQTP_LIB_EXPORT JKQTPBarVerticalErrorGraph: public JKQTPBarVerticalGraph,
\ingroup jkqtplotter_barssticks
This works much the same as JKQTPBarHorizontalGraph. Here is an example output:
+
\image html plot_bargraphhorplot.png
+
+ \see \ref JKQTPlotterBarcharts, jkqtpstatAddVHistogram1D(), jkqtpstatAddVHistogram1DAutoranged()
*/
class JKQTP_LIB_EXPORT JKQTPBarHorizontalGraph: public JKQTPBarVerticalGraph {
Q_OBJECT
@@ -279,6 +284,8 @@ class JKQTP_LIB_EXPORT JKQTPBarHorizontalGraph: public JKQTPBarVerticalGraph {
* Draw stacked barcharts by connecting several plots by calling \c setStackedParent(belowPlot) for each plot
* \image html JKQTPBarHorizontalGraphStacked.png
*
+ *
+ * \see JKQTPBarHorizontalGraph, \ref JKQTPlotterStackedBarChart
*/
class JKQTP_LIB_EXPORT JKQTPBarHorizontalStackableGraph: public JKQTPBarHorizontalGraph {
Q_OBJECT
@@ -318,6 +325,8 @@ class JKQTP_LIB_EXPORT JKQTPBarHorizontalStackableGraph: public JKQTPBarHorizont
* This works much the same as JKQTPBarHorizontalGraph. Here is an example output:
* \image html plot_bargraphhorploterr.png
*
+ * \see jkqtpstatAddXErrorBarGraph(), JKQTPBarHorizontalGraph, \ref JKQTPlotterBarcharts
+ *
*/
class JKQTP_LIB_EXPORT JKQTPBarHorizontalErrorGraph: public JKQTPBarHorizontalGraph, public JKQTPXGraphErrors {
Q_OBJECT
diff --git a/lib/jkqtplotter/jkqtpgraphsboxplot.h b/lib/jkqtplotter/jkqtpgraphsboxplot.h
index 0c2e14e052..386575201a 100644
--- a/lib/jkqtplotter/jkqtpgraphsboxplot.h
+++ b/lib/jkqtplotter/jkqtpgraphsboxplot.h
@@ -95,7 +95,7 @@
graphOutliers->setSymbolSize(7);
\endcode
- \see \ref JKQTPlotterBoxplotsGraphs
+ \see \ref JKQTPlotterBoxplotsGraphs, jkqtpstatVAddBoxplots(),\ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat, \ref JKQTPlotterBasicJKQTPDatastoreStatistics, \ref JKQTPlotterBoxplotStyling
*/
class JKQTP_LIB_EXPORT JKQTPBoxplotVerticalGraph: public JKQTPGraph, public JKQTPGraphBoxplotStyleMixin {
@@ -252,7 +252,7 @@ class JKQTP_LIB_EXPORT JKQTPBoxplotVerticalGraph: public JKQTPGraph, public JKQT
\note See the documentation of JKQTPBoxplotVerticalGraph for details on the properties of this class!
- \see JKQTPBoxplotVerticalGraph \ref JKQTPlotterBoxplotsGraphs
+ \see JKQTPBoxplotVerticalGraph \ref JKQTPlotterBoxplotsGraphs, jkqtpstatHAddBoxplots(), \ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat, \ref JKQTPlotterBasicJKQTPDatastoreStatistics, \ref JKQTPlotterBoxplotStyling
*/
class JKQTP_LIB_EXPORT JKQTPBoxplotHorizontalGraph: public JKQTPBoxplotVerticalGraph {
@@ -306,6 +306,8 @@ class JKQTP_LIB_EXPORT JKQTPBoxplotHorizontalGraph: public JKQTPBoxplotVerticalG
\image html test_styledboxplot.png
+ \see jkqtpstatVAddBoxplot(), \ref JKQTPlotterBasicJKQTPDatastoreStatistics, \ref JKQTPlotterBoxplotsGraphs, \ref JKQTPlotterBoxplotStyling, jkqtpstatAddVBoxplotAndOutliers()
+
*/
class JKQTP_LIB_EXPORT JKQTPBoxplotVerticalElement: public JKQTPPlotObject, public JKQTPGraphBoxplotStyleMixin {
Q_OBJECT
@@ -428,7 +430,8 @@ class JKQTP_LIB_EXPORT JKQTPBoxplotVerticalElement: public JKQTPPlotObject, publ
\note See JKQTPBoxplotVerticalElement for a detailed documentation
- \see JKQTPBoxplotVerticalElement
+ \see JKQTPBoxplotVerticalElement, jkqtpstatHAddBoxplot(), \ref JKQTPlotterBasicJKQTPDatastoreStatistics, \ref JKQTPlotterBoxplotsGraphs, \ref JKQTPlotterBoxplotStyling, jkqtpstatAddHBoxplotAndOutliers()
+
*/
class JKQTP_LIB_EXPORT JKQTPBoxplotHorizontalElement: public JKQTPBoxplotVerticalElement {
Q_OBJECT
diff --git a/lib/jkqtplotter/jkqtpgraphscontour.h b/lib/jkqtplotter/jkqtpgraphscontour.h
index 9a4432a283..f415cfdc3c 100644
--- a/lib/jkqtplotter/jkqtpgraphscontour.h
+++ b/lib/jkqtplotter/jkqtpgraphscontour.h
@@ -247,6 +247,8 @@ class JKQTP_LIB_EXPORT JKQTPContourPlot: public JKQTPMathImage, public JKQTPGrap
* \ingroup jkqtplotter_imagelots_contour
*
* \copydetails JKQTPContourPlot
+ *
+ * \see jkqtpstatAddKDE2DContour(), jkqtpstatAddHistogram2DContour(), \ref JKQTPlotterContourPlot, \ref JKQTPlotterBasicJKQTPDatastoreStatistics2D
*/
class JKQTP_LIB_EXPORT JKQTPColumnContourPlot: public JKQTPContourPlot {
Q_OBJECT
diff --git a/lib/jkqtplotter/jkqtpgraphsevaluatedfunction.h b/lib/jkqtplotter/jkqtpgraphsevaluatedfunction.h
index 4a35becef0..beb07a4129 100644
--- a/lib/jkqtplotter/jkqtpgraphsevaluatedfunction.h
+++ b/lib/jkqtplotter/jkqtpgraphsevaluatedfunction.h
@@ -65,6 +65,8 @@ typedef std::function jkqtpSimplePlotFunctionType;
the following image
\image html plot_functionplots.png
+
+ \see \ref JKQTPlotterFunctionPlots, jkqtpstatAddPolyFit(), jkqtpstatAddWeightedRegression(), jkqtpstatAddRobustIRLSRegression(), jkqtpstatAddRegression(), jkqtpstatAddLinearWeightedRegression(), jkqtpstatAddRobustIRLSLinearRegression(), jkqtpstatAddLinearRegression()
*/
class JKQTP_LIB_EXPORT JKQTPXFunctionLineGraph: public JKQTPGraph, public JKQTPGraphLineStyleMixin, public JKQTPGraphFillStyleMixin {
Q_OBJECT
@@ -392,6 +394,7 @@ class JKQTP_LIB_EXPORT JKQTPXFunctionLineGraph: public JKQTPGraph, public JKQTPG
/*! \brief This implements line plots where the data is taken from a user supplied function \f$ x=f(y) \f$
\ingroup jkqtplotter_functiongraphs
+ \see \ref JKQTPlotterFunctionPlots
*/
class JKQTP_LIB_EXPORT JKQTPYFunctionLineGraph: public JKQTPXFunctionLineGraph {
Q_OBJECT
diff --git a/lib/jkqtplotter/jkqtpgraphsfilledcurve.h b/lib/jkqtplotter/jkqtpgraphsfilledcurve.h
index 95b4e71346..c43b3dbbb1 100644
--- a/lib/jkqtplotter/jkqtpgraphsfilledcurve.h
+++ b/lib/jkqtplotter/jkqtpgraphsfilledcurve.h
@@ -54,7 +54,7 @@ class JKQTP_LIB_EXPORT JKQTPFilledCurveXGraph: public JKQTPSpecialLineHorizontal
\image html plot_filledcurvexerrorplots.png
- \see \ref JKQTPlotterFilledGraphs
+ \see \ref JKQTPlotterFilledGraphs, jkqtpstatAddXErrorFilledCurveGraph()
*/
class JKQTP_LIB_EXPORT JKQTPFilledCurveXErrorGraph: public JKQTPFilledCurveXGraph, public JKQTPYGraphErrors {
Q_OBJECT
@@ -103,7 +103,7 @@ class JKQTP_LIB_EXPORT JKQTPFilledCurveYGraph: public JKQTPSpecialLineVerticalGr
\image html plot_filledcurveyerrorplots.png
- \see \ref JKQTPlotterFilledGraphs
+ \see \ref JKQTPlotterFilledGraphs, jkqtpstatAddYErrorFilledCurveGraph()
*/
class JKQTP_LIB_EXPORT JKQTPFilledCurveYErrorGraph: public JKQTPFilledCurveYGraph, public JKQTPXGraphErrors {
Q_OBJECT
diff --git a/lib/jkqtplotter/jkqtpgraphsimage.h b/lib/jkqtplotter/jkqtpgraphsimage.h
index 05bf86ab0d..57d8a5655e 100644
--- a/lib/jkqtplotter/jkqtpgraphsimage.h
+++ b/lib/jkqtplotter/jkqtpgraphsimage.h
@@ -334,6 +334,8 @@ class JKQTP_LIB_EXPORT JKQTPMathImageBase: public JKQTPImageBase {
\ingroup jkqtplotter_imagelots_elements
\image html jkqtplotter_simpletest_rgbimageplot_qt.png
+
+ \see \ref JKQTPlotterImagePlotQImageRGB
*/
class JKQTP_LIB_EXPORT JKQTPImage: public JKQTPImageBase {
Q_OBJECT
@@ -467,6 +469,8 @@ class JKQTP_LIB_EXPORT JKQTPImage: public JKQTPImageBase {
\image html jkqtplotter_simpletest_imageplot.png
\image html jkqtplotter_simpletest_imageplot_modifier.png
\image html jkqtplotter_simpletest_imageplot__smallscaletransparent.png
+
+ \see \ref JKQTPlotterImagePlotNoDatastore
*/
class JKQTP_LIB_EXPORT JKQTPMathImage: public JKQTPMathImageBase {
Q_OBJECT
@@ -994,6 +998,7 @@ int JKQTPMathImage::getModifierSampleSize() const {
\image html jkqtplotter_simpletest_imageplot_modifier.png
\image html jkqtplotter_simpletest_imageplot__smallscaletransparent.png
+ \see jkqtpstatAddKDE2DImage(), jkqtpstatAddHistogram2DImage(), \ref JKQTPlotterImagePlot, \ref JKQTPlotterImagePlotModifier, \ref JKQTPlotterImagePlotOpenCV
*/
class JKQTP_LIB_EXPORT JKQTPColumnMathImage: public JKQTPMathImage {
Q_OBJECT
diff --git a/lib/jkqtplotter/jkqtpgraphsimpulses.h b/lib/jkqtplotter/jkqtpgraphsimpulses.h
index 1016a9798a..d9861f069c 100644
--- a/lib/jkqtplotter/jkqtpgraphsimpulses.h
+++ b/lib/jkqtplotter/jkqtpgraphsimpulses.h
@@ -31,6 +31,8 @@
\ingroup jkqtplotter_barssticks
\image html plot_impulsesxplots.png
+
+ \see JKQTPImpulsesVerticalGraph, \ref JKQTPlotterImpulsePlots
*/
class JKQTP_LIB_EXPORT JKQTPImpulsesHorizontalGraph: public JKQTPXYGraph, public JKQTPGraphLineStyleMixin, public JKQTPGraphSymbolStyleMixin{
Q_OBJECT
@@ -80,6 +82,8 @@ class JKQTP_LIB_EXPORT JKQTPImpulsesHorizontalGraph: public JKQTPXYGraph, public
\ingroup jkqtplotter_barssticks
\image html plot_impulsesxerrorsplots.png
+
+ \see jkqtpstatAddXErrorImpulsesGraph(), JKQTPImpulsesHorizontalGraph, \ref JKQTPlotterImpulsePlots
*/
class JKQTP_LIB_EXPORT JKQTPImpulsesHorizontalErrorGraph: public JKQTPImpulsesHorizontalGraph, public JKQTPXGraphErrors {
Q_OBJECT
@@ -103,6 +107,8 @@ class JKQTP_LIB_EXPORT JKQTPImpulsesHorizontalErrorGraph: public JKQTPImpulsesHo
\ingroup jkqtplotter_barssticks
\image html plot_impulsesyplots.png
+
+ \see \ref JKQTPlotterImpulsePlots
*/
class JKQTP_LIB_EXPORT JKQTPImpulsesVerticalGraph: public JKQTPImpulsesHorizontalGraph {
Q_OBJECT
@@ -122,6 +128,8 @@ class JKQTP_LIB_EXPORT JKQTPImpulsesVerticalGraph: public JKQTPImpulsesHorizonta
\ingroup jkqtplotter_barssticks
\image html plot_impulsesyerrorsplots.png
+
+ \see JKQTPImpulsesVerticalGraph, jkqtpstatAddYErrorImpulsesGraph(), \ref JKQTPlotterImpulsePlots
*/
class JKQTP_LIB_EXPORT JKQTPImpulsesVerticalErrorGraph: public JKQTPImpulsesVerticalGraph, public JKQTPYGraphErrors {
Q_OBJECT
diff --git a/lib/jkqtplotter/jkqtpgraphsparsedfunction.h b/lib/jkqtplotter/jkqtpgraphsparsedfunction.h
index c7409b98c6..4993087eea 100644
--- a/lib/jkqtplotter/jkqtpgraphsparsedfunction.h
+++ b/lib/jkqtplotter/jkqtpgraphsparsedfunction.h
@@ -42,6 +42,8 @@ class JKQTPlotter;
Parameters may also be given from a data column. Then first the params from the column and the the parameters from the vector are numbered.
Use the variable \c x in an equation to refer to the free parameter of the curve.
+
+ \see \ref JKQTPlotterParsedFunctionPlot, JKQTPMathParser
*/
class JKQTP_LIB_EXPORT JKQTPXParsedFunctionLineGraph: public JKQTPXFunctionLineGraph {
Q_OBJECT
@@ -108,6 +110,9 @@ class JKQTP_LIB_EXPORT JKQTPXParsedFunctionLineGraph: public JKQTPXFunctionLineG
Parameters may also be given from a data column. Then first the params from the column and the the parameters from the vector are numbered.
Use the variable \c y in an equation to refer to the free parameter of the curve (\c is also understood for convenience).
+
+ \see \ref JKQTPlotterParsedFunctionPlot, JKQTPMathParser
+
*/
class JKQTP_LIB_EXPORT JKQTPYParsedFunctionLineGraph: public JKQTPYFunctionLineGraph {
Q_OBJECT
diff --git a/lib/jkqtplotter/jkqtpgraphspeakstream.h b/lib/jkqtplotter/jkqtpgraphspeakstream.h
index c9a2c58329..c3bcf27252 100644
--- a/lib/jkqtplotter/jkqtpgraphspeakstream.h
+++ b/lib/jkqtplotter/jkqtpgraphspeakstream.h
@@ -42,6 +42,8 @@ class JKQTPDatastore;
\image html JKQTPPeakStreamGraphY.png "yPeaks=true"
\image html JKQTPPeakStreamGraphX.png "yPeaks=false"
+
+ \see \ref JKQTPlotterBasicJKQTPDatastoreStatistics
*/
class JKQTP_LIB_EXPORT JKQTPPeakStreamGraph: public JKQTPSingleColumnGraph, public JKQTPGraphLineStyleMixin {
Q_OBJECT
diff --git a/lib/jkqtplotter/jkqtpgraphsscatter.h b/lib/jkqtplotter/jkqtpgraphsscatter.h
index 626d10a56d..d1193d09b6 100644
--- a/lib/jkqtplotter/jkqtpgraphsscatter.h
+++ b/lib/jkqtplotter/jkqtpgraphsscatter.h
@@ -50,6 +50,8 @@ class JKQTPDatastore;
\ingroup jkqtplotter_linesymbolgraphs_simple
\image html plot_lineplots.png
+
+ \see \ref JKQTPlotterAdvancedLineAndFillStyling, \ref JKQTPlotterSimpleTest, \ref JKQTPlotterSymbolsAndStyles, jkqtpstatAddVKDE1D(), jkqtpstatAddVKDE1DAutoranged(), jkqtpstatAddHKDE1D(), jkqtpstatAddHKDE1DAutoranged()
*/
class JKQTP_LIB_EXPORT JKQTPXYLineGraph: public JKQTPXYGraph, public JKQTPGraphLineStyleMixin, public JKQTPGraphSymbolStyleMixin {
Q_OBJECT
@@ -109,7 +111,7 @@ class JKQTP_LIB_EXPORT JKQTPXYLineGraph: public JKQTPXYGraph, public JKQTPGraphL
\image html JKQTPXYParametrizedScatterGraph_SymbolFunctor.png
- \see JKQTPXYParametrizedErrorScatterGraph, \ref JKQTPlotterParamScatter , \ref JKQTPlotterParamScatterImage
+ \see JKQTPXYParametrizedErrorScatterGraph, \ref JKQTPlotterParamScatter , \ref JKQTPlotterParamScatterImage, \ref JKQTPlotterParametricCurves
*/
class JKQTP_LIB_EXPORT JKQTPXYParametrizedScatterGraph: public JKQTPXYLineGraph, public JKQTPColorPaletteStyleAndToolsMixin {
Q_OBJECT
@@ -367,6 +369,8 @@ class JKQTP_LIB_EXPORT JKQTPXYParametrizedScatterGraph: public JKQTPXYLineGraph,
\image html plot_errorbarlineplots.png
\image html plot_errorlinelineplots.png
\image html plot_errorpolygonlineplots.png
+
+ \see jkqtpstatAddXYErrorLineGraph(), jkqtpstatAddXErrorLineGraph(), jkqtpstatAddYErrorLineGraph(), \ref JKQTPlotterErrorBarStyles, \ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat
*/
class JKQTP_LIB_EXPORT JKQTPXYLineErrorGraph: public JKQTPXYLineGraph, public JKQTPXYGraphErrors {
Q_OBJECT
@@ -403,7 +407,7 @@ class JKQTP_LIB_EXPORT JKQTPXYLineErrorGraph: public JKQTPXYLineGraph, public JK
\image html screen_parmetrizedplots_datatable.png
- \see JKQTPXYParametrizedScatterGraph, \ref JKQTPlotterParamScatter
+ \see JKQTPXYParametrizedScatterGraph, \ref JKQTPlotterParamScatter, jkqtpstatAddXErrorParametrizedScatterGraph(), jkqtpstatAddYErrorParametrizedScatterGraph()
*/
class JKQTP_LIB_EXPORT JKQTPXYParametrizedErrorScatterGraph: public JKQTPXYParametrizedScatterGraph, public JKQTPXYGraphErrors {
Q_OBJECT
diff --git a/lib/jkqtplotter/jkqtpgraphsstatisticsadaptors.h b/lib/jkqtplotter/jkqtpgraphsstatisticsadaptors.h
index 0a5035afb2..04d1ff0536 100644
--- a/lib/jkqtplotter/jkqtpgraphsstatisticsadaptors.h
+++ b/lib/jkqtplotter/jkqtpgraphsstatisticsadaptors.h
@@ -30,6 +30,8 @@
#include "jkqtplotter/jkqtpgraphsevaluatedfunction.h"
#include "jkqtplotter/jkqtpgraphsimage.h"
#include "jkqtplotter/jkqtpgraphscontour.h"
+#include "jkqtplotter/jkqtpgraphsimpulses.h"
+#include "jkqtplotter/jkqtpgraphsfilledcurve.h"
#ifndef JKQTPGRAPHSSTATISTICSADAPTORS_H_INCLUDED
@@ -1788,4 +1790,735 @@ JKQTP_LIB_EXPORT JKQTPXFunctionLineGraph* jkqtpstatAddPolyFit(JKQTPXYGraph *data
+
+
+
+
+
+
+
+/*! \brief create a plot with y-direction error bars, calculated from average +/- stddev of groups in the input data
+ \ingroup jkqtptools_math_statistics_adaptors
+
+ \tparam TGraph type of graph that should be added to the plot
+ \tparam InputCatIt standard iterator type of \a inFirstCat_X and \a inLastCat_X
+ \tparam InputValueIt standard iterator type of \a inFirstValue_Y and \a inLastValue_Y
+ \param plotter the plotter to which to add the resulting graph
+ \param inFirstCat_X iterator pointing to the first item in the category dataset to use \f$ c_1 \f$ (used for x-coordinates)
+ \param inLastCat_X iterator pointing behind the last item in the category dataset to use \f$ c_N \f$ (used for x-coordinates)
+ \param inFirstValue_Y iterator pointing to the first item in the category dataset to use \f$ v_1 \f$ (used for y-coordinates)
+ \param inLastValue_Y iterator pointing behind the last item in the category dataset to use \f$ v_N \f$ (used for y-coordinates)
+ \param groupDefFunc assigns a group \f$ c_{\text{out},j} \f$ to each category value \f$ c_i \f$ .
+ \param columnBaseName string component used to build the names of the columns generated by this function
+ \return the graph showing \f$ c_{\text{out},j} \f$ and average +/- stddev for each group \f$ j \f$
+
+
+
+ \see jkqtpstatGroupData(), \ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat
+*/
+template
+inline TGraph* jkqtpstatAddYErrorGraph(JKQTBasePlotter* plotter, InputCatIt inFirstCat_X, InputCatIt inLastCat_X, InputValueIt inFirstValue_Y, InputValueIt inLastValue_Y, JKQTPStatGroupDefinitionFunctor1D groupDefFunc=&jkqtpstatGroupingIdentity1D, const QString& columnBaseName=QString("grouped data")) {
+ std::map > groupeddataBar;
+ jkqtpstatGroupData(inFirstCat_X, inLastCat_X, inFirstValue_Y, inLastValue_Y, groupeddataBar, groupDefFunc);
+
+ size_t colGroup=plotter->getDatastore()->addColumn(columnBaseName+", group");
+ size_t colAverage=plotter->getDatastore()->addColumn(columnBaseName+", average");
+ size_t colStdDev=plotter->getDatastore()->addColumn(columnBaseName+", stddev");
+
+ for (auto it=groupeddataBar.begin(); it!=groupeddataBar.end(); ++it) {
+ plotter->getDatastore()->appendToColumn(colGroup, it->first);
+ plotter->getDatastore()->appendToColumn(colAverage, jkqtpstatAverage(it->second.begin(), it->second.end()));
+ plotter->getDatastore()->appendToColumn(colStdDev, jkqtpstatStdDev(it->second.begin(), it->second.end()));
+ }
+
+ // 2.4. Finally the calculated groups are drawn
+ TGraph* graph;
+ plotter->addGraph(graph=new TGraph(plotter));
+ graph->setXColumn(colGroup);
+ graph->setYColumn(colAverage);
+ graph->setYErrorColumn(static_cast(colStdDev));
+
+ return graph;
+}
+
+
+/*! \brief create a JKQTPXYLineErrorGraph with y-direction error bars, calculated from average +/- stddev of groups in the input data
+ \ingroup jkqtptools_math_statistics_adaptors
+
+ \tparam InputCatIt standard iterator type of \a inFirstCat_X and \a inLastCat_X
+ \tparam InputValueIt standard iterator type of \a inFirstValue_Y and \a inLastValue_Y
+ \param plotter the plotter to which to add the resulting graph
+ \param inFirstCat_X iterator pointing to the first item in the category dataset to use \f$ c_1 \f$ (used for x-coordinates)
+ \param inLastCat_X iterator pointing behind the last item in the category dataset to use \f$ c_N \f$ (used for x-coordinates)
+ \param inFirstValue_Y iterator pointing to the first item in the category dataset to use \f$ v_1 \f$ (used for y-coordinates)
+ \param inLastValue_Y iterator pointing behind the last item in the category dataset to use \f$ v_N \f$ (used for y-coordinates)
+ \param groupDefFunc assigns a group \f$ c_{\text{out},j} \f$ to each category value \f$ c_i \f$ .
+ \param columnBaseName string component used to build the names of the columns generated by this function
+ \return the graph showing \f$ c_{\text{out},j} \f$ and average +/- stddev for each group \f$ j \f$
+
+
+
+ \see jkqtpstatGroupData(), jkqtpstatAddYErrorGraph(), JKQTPXYLineErrorGraph, \ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat
+*/
+template
+inline JKQTPXYLineErrorGraph* jkqtpstatAddYErrorLineGraph(JKQTBasePlotter* plotter, InputCatIt inFirstCat_X, InputCatIt inLastCat_X, InputValueIt inFirstValue_Y, InputValueIt inLastValue_Y, JKQTPStatGroupDefinitionFunctor1D groupDefFunc=&jkqtpstatGroupingIdentity1D, const QString& columnBaseName=QString("grouped data")) {
+ return jkqtpstatAddYErrorGraph(plotter,inFirstCat_X, inLastCat_X, inFirstValue_Y, inLastValue_Y, groupDefFunc, columnBaseName);
+}
+
+
+/*! \brief create a JKQTPBarVerticalErrorGraph with y-direction error bars, calculated from average +/- stddev of groups in the input data
+ \ingroup jkqtptools_math_statistics_adaptors
+
+ \tparam InputCatIt standard iterator type of \a inFirstCat_X and \a inLastCat_X
+ \tparam InputValueIt standard iterator type of \a inFirstValue_Y and \a inLastValue_Y
+ \param plotter the plotter to which to add the resulting graph
+ \param inFirstCat_X iterator pointing to the first item in the category dataset to use \f$ c_1 \f$ (used for x-coordinates)
+ \param inLastCat_X iterator pointing behind the last item in the category dataset to use \f$ c_N \f$ (used for x-coordinates)
+ \param inFirstValue_Y iterator pointing to the first item in the category dataset to use \f$ v_1 \f$ (used for y-coordinates)
+ \param inLastValue_Y iterator pointing behind the last item in the category dataset to use \f$ v_N \f$ (used for y-coordinates)
+ \param groupDefFunc assigns a group \f$ c_{\text{out},j} \f$ to each category value \f$ c_i \f$ .
+ \param columnBaseName string component used to build the names of the columns generated by this function
+ \return the graph showing \f$ c_{\text{out},j} \f$ and average +/- stddev for each group \f$ j \f$
+
+
+
+ \see jkqtpstatGroupData(), jkqtpstatAddYErrorGraph(), JKQTPBarVerticalErrorGraph, \ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat
+*/
+template
+inline JKQTPBarVerticalErrorGraph* jkqtpstatAddYErrorBarGraph(JKQTBasePlotter* plotter, InputCatIt inFirstCat_X, InputCatIt inLastCat_X, InputValueIt inFirstValue_Y, InputValueIt inLastValue_Y, JKQTPStatGroupDefinitionFunctor1D groupDefFunc=&jkqtpstatGroupingIdentity1D, const QString& columnBaseName=QString("grouped data")) {
+ return jkqtpstatAddYErrorGraph(plotter,inFirstCat_X, inLastCat_X, inFirstValue_Y, inLastValue_Y, groupDefFunc, columnBaseName);
+}
+
+
+/*! \brief create a JKQTPImpulsesVerticalErrorGraph with y-direction error bars, calculated from average +/- stddev of groups in the input data
+ \ingroup jkqtptools_math_statistics_adaptors
+
+ \tparam InputCatIt standard iterator type of \a inFirstCat_X and \a inLastCat_X
+ \tparam InputValueIt standard iterator type of \a inFirstValue_Y and \a inLastValue_Y
+ \param plotter the plotter to which to add the resulting graph
+ \param inFirstCat_X iterator pointing to the first item in the category dataset to use \f$ c_1 \f$ (used for x-coordinates)
+ \param inLastCat_X iterator pointing behind the last item in the category dataset to use \f$ c_N \f$ (used for x-coordinates)
+ \param inFirstValue_Y iterator pointing to the first item in the category dataset to use \f$ v_1 \f$ (used for y-coordinates)
+ \param inLastValue_Y iterator pointing behind the last item in the category dataset to use \f$ v_N \f$ (used for y-coordinates)
+ \param groupDefFunc assigns a group \f$ c_{\text{out},j} \f$ to each category value \f$ c_i \f$ .
+ \param columnBaseName string component used to build the names of the columns generated by this function
+ \return the graph showing \f$ c_{\text{out},j} \f$ and average +/- stddev for each group \f$ j \f$
+
+
+
+ \see jkqtpstatGroupData(), jkqtpstatAddYErrorGraph(), JKQTPImpulsesVerticalErrorGraph, \ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat
+*/
+template
+inline JKQTPImpulsesVerticalErrorGraph* jkqtpstatAddYErrorImpulsesGraph(JKQTBasePlotter* plotter, InputCatIt inFirstCat_X, InputCatIt inLastCat_X, InputValueIt inFirstValue_Y, InputValueIt inLastValue_Y, JKQTPStatGroupDefinitionFunctor1D groupDefFunc=&jkqtpstatGroupingIdentity1D, const QString& columnBaseName=QString("grouped data")) {
+ return jkqtpstatAddYErrorGraph(plotter,inFirstCat_X, inLastCat_X, inFirstValue_Y, inLastValue_Y, groupDefFunc, columnBaseName);
+}
+
+
+/*! \brief create a JKQTPXYParametrizedErrorScatterGraph with y-direction error bars, calculated from average +/- stddev of groups in the input data
+ \ingroup jkqtptools_math_statistics_adaptors
+
+ \tparam InputCatIt standard iterator type of \a inFirstCat_X and \a inLastCat_X
+ \tparam InputValueIt standard iterator type of \a inFirstValue_Y and \a inLastValue_Y
+ \param plotter the plotter to which to add the resulting graph
+ \param inFirstCat_X iterator pointing to the first item in the category dataset to use \f$ c_1 \f$ (used for x-coordinates)
+ \param inLastCat_X iterator pointing behind the last item in the category dataset to use \f$ c_N \f$ (used for x-coordinates)
+ \param inFirstValue_Y iterator pointing to the first item in the category dataset to use \f$ v_1 \f$ (used for y-coordinates)
+ \param inLastValue_Y iterator pointing behind the last item in the category dataset to use \f$ v_N \f$ (used for y-coordinates)
+ \param groupDefFunc assigns a group \f$ c_{\text{out},j} \f$ to each category value \f$ c_i \f$ .
+ \param columnBaseName string component used to build the names of the columns generated by this function
+ \return the graph showing \f$ c_{\text{out},j} \f$ and average +/- stddev for each group \f$ j \f$
+
+
+
+ \see jkqtpstatGroupData(), jkqtpstatAddYErrorGraph(), JKQTPXYParametrizedErrorScatterGraph, \ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat
+*/
+template
+inline JKQTPXYParametrizedErrorScatterGraph* jkqtpstatAddYErrorParametrizedScatterGraph(JKQTBasePlotter* plotter, InputCatIt inFirstCat_X, InputCatIt inLastCat_X, InputValueIt inFirstValue_Y, InputValueIt inLastValue_Y, JKQTPStatGroupDefinitionFunctor1D groupDefFunc=&jkqtpstatGroupingIdentity1D, const QString& columnBaseName=QString("grouped data")) {
+ return jkqtpstatAddYErrorGraph(plotter,inFirstCat_X, inLastCat_X, inFirstValue_Y, inLastValue_Y, groupDefFunc, columnBaseName);
+}
+
+
+/*! \brief create a JKQTPFilledCurveYErrorGraph with y-direction error bars, calculated from average +/- stddev of groups in the input data
+ \ingroup jkqtptools_math_statistics_adaptors
+
+ \tparam InputCatIt standard iterator type of \a inFirstCat_X and \a inLastCat_X
+ \tparam InputValueIt standard iterator type of \a inFirstValue_Y and \a inLastValue_Y
+ \param plotter the plotter to which to add the resulting graph
+ \param inFirstCat_X iterator pointing to the first item in the category dataset to use \f$ c_1 \f$ (used for x-coordinates)
+ \param inLastCat_X iterator pointing behind the last item in the category dataset to use \f$ c_N \f$ (used for x-coordinates)
+ \param inFirstValue_Y iterator pointing to the first item in the category dataset to use \f$ v_1 \f$ (used for y-coordinates)
+ \param inLastValue_Y iterator pointing behind the last item in the category dataset to use \f$ v_N \f$ (used for y-coordinates)
+ \param groupDefFunc assigns a group \f$ c_{\text{out},j} \f$ to each category value \f$ c_i \f$ .
+ \param columnBaseName string component used to build the names of the columns generated by this function
+ \return the graph showing \f$ c_{\text{out},j} \f$ and average +/- stddev for each group \f$ j \f$
+
+
+
+ \see jkqtpstatGroupData(), jkqtpstatAddYErrorGraph(), JKQTPFilledCurveYErrorGraph, \ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat
+*/
+template
+inline JKQTPFilledCurveYErrorGraph* jkqtpstatAddYErrorFilledCurveGraph(JKQTBasePlotter* plotter, InputCatIt inFirstCat_X, InputCatIt inLastCat_X, InputValueIt inFirstValue_Y, InputValueIt inLastValue_Y, JKQTPStatGroupDefinitionFunctor1D groupDefFunc=&jkqtpstatGroupingIdentity1D, const QString& columnBaseName=QString("grouped data")) {
+ return jkqtpstatAddYErrorGraph(plotter,inFirstCat_X, inLastCat_X, inFirstValue_Y, inLastValue_Y, groupDefFunc, columnBaseName);
+}
+
+
+
+
+
+
+
+/*! \brief create a plot with x-direction error bars, calculated from average +/- stddev of groups in the input data
+ \ingroup jkqtptools_math_statistics_adaptors
+
+ \tparam TGraph type of graph that should be added to the plot
+ \tparam InputCatIt standard iterator type of \a inFirstCat_Y and \a inLastCat_Y
+ \tparam InputValueIt standard iterator type of \a inFirstValue_Y and \a inLastValue_Y
+ \param plotter the plotter to which to add the resulting graph
+ \param inFirstCat_Y iterator pointing to the first item in the category dataset to use \f$ c_1 \f$ (used for y-coordinates)
+ \param inLastCat_Y iterator pointing behind the last item in the category dataset to use \f$ c_N \f$ (used for y-coordinates)
+ \param inFirstValue_Y iterator pointing to the first item in the category dataset to use \f$ v_1 \f$ (used for x-coordinates)
+ \param inLastValue_Y iterator pointing behind the last item in the category dataset to use \f$ v_N \f$ (used for x-coordinates)
+ \param groupDefFunc assigns a group \f$ c_{\text{out},j} \f$ to each category value \f$ c_i \f$ .
+ \param columnBaseName string component used to build the names of the columns generated by this function
+ \return the graph showing \f$ c_{\text{out},j} \f$ and average +/- stddev for each group \f$ j \f$
+
+
+
+ \see jkqtpstatGroupData(), \ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat
+*/
+template
+inline TGraph* jkqtpstatAddXErrorGraph(JKQTBasePlotter* plotter, InputCatIt inFirstCat_Y, InputCatIt inLastCat_Y, InputValueIt inFirstValue_Y, InputValueIt inLastValue_Y, JKQTPStatGroupDefinitionFunctor1D groupDefFunc=&jkqtpstatGroupingIdentity1D, const QString& columnBaseName=QString("grouped data")) {
+ std::map > groupeddataBar;
+ jkqtpstatGroupData(inFirstCat_Y, inLastCat_Y, inFirstValue_Y, inLastValue_Y, groupeddataBar, groupDefFunc);
+
+ size_t colGroup=plotter->getDatastore()->addColumn(columnBaseName+", group");
+ size_t colAverage=plotter->getDatastore()->addColumn(columnBaseName+", average");
+ size_t colStdDev=plotter->getDatastore()->addColumn(columnBaseName+", stddev");
+
+ for (auto it=groupeddataBar.begin(); it!=groupeddataBar.end(); ++it) {
+ plotter->getDatastore()->appendToColumn(colGroup, it->first);
+ plotter->getDatastore()->appendToColumn(colAverage, jkqtpstatAverage(it->second.begin(), it->second.end()));
+ plotter->getDatastore()->appendToColumn(colStdDev, jkqtpstatStdDev(it->second.begin(), it->second.end()));
+ }
+
+ // 2.4. Finally the calculated groups are drawn
+ TGraph* graph;
+ plotter->addGraph(graph=new TGraph(plotter));
+ graph->setXColumn(colAverage);
+ graph->setYColumn(colGroup);
+ graph->setXErrorColumn(static_cast(colStdDev));
+
+ return graph;
+}
+
+
+/*! \brief create a JKQTPXYLineErrorGraph with x-direction error bars, calculated from average +/- stddev of groups in the input data
+ \ingroup jkqtptools_math_statistics_adaptors
+
+ \tparam InputCatIt standard iterator type of \a inFirstCat_Y and \a inLastCat_Y
+ \tparam InputValueIt standard iterator type of \a inFirstValue_Y and \a inLastValue_Y
+ \param plotter the plotter to which to add the resulting graph
+ \param inFirstCat_Y iterator pointing to the first item in the category dataset to use \f$ c_1 \f$ (used for y-coordinates)
+ \param inLastCat_Y iterator pointing behind the last item in the category dataset to use \f$ c_N \f$ (used for y-coordinates)
+ \param inFirstValue_Y iterator pointing to the first item in the category dataset to use \f$ v_1 \f$ (used for x-coordinates)
+ \param inLastValue_Y iterator pointing behind the last item in the category dataset to use \f$ v_N \f$ (used for x-coordinates)
+ \param groupDefFunc assigns a group \f$ c_{\text{out},j} \f$ to each category value \f$ c_i \f$ .
+ \param columnBaseName string component used to build the names of the columns generated by this function
+ \return the graph showing \f$ c_{\text{out},j} \f$ and average +/- stddev for each group \f$ j \f$
+
+
+
+ \see jkqtpstatGroupData(), jkqtpstatAddXErrorGraph(), JKQTPXYLineErrorGraph, \ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat
+*/
+template
+inline JKQTPXYLineErrorGraph* jkqtpstatAddXErrorLineGraph(JKQTBasePlotter* plotter, InputCatIt inFirstCat_Y, InputCatIt inLastCat_Y, InputValueIt inFirstValue_Y, InputValueIt inLastValue_Y, JKQTPStatGroupDefinitionFunctor1D groupDefFunc=&jkqtpstatGroupingIdentity1D, const QString& columnBaseName=QString("grouped data")) {
+ return jkqtpstatAddXErrorGraph(plotter,inFirstCat_Y, inLastCat_Y, inFirstValue_Y, inLastValue_Y, groupDefFunc, columnBaseName);
+}
+
+
+/*! \brief create a JKQTPBarHorizontalErrorGraph with x-direction error bars, calculated from average +/- stddev of groups in the input data
+ \ingroup jkqtptools_math_statistics_adaptors
+
+ \tparam InputCatIt standard iterator type of \a inFirstCat_Y and \a inLastCat_Y
+ \tparam InputValueIt standard iterator type of \a inFirstValue_Y and \a inLastValue_Y
+ \param plotter the plotter to which to add the resulting graph
+ \param inFirstCat_Y iterator pointing to the first item in the category dataset to use \f$ c_1 \f$ (used for y-coordinates)
+ \param inLastCat_Y iterator pointing behind the last item in the category dataset to use \f$ c_N \f$ (used for y-coordinates)
+ \param inFirstValue_Y iterator pointing to the first item in the category dataset to use \f$ v_1 \f$ (used for x-coordinates)
+ \param inLastValue_Y iterator pointing behind the last item in the category dataset to use \f$ v_N \f$ (used for x-coordinates)
+ \param groupDefFunc assigns a group \f$ c_{\text{out},j} \f$ to each category value \f$ c_i \f$ .
+ \param columnBaseName string component used to build the names of the columns generated by this function
+ \return the graph showing \f$ c_{\text{out},j} \f$ and average +/- stddev for each group \f$ j \f$
+
+
+
+ \see jkqtpstatGroupData(), jkqtpstatAddXErrorGraph(), JKQTPBarHorizontalErrorGraph, \ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat
+*/
+template
+inline JKQTPBarHorizontalErrorGraph* jkqtpstatAddXErrorBarGraph(JKQTBasePlotter* plotter, InputCatIt inFirstCat_Y, InputCatIt inLastCat_Y, InputValueIt inFirstValue_Y, InputValueIt inLastValue_Y, JKQTPStatGroupDefinitionFunctor1D groupDefFunc=&jkqtpstatGroupingIdentity1D, const QString& columnBaseName=QString("grouped data")) {
+ return jkqtpstatAddXErrorGraph(plotter,inFirstCat_Y, inLastCat_Y, inFirstValue_Y, inLastValue_Y, groupDefFunc, columnBaseName);
+}
+
+
+/*! \brief create a JKQTPImpulsesHorizontalErrorGraph with x-direction error bars, calculated from average +/- stddev of groups in the input data
+ \ingroup jkqtptools_math_statistics_adaptors
+
+ \tparam InputCatIt standard iterator type of \a inFirstCat_Y and \a inLastCat_Y
+ \tparam InputValueIt standard iterator type of \a inFirstValue_Y and \a inLastValue_Y
+ \param plotter the plotter to which to add the resulting graph
+ \param inFirstCat_Y iterator pointing to the first item in the category dataset to use \f$ c_1 \f$ (used for y-coordinates)
+ \param inLastCat_Y iterator pointing behind the last item in the category dataset to use \f$ c_N \f$ (used for y-coordinates)
+ \param inFirstValue_Y iterator pointing to the first item in the category dataset to use \f$ v_1 \f$ (used for x-coordinates)
+ \param inLastValue_Y iterator pointing behind the last item in the category dataset to use \f$ v_N \f$ (used for x-coordinates)
+ \param groupDefFunc assigns a group \f$ c_{\text{out},j} \f$ to each category value \f$ c_i \f$ .
+ \param columnBaseName string component used to build the names of the columns generated by this function
+ \return the graph showing \f$ c_{\text{out},j} \f$ and average +/- stddev for each group \f$ j \f$
+
+
+
+ \see jkqtpstatGroupData(), jkqtpstatAddXErrorGraph(), JKQTPImpulsesHorizontalErrorGraph, \ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat
+*/
+template
+inline JKQTPImpulsesHorizontalErrorGraph* jkqtpstatAddXErrorImpulsesGraph(JKQTBasePlotter* plotter, InputCatIt inFirstCat_Y, InputCatIt inLastCat_Y, InputValueIt inFirstValue_Y, InputValueIt inLastValue_Y, JKQTPStatGroupDefinitionFunctor1D groupDefFunc=&jkqtpstatGroupingIdentity1D, const QString& columnBaseName=QString("grouped data")) {
+ return jkqtpstatAddXErrorGraph(plotter,inFirstCat_Y, inLastCat_Y, inFirstValue_Y, inLastValue_Y, groupDefFunc, columnBaseName);
+}
+
+
+/*! \brief create a JKQTPXYParametrizedErrorScatterGraph with x-direction error bars, calculated from average +/- stddev of groups in the input data
+ \ingroup jkqtptools_math_statistics_adaptors
+
+ \tparam InputCatIt standard iterator type of \a inFirstCat_Y and \a inLastCat_Y
+ \tparam InputValueIt standard iterator type of \a inFirstValue_Y and \a inLastValue_Y
+ \param plotter the plotter to which to add the resulting graph
+ \param inFirstCat_Y iterator pointing to the first item in the category dataset to use \f$ c_1 \f$ (used for y-coordinates)
+ \param inLastCat_Y iterator pointing behind the last item in the category dataset to use \f$ c_N \f$ (used for y-coordinates)
+ \param inFirstValue_Y iterator pointing to the first item in the category dataset to use \f$ v_1 \f$ (used for x-coordinates)
+ \param inLastValue_Y iterator pointing behind the last item in the category dataset to use \f$ v_N \f$ (used for x-coordinates)
+ \param groupDefFunc assigns a group \f$ c_{\text{out},j} \f$ to each category value \f$ c_i \f$ .
+ \param columnBaseName string component used to build the names of the columns generated by this function
+ \return the graph showing \f$ c_{\text{out},j} \f$ and average +/- stddev for each group \f$ j \f$
+
+
+
+ \see jkqtpstatGroupData(), jkqtpstatAddXErrorGraph(), JKQTPXYParametrizedErrorScatterGraph, \ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat
+*/
+template
+inline JKQTPXYParametrizedErrorScatterGraph* jkqtpstatAddXErrorParametrizedScatterGraph(JKQTBasePlotter* plotter, InputCatIt inFirstCat_Y, InputCatIt inLastCat_Y, InputValueIt inFirstValue_Y, InputValueIt inLastValue_Y, JKQTPStatGroupDefinitionFunctor1D groupDefFunc=&jkqtpstatGroupingIdentity1D, const QString& columnBaseName=QString("grouped data")) {
+ return jkqtpstatAddXErrorGraph(plotter,inFirstCat_Y, inLastCat_Y, inFirstValue_Y, inLastValue_Y, groupDefFunc, columnBaseName);
+}
+
+
+/*! \brief create a JKQTPFilledCurveXErrorGraph with x-direction error bars, calculated from average +/- stddev of groups in the input data
+ \ingroup jkqtptools_math_statistics_adaptors
+
+ \tparam InputCatIt standard iterator type of \a inFirstCat_Y and \a inLastCat_Y
+ \tparam InputValueIt standard iterator type of \a inFirstValue_Y and \a inLastValue_Y
+ \param plotter the plotter to which to add the resulting graph
+ \param inFirstCat_Y iterator pointing to the first item in the category dataset to use \f$ c_1 \f$ (used for y-coordinates)
+ \param inLastCat_Y iterator pointing behind the last item in the category dataset to use \f$ c_N \f$ (used for y-coordinates)
+ \param inFirstValue_Y iterator pointing to the first item in the category dataset to use \f$ v_1 \f$ (used for x-coordinates)
+ \param inLastValue_Y iterator pointing behind the last item in the category dataset to use \f$ v_N \f$ (used for x-coordinates)
+ \param groupDefFunc assigns a group \f$ c_{\text{out},j} \f$ to each category value \f$ c_i \f$ .
+ \param columnBaseName string component used to build the names of the columns generated by this function
+ \return the graph showing \f$ c_{\text{out},j} \f$ and average +/- stddev for each group \f$ j \f$
+
+
+
+ \see jkqtpstatGroupData(), jkqtpstatAddXErrorGraph(), JKQTPFilledCurveXErrorGraph, \ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat
+*/
+template
+inline JKQTPFilledCurveXErrorGraph* jkqtpstatAddXErrorFilledCurveGraph(JKQTBasePlotter* plotter, InputCatIt inFirstCat_Y, InputCatIt inLastCat_Y, InputValueIt inFirstValue_Y, InputValueIt inLastValue_Y, JKQTPStatGroupDefinitionFunctor1D groupDefFunc=&jkqtpstatGroupingIdentity1D, const QString& columnBaseName=QString("grouped data")) {
+ return jkqtpstatAddXErrorGraph(plotter,inFirstCat_Y, inLastCat_Y, inFirstValue_Y, inLastValue_Y, groupDefFunc, columnBaseName);
+}
+
+
+
+
+
+
+
+
+/*! \brief create a plot with x- and y-direction error bars, calculated from directional average +/- stddev of groups in the input data
+ \ingroup jkqtptools_math_statistics_adaptors
+
+ \tparam TGraph type of graph that should be added to the plot
+ \tparam InputCatIt standard iterator type of \a inFirstCat_X and \a inLastCat_X
+ \tparam InputValueIt standard iterator type of \a inFirstValue_Y and \a inLastValue_Y
+ \param plotter the plotter to which to add the resulting graph
+ \param inFirstCat_X iterator pointing to the first item in the category dataset to use \f$ c_1 \f$ (used for x-coordinates)
+ \param inLastCat_X iterator pointing behind the last item in the category dataset to use \f$ c_N \f$ (used for x-coordinates)
+ \param inFirstValue_Y iterator pointing to the first item in the category dataset to use \f$ v_1 \f$ (used for y-coordinates)
+ \param inLastValue_Y iterator pointing behind the last item in the category dataset to use \f$ v_N \f$ (used for y-coordinates)
+ \param groupDefFunc assigns a group \f$ c_{\text{out},j} \f$ to each category value \f$ c_i \f$ .
+ \param columnBaseName string component used to build the names of the columns generated by this function
+ \return the graph showing \f$ c_{\text{out},j} \f$ and average +/- stddev for each group \f$ j \f$
+
+
+
+ \see jkqtpstatGroupData(), \ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat
+*/
+template
+inline TGraph* jkqtpstatAddXYErrorGraph(JKQTBasePlotter* plotter, InputCatIt inFirstCat_X, InputCatIt inLastCat_X, InputValueIt inFirstValue_Y, InputValueIt inLastValue_Y, JKQTPStatGroupDefinitionFunctor1D groupDefFunc=&jkqtpstatGroupingIdentity1D, const QString& columnBaseName=QString("grouped data")) {
+ std::map, std::vector > > groupeddataBar;
+ jkqtpstatGroupData(inFirstCat_X, inLastCat_X, inFirstValue_Y, inLastValue_Y, groupeddataBar, groupDefFunc);
+
+ size_t colGroup=plotter->getDatastore()->addColumn(columnBaseName+", group");
+ size_t colAverageX=plotter->getDatastore()->addColumn(columnBaseName+", category-average");
+ size_t colStdDevX=plotter->getDatastore()->addColumn(columnBaseName+", category-stddev");
+ size_t colAverageY=plotter->getDatastore()->addColumn(columnBaseName+", value-average");
+ size_t colStdDevY=plotter->getDatastore()->addColumn(columnBaseName+", value-stddev");
+
+ for (auto it=groupeddataBar.begin(); it!=groupeddataBar.end(); ++it) {
+ plotter->getDatastore()->appendToColumn(colGroup, it->first);
+ plotter->getDatastore()->appendToColumn(colAverageX, jkqtpstatAverage(it->second.first.begin(), it->second.first.end()));
+ plotter->getDatastore()->appendToColumn(colStdDevX, jkqtpstatStdDev(it->second.first.begin(), it->second.first.end()));
+ plotter->getDatastore()->appendToColumn(colAverageY, jkqtpstatAverage(it->second.second.begin(), it->second.second.end()));
+ plotter->getDatastore()->appendToColumn(colStdDevY, jkqtpstatStdDev(it->second.second.begin(), it->second.second.end()));
+ }
+
+ // 2.4. Finally the calculated groups are drawn
+ TGraph* graph;
+ plotter->addGraph(graph=new TGraph(plotter));
+ graph->setXColumn(colAverageX);
+ graph->setYColumn(colAverageY);
+ graph->setXErrorColumn(static_cast(colStdDevX));
+ graph->setYErrorColumn(static_cast(colStdDevY));
+
+ return graph;
+}
+
+
+/*! \brief create a JKQTPXYLineErrorGraph with y-direction error bars, calculated from average +/- stddev of groups in the input data
+ \ingroup jkqtptools_math_statistics_adaptors
+
+ \tparam InputCatIt standard iterator type of \a inFirstCat_X and \a inLastCat_X
+ \tparam InputValueIt standard iterator type of \a inFirstValue_Y and \a inLastValue_Y
+ \param plotter the plotter to which to add the resulting graph
+ \param inFirstCat_X iterator pointing to the first item in the category dataset to use \f$ c_1 \f$ (used for x-coordinates)
+ \param inLastCat_X iterator pointing behind the last item in the category dataset to use \f$ c_N \f$ (used for x-coordinates)
+ \param inFirstValue_Y iterator pointing to the first item in the category dataset to use \f$ v_1 \f$ (used for y-coordinates)
+ \param inLastValue_Y iterator pointing behind the last item in the category dataset to use \f$ v_N \f$ (used for y-coordinates)
+ \param groupDefFunc assigns a group \f$ c_{\text{out},j} \f$ to each category value \f$ c_i \f$ .
+ \param columnBaseName string component used to build the names of the columns generated by this function
+ \return the graph showing \f$ c_{\text{out},j} \f$ and average +/- stddev for each group \f$ j \f$
+
+
+
+ \see jkqtpstatGroupData(), jkqtpstatAddXYErrorGraph(), JKQTPXYLineErrorGraph, \ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat
+*/
+template
+inline JKQTPXYLineErrorGraph* jkqtpstatAddXYErrorLineGraph(JKQTBasePlotter* plotter, InputCatIt inFirstCat_X, InputCatIt inLastCat_X, InputValueIt inFirstValue_Y, InputValueIt inLastValue_Y, JKQTPStatGroupDefinitionFunctor1D groupDefFunc=&jkqtpstatGroupingIdentity1D, const QString& columnBaseName=QString("grouped data")) {
+ return jkqtpstatAddXYErrorGraph(plotter,inFirstCat_X, inLastCat_X, inFirstValue_Y, inLastValue_Y, groupDefFunc, columnBaseName);
+}
+
+
+
+/*! \brief create a JKQTPXYParametrizedErrorScatterGraph with y-direction error bars, calculated from average +/- stddev of groups in the input data
+ \ingroup jkqtptools_math_statistics_adaptors
+
+ \tparam InputCatIt standard iterator type of \a inFirstCat_X and \a inLastCat_X
+ \tparam InputValueIt standard iterator type of \a inFirstValue_Y and \a inLastValue_Y
+ \param plotter the plotter to which to add the resulting graph
+ \param inFirstCat_X iterator pointing to the first item in the category dataset to use \f$ c_1 \f$ (used for x-coordinates)
+ \param inLastCat_X iterator pointing behind the last item in the category dataset to use \f$ c_N \f$ (used for x-coordinates)
+ \param inFirstValue_Y iterator pointing to the first item in the category dataset to use \f$ v_1 \f$ (used for y-coordinates)
+ \param inLastValue_Y iterator pointing behind the last item in the category dataset to use \f$ v_N \f$ (used for y-coordinates)
+ \param groupDefFunc assigns a group \f$ c_{\text{out},j} \f$ to each category value \f$ c_i \f$ .
+ \param columnBaseName string component used to build the names of the columns generated by this function
+ \return the graph showing \f$ c_{\text{out},j} \f$ and average +/- stddev for each group \f$ j \f$
+
+
+
+ \see jkqtpstatGroupData(), jkqtpstatAddXYErrorGraph(), JKQTPXYParametrizedErrorScatterGraph, \ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat
+*/
+template
+inline JKQTPXYParametrizedErrorScatterGraph* jkqtpstatAddXYErrorParametrizedScatterGraph(JKQTBasePlotter* plotter, InputCatIt inFirstCat_X, InputCatIt inLastCat_X, InputValueIt inFirstValue_Y, InputValueIt inLastValue_Y, JKQTPStatGroupDefinitionFunctor1D groupDefFunc=&jkqtpstatGroupingIdentity1D, const QString& columnBaseName=QString("grouped data")) {
+ return jkqtpstatAddXYErrorGraph(plotter,inFirstCat_X, inLastCat_X, inFirstValue_Y, inLastValue_Y, groupDefFunc, columnBaseName);
+}
+
+
+
+
+
+/*! \brief create horizontal boxplots of type \a TGraph, from the 5-value-summary of groups in the input data
+ \ingroup jkqtptools_math_statistics_adaptors
+ \internal
+
+ \tparam TGraph type of graph that should be added to the plot, has to offer the same interface as JKQTPBoxplotVerticalGraph or JKQTPBoxplotHorizontalGraph
+ \tparam InputCatIt standard iterator type of \a inFirstCat_Y and \a inLastCat_Y
+ \tparam InputValueIt standard iterator type of \a inFirstValue_Y and \a inLastValue_Y
+ \param plotter the plotter to which to add the resulting graph
+ \param inFirstCat_Y iterator pointing to the first item in the category dataset to use \f$ c_1 \f$ (used for y-coordinates)
+ \param inLastCat_Y iterator pointing behind the last item in the category dataset to use \f$ c_N \f$ (used for y-coordinates)
+ \param inFirstValue_Y iterator pointing to the first item in the category dataset to use \f$ v_1 \f$ (used for x-coordinates)
+ \param inLastValue_Y iterator pointing behind the last item in the category dataset to use \f$ v_N \f$ (used for x-coordinates)
+ \param quantile1Spec specifies which quantile to calculate for \a qantile1 (range: 0..1)
+ \param quantile2Spec specifies which quantile to calculate for \a qantile2 (range: 0..1)
+ \param minimumQuantile specifies a quantile for the return value minimum (default is 0 for the real minimum, but you could e.g. use 0.05 for the 5% quantile!)
+ \param maximumQuantile specifies a quantile for the return value maximum (default is 1 for the real maximum, but you could e.g. use 0.95 for the 95% quantile!)
+ \param groupDefFunc assigns a group \f$ c_{\text{out},j} \f$ to each category value \f$ c_i \f$ .
+ \param columnBaseName string component used to build the names of the columns generated by this function
+ \return the boxplot graph
+
+
+
+ \see jkqtpstatGroupData(), \ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat
+*/
+template
+inline TGraph* jkqtpstatAddBoxplots(JKQTBasePlotter* plotter, InputCatIt inFirstCat_Y, InputCatIt inLastCat_Y, InputValueIt inFirstValue_Y, InputValueIt inLastValue_Y, double quantile1Spec=0.25, double quantile2Spec=0.75, double minimumQuantile=0, double maximumQuantile=1.0, JKQTPStatGroupDefinitionFunctor1D groupDefFunc=&jkqtpstatGroupingIdentity1D, const QString& columnBaseName=QString("grouped boxplot data")) {
+ std::map > groupeddataBar;
+ jkqtpstatGroupData(inFirstCat_Y, inLastCat_Y, inFirstValue_Y, inLastValue_Y, groupeddataBar, groupDefFunc);
+
+ size_t colGroup=plotter->getDatastore()->addColumn(columnBaseName+", group");
+ size_t colMin=plotter->getDatastore()->addColumn(columnBaseName+", minimum");
+ size_t colQ25=plotter->getDatastore()->addColumn(columnBaseName+", quartile25");
+ size_t colMedian=plotter->getDatastore()->addColumn(columnBaseName+", median");
+ size_t colIQRSig=plotter->getDatastore()->addColumn(columnBaseName+", MedianSignificance");
+ size_t colAverage=plotter->getDatastore()->addColumn(columnBaseName+", average");
+ size_t colQ75=plotter->getDatastore()->addColumn(columnBaseName+", quartile75");
+ size_t colMax=plotter->getDatastore()->addColumn(columnBaseName+", maximum");
+
+ for (auto it=groupeddataBar.begin(); it!=groupeddataBar.end(); ++it) {
+
+ auto stat5=jkqtpstat5NumberStatistics(it->second.begin(), it->second.end(), quantile1Spec, quantile2Spec, minimumQuantile, maximumQuantile);
+
+ plotter->getDatastore()->appendToColumn(colGroup, it->first);
+ plotter->getDatastore()->appendToColumn(colAverage, jkqtpstatAverage(it->second.begin(), it->second.end()));
+ plotter->getDatastore()->appendToColumn(colMin, stat5.minimum);
+ plotter->getDatastore()->appendToColumn(colQ25, stat5.quantile1);
+ plotter->getDatastore()->appendToColumn(colMedian, stat5.median);
+ plotter->getDatastore()->appendToColumn(colQ75, stat5.quantile2);
+ plotter->getDatastore()->appendToColumn(colMax, stat5.maximum);
+ plotter->getDatastore()->appendToColumn(colIQRSig, stat5.IQRSignificanceEstimate());
+ }
+
+ // 2.4. Finally the calculated groups are drawn
+ TGraph* graph;
+ plotter->addGraph(graph=new TGraph(plotter));
+ graph->setPositionColumn(colGroup);
+ graph->setMinColumn(colMin);
+ graph->setMaxColumn(colMax);
+ graph->setMedianColumn(colMedian);
+ graph->setMeanColumn(colAverage);
+ graph->setPercentile25Column(colQ25);
+ graph->setPercentile75Column(colQ75);
+ graph->setMedianConfidenceColumn(colIQRSig);
+
+ return graph;
+}
+
+/*! \brief create vertical boxplots of type \a JKQTPBoxplotVerticalGraph, from the 5-value-summary of groups in the input data
+ \ingroup jkqtptools_math_statistics_adaptors
+ \internal
+
+ \tparam InputCatIt standard iterator type of \a inFirstCat_Y and \a inLastCat_Y
+ \tparam InputValueIt standard iterator type of \a inFirstValue_X and \a inLastValue_X
+ \param plotter the plotter to which to add the resulting graph
+ \param inFirstCat_Y iterator pointing to the first item in the category dataset to use \f$ c_1 \f$ (used for y-coordinates)
+ \param inLastCat_Y iterator pointing behind the last item in the category dataset to use \f$ c_N \f$ (used for y-coordinates)
+ \param inFirstValue_X iterator pointing to the first item in the category dataset to use \f$ v_1 \f$ (used for x-coordinates)
+ \param inLastValue_X iterator pointing behind the last item in the category dataset to use \f$ v_N \f$ (used for x-coordinates)
+ \param quantile1Spec specifies which quantile to calculate for \a qantile1 (range: 0..1)
+ \param quantile2Spec specifies which quantile to calculate for \a qantile2 (range: 0..1)
+ \param minimumQuantile specifies a quantile for the return value minimum (default is 0 for the real minimum, but you could e.g. use 0.05 for the 5% quantile!)
+ \param maximumQuantile specifies a quantile for the return value maximum (default is 1 for the real maximum, but you could e.g. use 0.95 for the 95% quantile!)
+ \param groupDefFunc assigns a group \f$ c_{\text{out},j} \f$ to each category value \f$ c_i \f$ .
+ \param columnBaseName string component used to build the names of the columns generated by this function
+ \return the boxplot graph
+
+
+
+ \see jkqtpstatGroupData(), \ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat
+*/
+template
+inline JKQTPBoxplotVerticalGraph* jkqtpstatVAddBoxplots(JKQTBasePlotter* plotter, InputCatIt inFirstCat_Y, InputCatIt inLastCat_Y, InputValueIt inFirstValue_X, InputValueIt inLastValue_X, double quantile1Spec=0.25, double quantile2Spec=0.75, double minimumQuantile=0, double maximumQuantile=1.0, JKQTPStatGroupDefinitionFunctor1D groupDefFunc=&jkqtpstatGroupingIdentity1D, const QString& columnBaseName=QString("grouped boxplot data")) {
+
+ return jkqtpstatAddBoxplots(plotter, inFirstCat_Y, inLastCat_Y, inFirstValue_X, inLastValue_X, quantile1Spec, quantile2Spec, minimumQuantile, maximumQuantile, groupDefFunc, columnBaseName);
+}
+
+/*! \brief create horizontal boxplots of type \a JKQTPBoxplotHorizontalGraph, from the 5-value-summary of groups in the input data
+ \ingroup jkqtptools_math_statistics_adaptors
+ \internal
+
+ \tparam InputCatIt standard iterator type of \a inFirstCat_X and \a inLastCat_X
+ \tparam InputValueIt standard iterator type of \a inFirstValue_Y and \a inLastValue_Y
+ \param plotter the plotter to which to add the resulting graph
+ \param inFirstCat_X iterator pointing to the first item in the category dataset to use \f$ c_1 \f$ (used for y-coordinates)
+ \param inLastCat_X iterator pointing behind the last item in the category dataset to use \f$ c_N \f$ (used for y-coordinates)
+ \param inFirstValue_Y iterator pointing to the first item in the category dataset to use \f$ v_1 \f$ (used for x-coordinates)
+ \param inLastValue_Y iterator pointing behind the last item in the category dataset to use \f$ v_N \f$ (used for x-coordinates)
+ \param quantile1Spec specifies which quantile to calculate for \a qantile1 (range: 0..1)
+ \param quantile2Spec specifies which quantile to calculate for \a qantile2 (range: 0..1)
+ \param minimumQuantile specifies a quantile for the return value minimum (default is 0 for the real minimum, but you could e.g. use 0.05 for the 5% quantile!)
+ \param maximumQuantile specifies a quantile for the return value maximum (default is 1 for the real maximum, but you could e.g. use 0.95 for the 95% quantile!)
+ \param groupDefFunc assigns a group \f$ c_{\text{out},j} \f$ to each category value \f$ c_i \f$ .
+ \param columnBaseName string component used to build the names of the columns generated by this function
+ \return the boxplot graph
+
+
+
+ \see jkqtpstatGroupData(), \ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat
+*/
+template
+inline JKQTPBoxplotHorizontalGraph* jkqtpstatVAddBoxplots(JKQTBasePlotter* plotter, InputCatIt inFirstCat_X, InputCatIt inLastCat_X, InputValueIt inFirstValue_Y, InputValueIt inLastValue_Y, double quantile1Spec=0.25, double quantile2Spec=0.75, double minimumQuantile=0, double maximumQuantile=1.0, JKQTPStatGroupDefinitionFunctor1D groupDefFunc=&jkqtpstatGroupingIdentity1D, const QString& columnBaseName=QString("grouped boxplot data")) {
+
+ return jkqtpstatAddBoxplots(plotter, inFirstCat_X, inLastCat_X, inFirstValue_Y, inLastValue_Y, quantile1Spec, quantile2Spec, minimumQuantile, maximumQuantile, groupDefFunc, columnBaseName);
+}
+
+/*! \brief create vertical boxplots of type \a JKQTPBoxplotVerticalGraph, from the 5-value-summary of groups in the input data, also adds a graph showing the outliers
+ \ingroup jkqtptools_math_statistics_adaptors
+
+ \tparam InputCatIt standard iterator type of \a inFirstCat_X and \a inLastCat_X
+ \tparam InputValueIt standard iterator type of \a inFirstValue_Y and \a inLastValue_Y
+ \param plotter the plotter to which to add the resulting graph
+ \param inFirstCat_X iterator pointing to the first item in the category dataset to use \f$ c_1 \f$ (used for y-coordinates)
+ \param inLastCat_X iterator pointing behind the last item in the category dataset to use \f$ c_N \f$ (used for y-coordinates)
+ \param inFirstValue_Y iterator pointing to the first item in the category dataset to use \f$ v_1 \f$ (used for x-coordinates)
+ \param inLastValue_Y iterator pointing behind the last item in the category dataset to use \f$ v_N \f$ (used for x-coordinates)
+ \param quantile1Spec specifies which quantile to calculate for \a qantile1 (range: 0..1)
+ \param quantile2Spec specifies which quantile to calculate for \a qantile2 (range: 0..1)
+ \param minimumQuantile specifies a quantile for the return value minimum (default is 0 for the real minimum, but you could e.g. use 0.05 for the 5% quantile!)
+ \param maximumQuantile specifies a quantile for the return value maximum (default is 1 for the real maximum, but you could e.g. use 0.95 for the 95% quantile!)
+ \param groupDefFunc assigns a group \f$ c_{\text{out},j} \f$ to each category value \f$ c_i \f$ .
+ \param columnBaseName string component used to build the names of the columns generated by this function
+ \return the boxplot graph (return.first) and the outliers graph (return.second)
+
+
+
+ \see jkqtpstatGroupData(), \ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat
+*/
+template
+inline std::pair jkqtpstatAddVBoxplotsAndOutliers(JKQTBasePlotter* plotter, InputCatIt inFirstCat_X, InputCatIt inLastCat_X, InputValueIt inFirstValue_Y, InputValueIt inLastValue_Y, double quantile1Spec=0.25, double quantile2Spec=0.75, double minimumQuantile=0.03, double maximumQuantile=0.97, JKQTPStatGroupDefinitionFunctor1D groupDefFunc=&jkqtpstatGroupingIdentity1D, const QString& columnBaseName=QString("grouped boxplot data")) {
+ std::map > groupeddataBar;
+ jkqtpstatGroupData(inFirstCat_X, inLastCat_X, inFirstValue_Y, inLastValue_Y, groupeddataBar, groupDefFunc);
+
+ size_t colGroup=plotter->getDatastore()->addColumn(columnBaseName+", group");
+ size_t colMin=plotter->getDatastore()->addColumn(columnBaseName+", minimum");
+ size_t colQ25=plotter->getDatastore()->addColumn(columnBaseName+", quartile25");
+ size_t colMedian=plotter->getDatastore()->addColumn(columnBaseName+", median");
+ size_t colIQRSig=plotter->getDatastore()->addColumn(columnBaseName+", MedianSignificance");
+ size_t colAverage=plotter->getDatastore()->addColumn(columnBaseName+", average");
+ size_t colQ75=plotter->getDatastore()->addColumn(columnBaseName+", quartile75");
+ size_t colMax=plotter->getDatastore()->addColumn(columnBaseName+", maximum");
+ size_t colOutlierG=plotter->getDatastore()->addColumn(columnBaseName+", outlier-group");
+ size_t colOutlierV=plotter->getDatastore()->addColumn(columnBaseName+", outlier-value");
+
+ for (auto it=groupeddataBar.begin(); it!=groupeddataBar.end(); ++it) {
+
+ auto stat5=jkqtpstat5NumberStatistics(it->second.begin(), it->second.end(), quantile1Spec, quantile2Spec, minimumQuantile, maximumQuantile);
+
+ plotter->getDatastore()->appendToColumn(colGroup, it->first);
+ plotter->getDatastore()->appendToColumn(colAverage, jkqtpstatAverage(it->second.begin(), it->second.end()));
+ plotter->getDatastore()->appendToColumn(colMin, stat5.minimum);
+ plotter->getDatastore()->appendToColumn(colQ25, stat5.quantile1);
+ plotter->getDatastore()->appendToColumn(colMedian, stat5.median);
+ plotter->getDatastore()->appendToColumn(colQ75, stat5.quantile2);
+ plotter->getDatastore()->appendToColumn(colMax, stat5.maximum);
+ plotter->getDatastore()->appendToColumn(colIQRSig, stat5.IQRSignificanceEstimate());
+ std::fill_n(plotter->getDatastore()->backInserter(colOutlierG), stat5.outliers.size(), jkqtp_todouble(it->first));
+ plotter->getDatastore()->appendToColumn(colOutlierV, stat5.outliers.begin(), stat5.outliers.end());
+ }
+
+ JKQTPBoxplotVerticalGraph* graph;
+ plotter->addGraph(graph=new JKQTPBoxplotVerticalGraph(plotter));
+ graph->setPositionColumn(colGroup);
+ graph->setMinColumn(colMin);
+ graph->setMaxColumn(colMax);
+ graph->setMedianColumn(colMedian);
+ graph->setMeanColumn(colAverage);
+ graph->setPercentile25Column(colQ25);
+ graph->setPercentile75Column(colQ75);
+ graph->setMedianConfidenceColumn(colIQRSig);
+
+ JKQTPXYLineGraph* graphOL;
+ plotter->addGraph(graphOL=new JKQTPXYLineGraph(plotter));
+ graphOL->setXColumn(colOutlierG);
+ graphOL->setYColumn(colOutlierV);
+ graphOL->setDrawLine(false);
+ graphOL->setSymbolSize(graphOL->getSymbolSize()/2.0);
+ graphOL->setColor(graph->getLineColor());
+ return std::pair(graph, graphOL);
+}
+
+
+/*! \brief create vertical boxplots of type \a JKQTPBoxplotHorizontalGraph, from the 5-value-summary of groups in the input data, also adds a graph showing the outliers
+ \ingroup jkqtptools_math_statistics_adaptors
+
+ \tparam InputCatIt standard iterator type of \a inFirstCat_Y and \a inLastCat_Y
+ \tparam InputValueIt standard iterator type of \a inFirstValue_X and \a inLastValue_X
+ \param plotter the plotter to which to add the resulting graph
+ \param inFirstCat_Y iterator pointing to the first item in the category dataset to use \f$ c_1 \f$ (used for y-coordinates)
+ \param inLastCat_Y iterator pointing behind the last item in the category dataset to use \f$ c_N \f$ (used for y-coordinates)
+ \param inFirstValue_X iterator pointing to the first item in the category dataset to use \f$ v_1 \f$ (used for x-coordinates)
+ \param inLastValue_X iterator pointing behind the last item in the category dataset to use \f$ v_N \f$ (used for x-coordinates)
+ \param quantile1Spec specifies which quantile to calculate for \a qantile1 (range: 0..1)
+ \param quantile2Spec specifies which quantile to calculate for \a qantile2 (range: 0..1)
+ \param minimumQuantile specifies a quantile for the return value minimum (default is 0 for the real minimum, but you could e.g. use 0.05 for the 5% quantile!)
+ \param maximumQuantile specifies a quantile for the return value maximum (default is 1 for the real maximum, but you could e.g. use 0.95 for the 95% quantile!)
+ \param groupDefFunc assigns a group \f$ c_{\text{out},j} \f$ to each category value \f$ c_i \f$ .
+ \param columnBaseName string component used to build the names of the columns generated by this function
+ \return the boxplot graph (return.first) and the outliers graph (return.second)
+
+
+
+ \see jkqtpstatGroupData(), \ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat
+*/
+template
+inline std::pair jkqtpstatAddHBoxplotsAndOutliers(JKQTBasePlotter* plotter, InputCatIt inFirstCat_Y, InputCatIt inLastCat_Y, InputValueIt inFirstValue_X, InputValueIt inLastValue_X, double quantile1Spec=0.25, double quantile2Spec=0.75, double minimumQuantile=0.03, double maximumQuantile=0.97, JKQTPStatGroupDefinitionFunctor1D groupDefFunc=&jkqtpstatGroupingIdentity1D, const QString& columnBaseName=QString("grouped boxplot data")) {
+ std::map > groupeddataBar;
+ jkqtpstatGroupData(inFirstCat_Y, inLastCat_Y, inFirstValue_X, inLastValue_X, groupeddataBar, groupDefFunc);
+
+ size_t colGroup=plotter->getDatastore()->addColumn(columnBaseName+", group");
+ size_t colMin=plotter->getDatastore()->addColumn(columnBaseName+", minimum");
+ size_t colQ25=plotter->getDatastore()->addColumn(columnBaseName+", quartile25");
+ size_t colMedian=plotter->getDatastore()->addColumn(columnBaseName+", median");
+ size_t colIQRSig=plotter->getDatastore()->addColumn(columnBaseName+", MedianSignificance");
+ size_t colAverage=plotter->getDatastore()->addColumn(columnBaseName+", average");
+ size_t colQ75=plotter->getDatastore()->addColumn(columnBaseName+", quartile75");
+ size_t colMax=plotter->getDatastore()->addColumn(columnBaseName+", maximum");
+ size_t colOutlierG=plotter->getDatastore()->addColumn(columnBaseName+", outlier-group");
+ size_t colOutlierV=plotter->getDatastore()->addColumn(columnBaseName+", outlier-value");
+
+ for (auto it=groupeddataBar.begin(); it!=groupeddataBar.end(); ++it) {
+
+ auto stat5=jkqtpstat5NumberStatistics(it->second.begin(), it->second.end(), quantile1Spec, quantile2Spec, minimumQuantile, maximumQuantile);
+
+ plotter->getDatastore()->appendToColumn(colGroup, it->first);
+ plotter->getDatastore()->appendToColumn(colAverage, jkqtpstatAverage(it->second.begin(), it->second.end()));
+ plotter->getDatastore()->appendToColumn(colMin, stat5.minimum);
+ plotter->getDatastore()->appendToColumn(colQ25, stat5.quantile1);
+ plotter->getDatastore()->appendToColumn(colMedian, stat5.median);
+ plotter->getDatastore()->appendToColumn(colQ75, stat5.quantile2);
+ plotter->getDatastore()->appendToColumn(colMax, stat5.maximum);
+ plotter->getDatastore()->appendToColumn(colIQRSig, stat5.IQRSignificanceEstimate());
+ std::fill_n(plotter->getDatastore()->backInserter(colOutlierG), stat5.outliers.size(), jkqtp_todouble(it->first));
+ plotter->getDatastore()->appendToColumn(colOutlierV, stat5.outliers.begin(), stat5.outliers.end());
+ }
+
+ JKQTPBoxplotHorizontalGraph* graph;
+ plotter->addGraph(graph=new JKQTPBoxplotHorizontalGraph(plotter));
+ graph->setPositionColumn(colGroup);
+ graph->setMinColumn(colMin);
+ graph->setMaxColumn(colMax);
+ graph->setMedianColumn(colMedian);
+ graph->setMeanColumn(colAverage);
+ graph->setPercentile25Column(colQ25);
+ graph->setPercentile75Column(colQ75);
+ graph->setMedianConfidenceColumn(colIQRSig);
+
+ JKQTPXYLineGraph* graphOL;
+ plotter->addGraph(graphOL=new JKQTPXYLineGraph(plotter));
+ graphOL->setYColumn(colOutlierG);
+ graphOL->setXColumn(colOutlierV);
+ graphOL->setDrawLine(false);
+ graphOL->setSymbolSize(graphOL->getSymbolSize()/2.0);
+ graphOL->setColor(graph->getLineColor());
+ return std::pair(graph, graphOL);
+}
+
+
+
+
+
+
#endif // JKQTPGRAPHSSTATISTICSADAPTORS_H_INCLUDED
diff --git a/screenshots/jkqtplotter_simpletest_datastore_groupedstat.png b/screenshots/jkqtplotter_simpletest_datastore_groupedstat.png
new file mode 100644
index 0000000000..06555f908e
Binary files /dev/null and b/screenshots/jkqtplotter_simpletest_datastore_groupedstat.png differ
diff --git a/screenshots/jkqtplotter_simpletest_datastore_groupedstat_barchart.png b/screenshots/jkqtplotter_simpletest_datastore_groupedstat_barchart.png
new file mode 100644
index 0000000000..17bf29e80a
Binary files /dev/null and b/screenshots/jkqtplotter_simpletest_datastore_groupedstat_barchart.png differ
diff --git a/screenshots/jkqtplotter_simpletest_datastore_groupedstat_barchartrawdata.png b/screenshots/jkqtplotter_simpletest_datastore_groupedstat_barchartrawdata.png
new file mode 100644
index 0000000000..738c1e5925
Binary files /dev/null and b/screenshots/jkqtplotter_simpletest_datastore_groupedstat_barchartrawdata.png differ
diff --git a/screenshots/jkqtplotter_simpletest_datastore_groupedstat_boxplot.png b/screenshots/jkqtplotter_simpletest_datastore_groupedstat_boxplot.png
new file mode 100644
index 0000000000..38897633ea
Binary files /dev/null and b/screenshots/jkqtplotter_simpletest_datastore_groupedstat_boxplot.png differ
diff --git a/screenshots/jkqtplotter_simpletest_datastore_groupedstat_scatter.png b/screenshots/jkqtplotter_simpletest_datastore_groupedstat_scatter.png
new file mode 100644
index 0000000000..5d34a9fd96
Binary files /dev/null and b/screenshots/jkqtplotter_simpletest_datastore_groupedstat_scatter.png differ
diff --git a/screenshots/jkqtplotter_simpletest_datastore_groupedstat_scatterrawdata.png b/screenshots/jkqtplotter_simpletest_datastore_groupedstat_scatterrawdata.png
new file mode 100644
index 0000000000..ef73c4c8c0
Binary files /dev/null and b/screenshots/jkqtplotter_simpletest_datastore_groupedstat_scatterrawdata.png differ
diff --git a/screenshots/jkqtplotter_simpletest_datastore_groupedstat_small.png b/screenshots/jkqtplotter_simpletest_datastore_groupedstat_small.png
new file mode 100644
index 0000000000..4d47f8c16a
Binary files /dev/null and b/screenshots/jkqtplotter_simpletest_datastore_groupedstat_small.png differ
|