next commit
This commit is contained in:
141
plots/PlotErrFunc.h
Normal file
141
plots/PlotErrFunc.h
Normal file
@@ -0,0 +1,141 @@
|
||||
#ifndef PLOTERRFUNC_H
|
||||
#define PLOTERRFUNC_H
|
||||
|
||||
#include <KLib/math/statistics/Statistics.h>
|
||||
|
||||
#include <KLib/misc/gnuplot/Gnuplot.h>
|
||||
#include <KLib/misc/gnuplot/GnuplotPlot.h>
|
||||
#include <KLib/misc/gnuplot/GnuplotPlotElementLines.h>
|
||||
|
||||
|
||||
/**
|
||||
* helper class to plot error development stored within Statistics<T>.
|
||||
* statistics are given as pointers and may be altered outside.
|
||||
* when plot() is called, everything is rebuild using the current contents
|
||||
* of each Statistics<T> object
|
||||
*/
|
||||
class PlotErrFunc {
|
||||
|
||||
/** group name and statistics together */
|
||||
struct Entry {
|
||||
std::string name;
|
||||
const K::Statistics<float>* stats;
|
||||
K::GnuplotPlotElementLines* line = nullptr;
|
||||
Entry(const std::string& name, const K::Statistics<float>* stats) : name(name), stats(stats) {;}
|
||||
};
|
||||
|
||||
|
||||
std::vector<Entry> entries;
|
||||
|
||||
K::Gnuplot gp;
|
||||
K::GnuplotPlot gplot;
|
||||
|
||||
//std::vector<std::string> colors = {"#000000", "#ff0000", "#00bb00", "#0000ff"};
|
||||
std::vector<std::string> colors = {"#000000", "#999999", "#0000ff", "#9999ff", "#ff0000"};
|
||||
|
||||
bool markers = false;
|
||||
|
||||
std::string codeFile;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/** ctor with x-axis label */
|
||||
PlotErrFunc(const std::string& xLabel, const std::string& yLabel) {
|
||||
gplot.setLabelX(xLabel);
|
||||
gplot.setLabelY(yLabel);
|
||||
gplot.setRangeX(K::GnuplotAxisRange(0, K::GnuplotAxisRange::AUTO));
|
||||
gplot.setRangeY(K::GnuplotAxisRange(0, K::GnuplotAxisRange::AUTO));
|
||||
}
|
||||
|
||||
/** add one curve. Statistics<T> are allowed to be altered outside afterwards! */
|
||||
void add(const std::string name, const K::Statistics<float>* stats) {
|
||||
Entry entry(name, stats);
|
||||
entry.line = new K::GnuplotPlotElementLines();
|
||||
entry.line->setTitle(name);
|
||||
entry.line->setLineWidth(2);
|
||||
gplot.add(entry.line);
|
||||
entries.push_back(entry);
|
||||
}
|
||||
|
||||
/** remove all previously added entries */
|
||||
void clear() {
|
||||
for (Entry& e : entries) {
|
||||
gplot.remove(e.line);
|
||||
delete e.line;
|
||||
}
|
||||
entries.clear();
|
||||
}
|
||||
|
||||
K::Gnuplot& getGP() {
|
||||
return gp;
|
||||
}
|
||||
|
||||
void writeCodeTo(const std::string& file) {
|
||||
this->codeFile = file;
|
||||
}
|
||||
|
||||
void showMarkers(const bool show) {
|
||||
this->markers = show;
|
||||
}
|
||||
|
||||
/** plot all curves */
|
||||
void plot() {
|
||||
|
||||
gp << "set grid\n";
|
||||
|
||||
for (size_t i = 0; i < entries.size(); ++i) {
|
||||
|
||||
const Entry& e = entries[i];
|
||||
|
||||
e.line->clear();
|
||||
e.line->setColorHex(colors[i]);
|
||||
|
||||
// distancen between min and max
|
||||
const float minX = e.stats->getQuantile(0);
|
||||
const float range = e.stats->getQuantile(0.85) - minX;
|
||||
const float space = range * 0.07;
|
||||
|
||||
// 0 - 80%
|
||||
for (int j = 0; j <= 85; j+= 5) {
|
||||
const float y = j / 100.0f;
|
||||
const float x = e.stats->getQuantile(y);
|
||||
K::GnuplotPoint2 gp2(x, y*100);
|
||||
e.line->add(gp2);
|
||||
|
||||
|
||||
|
||||
if (markers) {
|
||||
int id = (i+1) * 100;
|
||||
if (j == 50) {
|
||||
gp << "set object " << id+1 << " circle at " << x << "," << j << " size screen 0.02,0.02\n";
|
||||
gp << "set label " << id+2 << " at " << x+space << "," << j << " '" << x << "'\n";
|
||||
gp << "set arrow " << id+3 << " from " << x << "," << 0 << " to " << x << "," << j << " nohead\n";
|
||||
gp << "set arrow " << id+4 << " from " << 0 << "," << j << " to " << x << "," << j << " nohead\n";
|
||||
} else if (j == 75) {
|
||||
gp << "set object " << id+5 << " circle at " << x << "," << j << " size screen 0.02,0.02\n";
|
||||
gp << "set label " << id+6 << " at " << x+space << "," << j << " '" << x << "'\n";
|
||||
gp << "set arrow " << id+7 << " from " << x << "," << 0 << " to " << x << "," << j << " nohead\n";
|
||||
gp << "set arrow " << id+8 << " from " << 0 << "," << j << " to " << x << "," << j << " nohead\n";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
gp.draw(gplot);
|
||||
|
||||
if (codeFile != "") {
|
||||
std::ofstream out(codeFile);
|
||||
out << gp.getBuffer();
|
||||
out.close();
|
||||
}
|
||||
|
||||
gp.flush();
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // PLOTERRFUNC_H
|
||||
Reference in New Issue
Block a user