Commit 6ebad57b201989a25d35171b914269ac7876eeab
1 parent
cb9c5416
Sample ROC points at fixed FAR values for easy vertical averaging. Display conf…
…idence intervals in tables and plots.
Showing
2 changed files
with
71 additions
and
50 deletions
openbr/core/eval.cpp
| @@ -48,22 +48,26 @@ struct OperatingPoint | @@ -48,22 +48,26 @@ struct OperatingPoint | ||
| 48 | : score(_score), FAR(_FAR), TAR(_TAR) {} | 48 | : score(_score), FAR(_FAR), TAR(_TAR) {} |
| 49 | }; | 49 | }; |
| 50 | 50 | ||
| 51 | -static float getTAR(const QList<OperatingPoint> &operatingPoints, float FAR) | 51 | +static OperatingPoint getOperatingPoint(const QList<OperatingPoint> &operatingPoints, float FAR) |
| 52 | { | 52 | { |
| 53 | int index = 0; | 53 | int index = 0; |
| 54 | while (operatingPoints[index].FAR < FAR) { | 54 | while (operatingPoints[index].FAR < FAR) { |
| 55 | index++; | 55 | index++; |
| 56 | if (index == operatingPoints.size()) | 56 | if (index == operatingPoints.size()) |
| 57 | - return 1; | 57 | + return OperatingPoint(operatingPoints.last().score, FAR, operatingPoints.last().TAR); |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | - const float x1 = (index == 0 ? 0 : operatingPoints[index-1].FAR); | ||
| 61 | - const float y1 = (index == 0 ? 0 : operatingPoints[index-1].TAR); | ||
| 62 | - const float x2 = operatingPoints[index].FAR; | ||
| 63 | - const float y2 = operatingPoints[index].TAR; | ||
| 64 | - const float m = (y2 - y1) / (x2 - x1); | ||
| 65 | - const float b = y1 - m*x1; | ||
| 66 | - return m * FAR + b; | 60 | + const float FAR1 = (index == 0 ? 0 : operatingPoints[index-1].FAR); |
| 61 | + const float TAR1 = (index == 0 ? 0 : operatingPoints[index-1].TAR); | ||
| 62 | + const float score1 = (index == 0 ? operatingPoints[index].score : operatingPoints[index-1].score); | ||
| 63 | + const float FAR2 = operatingPoints[index].FAR; | ||
| 64 | + const float TAR2 = operatingPoints[index].TAR; | ||
| 65 | + const float score2 = operatingPoints[index].score; | ||
| 66 | + const float mTAR = (TAR2 - TAR1) / (FAR2 - FAR1); | ||
| 67 | + const float bTAR = TAR1 - mTAR*FAR1; | ||
| 68 | + const float mScore = (score2 - score1) / (FAR2 - FAR1); | ||
| 69 | + const float bScore = score1 - mScore*FAR1; | ||
| 70 | + return OperatingPoint(mScore * FAR + bScore,FAR, mTAR * FAR + bTAR); | ||
| 67 | } | 71 | } |
| 68 | 72 | ||
| 69 | static float getCMC(const QVector<int> &firstGenuineReturns, int rank) | 73 | static float getCMC(const QVector<int> &firstGenuineReturns, int rank) |
| @@ -266,23 +270,26 @@ float Evaluate(const Mat &simmat, const Mat &mask, const QString &csv, const QSt | @@ -266,23 +270,26 @@ float Evaluate(const Mat &simmat, const Mat &mask, const QString &csv, const QSt | ||
| 266 | } | 270 | } |
| 267 | 271 | ||
| 268 | // Write Detection Error Tradeoff (DET), PRE, REC | 272 | // Write Detection Error Tradeoff (DET), PRE, REC |
| 269 | - int points = qMin(operatingPoints.size(), Max_Points); | ||
| 270 | - for (int i=0; i<points; i++) { | ||
| 271 | - const OperatingPoint &operatingPoint = operatingPoints[double(i) / double(points-1) * double(operatingPoints.size()-1)]; | ||
| 272 | - lines.append(QString("DET,%1,%2").arg(QString::number(operatingPoint.FAR), | 273 | + float FAR=0.000001; |
| 274 | + for (int i=0; i<Max_Points; i++) { | ||
| 275 | + OperatingPoint operatingPoint = getOperatingPoint(operatingPoints, FAR); | ||
| 276 | + lines.append(QString("DET,%1,%2").arg(QString::number(FAR), | ||
| 273 | QString::number(1-operatingPoint.TAR))); | 277 | QString::number(1-operatingPoint.TAR))); |
| 274 | lines.append(QString("FAR,%1,%2").arg(QString::number(operatingPoint.score), | 278 | lines.append(QString("FAR,%1,%2").arg(QString::number(operatingPoint.score), |
| 275 | - QString::number(operatingPoint.FAR))); | 279 | + QString::number(FAR))); |
| 276 | lines.append(QString("FRR,%1,%2").arg(QString::number(operatingPoint.score), | 280 | lines.append(QString("FRR,%1,%2").arg(QString::number(operatingPoint.score), |
| 277 | QString::number(1-operatingPoint.TAR))); | 281 | QString::number(1-operatingPoint.TAR))); |
| 282 | + //multiplier roughly spans 10E-6 to 1 | ||
| 283 | + FAR *=1.02807; | ||
| 278 | } | 284 | } |
| 285 | + | ||
| 279 | // Write FAR/TAR Table (FT) | 286 | // Write FAR/TAR Table (FT) |
| 280 | - lines.append(qPrintable(QString("FT,0.000001,%1").arg(QString::number(getTAR(operatingPoints, 0.000001), 'f', 3)))); | ||
| 281 | - lines.append(qPrintable(QString("FT,0.00001,%1").arg(QString::number(getTAR(operatingPoints, 0.00001), 'f', 3)))); | ||
| 282 | - lines.append(qPrintable(QString("FT,0.0001,%1").arg(QString::number(getTAR(operatingPoints, 0.0001), 'f', 3)))); | ||
| 283 | - lines.append(qPrintable(QString("FT,0.001,%1").arg(QString::number(getTAR(operatingPoints, 0.001), 'f', 3)))); | ||
| 284 | - lines.append(qPrintable(QString("FT,0.01,%1").arg(QString::number(getTAR(operatingPoints, 0.01), 'f', 3)))); | ||
| 285 | - lines.append(qPrintable(QString("FT,0.1,%1").arg(QString::number(getTAR(operatingPoints, 0.1), 'f', 3)))); | 287 | + lines.append(qPrintable(QString("FT,0.000001,%1").arg(QString::number(getOperatingPoint(operatingPoints, 0.000001).TAR, 'f', 3)))); |
| 288 | + lines.append(qPrintable(QString("FT,0.00001,%1").arg(QString::number(getOperatingPoint(operatingPoints, 0.00001).TAR, 'f', 3)))); | ||
| 289 | + lines.append(qPrintable(QString("FT,0.0001,%1").arg(QString::number(getOperatingPoint(operatingPoints, 0.0001).TAR, 'f', 3)))); | ||
| 290 | + lines.append(qPrintable(QString("FT,0.001,%1").arg(QString::number(getOperatingPoint(operatingPoints, 0.001).TAR, 'f', 3)))); | ||
| 291 | + lines.append(qPrintable(QString("FT,0.01,%1").arg(QString::number(getOperatingPoint(operatingPoints, 0.01).TAR, 'f', 3)))); | ||
| 292 | + lines.append(qPrintable(QString("FT,0.1,%1").arg(QString::number(getOperatingPoint(operatingPoints, 0.1).TAR, 'f', 3)))); | ||
| 286 | 293 | ||
| 287 | //Write CMC Table (CT) | 294 | //Write CMC Table (CT) |
| 288 | lines.append(qPrintable(QString("CT,1,%1").arg(QString::number(getCMC(firstGenuineReturns, 1), 'f', 3)))); | 295 | lines.append(qPrintable(QString("CT,1,%1").arg(QString::number(getCMC(firstGenuineReturns, 1), 'f', 3)))); |
| @@ -293,19 +300,18 @@ float Evaluate(const Mat &simmat, const Mat &mask, const QString &csv, const QSt | @@ -293,19 +300,18 @@ float Evaluate(const Mat &simmat, const Mat &mask, const QString &csv, const QSt | ||
| 293 | lines.append(qPrintable(QString("CT,100,%1").arg(QString::number(getCMC(firstGenuineReturns, 100), 'f', 3)))); | 300 | lines.append(qPrintable(QString("CT,100,%1").arg(QString::number(getCMC(firstGenuineReturns, 100), 'f', 3)))); |
| 294 | 301 | ||
| 295 | // Write FAR/TAR Bar Chart (BC) | 302 | // Write FAR/TAR Bar Chart (BC) |
| 296 | - lines.append(qPrintable(QString("BC,0.001,%1").arg(QString::number(getTAR(operatingPoints, 0.001), 'f', 3)))); | ||
| 297 | - lines.append(qPrintable(QString("BC,0.01,%1").arg(QString::number(result = getTAR(operatingPoints, 0.01), 'f', 3)))); | 303 | + lines.append(qPrintable(QString("BC,0.001,%1").arg(QString::number(getOperatingPoint(operatingPoints, 0.001).TAR, 'f', 3)))); |
| 304 | + lines.append(qPrintable(QString("BC,0.01,%1").arg(QString::number(result = getOperatingPoint(operatingPoints, 0.01).TAR, 'f', 3)))); | ||
| 298 | 305 | ||
| 299 | // Attempt to read template size from enrolled gallery and write to output CSV | 306 | // Attempt to read template size from enrolled gallery and write to output CSV |
| 300 | size_t maxSize(0); | 307 | size_t maxSize(0); |
| 301 | if (target.endsWith(".gal")) { | 308 | if (target.endsWith(".gal")) { |
| 302 | foreach (const Template &t, TemplateList::fromGallery(target)) maxSize = max(maxSize, t.bytes()); | 309 | foreach (const Template &t, TemplateList::fromGallery(target)) maxSize = max(maxSize, t.bytes()); |
| 310 | + lines.append(QString("TS,,%1").arg(QString::number(maxSize))); | ||
| 303 | } | 311 | } |
| 304 | 312 | ||
| 305 | - lines.append(QString("TS,,%1").arg(QString::number(maxSize))); | ||
| 306 | - | ||
| 307 | // Write SD & KDE | 313 | // Write SD & KDE |
| 308 | - points = qMin(qMin(Max_Points, genuines.size()), impostors.size()); | 314 | + int points = qMin(qMin(Max_Points, genuines.size()), impostors.size()); |
| 309 | QList<double> sampledGenuineScores; sampledGenuineScores.reserve(points); | 315 | QList<double> sampledGenuineScores; sampledGenuineScores.reserve(points); |
| 310 | QList<double> sampledImpostorScores; sampledImpostorScores.reserve(points); | 316 | QList<double> sampledImpostorScores; sampledImpostorScores.reserve(points); |
| 311 | 317 | ||
| @@ -332,10 +338,10 @@ float Evaluate(const Mat &simmat, const Mat &mask, const QString &csv, const QSt | @@ -332,10 +338,10 @@ float Evaluate(const Mat &simmat, const Mat &mask, const QString &csv, const QSt | ||
| 332 | 338 | ||
| 333 | QtUtils::writeFile(csv, lines); | 339 | QtUtils::writeFile(csv, lines); |
| 334 | if (maxSize > 0) qDebug("Template Size: %i bytes", (int)maxSize); | 340 | if (maxSize > 0) qDebug("Template Size: %i bytes", (int)maxSize); |
| 335 | - qDebug("TAR @ FAR = 0.01: %.3f",getTAR(operatingPoints, 0.01)); | ||
| 336 | - qDebug("TAR @ FAR = 0.001: %.3f",getTAR(operatingPoints, 0.001)); | ||
| 337 | - qDebug("TAR @ FAR = 0.0001: %.3f",getTAR(operatingPoints, 0.0001)); | ||
| 338 | - qDebug("TAR @ FAR = 0.00001: %.3f",getTAR(operatingPoints, 0.00001)); | 341 | + qDebug("TAR @ FAR = 0.01: %.3f",getOperatingPoint(operatingPoints, 0.01).TAR); |
| 342 | + qDebug("TAR @ FAR = 0.001: %.3f",getOperatingPoint(operatingPoints, 0.001).TAR); | ||
| 343 | + qDebug("TAR @ FAR = 0.0001: %.3f",getOperatingPoint(operatingPoints, 0.0001).TAR); | ||
| 344 | + qDebug("TAR @ FAR = 0.00001: %.3f",getOperatingPoint(operatingPoints, 0.00001).TAR); | ||
| 339 | 345 | ||
| 340 | qDebug("\nRetrieval Rate @ Rank = %d: %.3f", Report_Retrieval, getCMC(firstGenuineReturns, Report_Retrieval)); | 346 | qDebug("\nRetrieval Rate @ Rank = %d: %.3f", Report_Retrieval, getCMC(firstGenuineReturns, Report_Retrieval)); |
| 341 | 347 | ||
| @@ -560,8 +566,8 @@ float InplaceEval(const QString &simmat, const QString &target, const QString &q | @@ -560,8 +566,8 @@ float InplaceEval(const QString &simmat, const QString &target, const QString &q | ||
| 560 | 566 | ||
| 561 | float result; | 567 | float result; |
| 562 | // Write FAR/TAR Bar Chart (BC) | 568 | // Write FAR/TAR Bar Chart (BC) |
| 563 | - lines.append(qPrintable(QString("BC,0.001,%1").arg(QString::number(getTAR(operatingPoints, 0.001), 'f', 3)))); | ||
| 564 | - lines.append(qPrintable(QString("BC,0.01,%1").arg(QString::number(result = getTAR(operatingPoints, 0.01), 'f', 3)))); | 569 | + lines.append(qPrintable(QString("BC,0.001,%1").arg(QString::number(getOperatingPoint(operatingPoints, 0.001).TAR, 'f', 3)))); |
| 570 | + lines.append(qPrintable(QString("BC,0.01,%1").arg(QString::number(result = getOperatingPoint(operatingPoints, 0.01).TAR, 'f', 3)))); | ||
| 565 | 571 | ||
| 566 | qDebug("TAR @ FAR = 0.01: %.3f", result); | 572 | qDebug("TAR @ FAR = 0.01: %.3f", result); |
| 567 | QtUtils::writeFile(csv, lines); | 573 | QtUtils::writeFile(csv, lines); |
openbr/core/plot.cpp
| @@ -108,7 +108,6 @@ struct RPlot | @@ -108,7 +108,6 @@ struct RPlot | ||
| 108 | pivotItems = QVector< QSet<QString> >(pivotHeaders.size()); | 108 | pivotItems = QVector< QSet<QString> >(pivotHeaders.size()); |
| 109 | foreach (const QString &fileName, files) { | 109 | foreach (const QString &fileName, files) { |
| 110 | QStringList pivots = getPivots(fileName, false); | 110 | QStringList pivots = getPivots(fileName, false); |
| 111 | - | ||
| 112 | // If the number of pivots don't match, abandon the directory/filename labeling scheme | 111 | // If the number of pivots don't match, abandon the directory/filename labeling scheme |
| 113 | if (pivots.size() != pivotHeaders.size()) { | 112 | if (pivots.size() != pivotHeaders.size()) { |
| 114 | pivots.clear(); | 113 | pivots.clear(); |
| @@ -132,7 +131,6 @@ struct RPlot | @@ -132,7 +131,6 @@ struct RPlot | ||
| 132 | minor = Pivot(i, size, pivotHeaders[i]); | 131 | minor = Pivot(i, size, pivotHeaders[i]); |
| 133 | } | 132 | } |
| 134 | } | 133 | } |
| 135 | - | ||
| 136 | const QString &smooth = destination.get<QString>("smooth", ""); | 134 | const QString &smooth = destination.get<QString>("smooth", ""); |
| 137 | major.smooth = !smooth.isEmpty() && (major.header == smooth) && (major.size > 1); | 135 | major.smooth = !smooth.isEmpty() && (major.header == smooth) && (major.size > 1); |
| 138 | minor.smooth = !smooth.isEmpty() && (minor.header == smooth) && (minor.size > 1); | 136 | minor.smooth = !smooth.isEmpty() && (minor.header == smooth) && (minor.size > 1); |
| @@ -177,29 +175,42 @@ struct RPlot | @@ -177,29 +175,42 @@ struct RPlot | ||
| 177 | "TS$Y <- as.character(TS$Y)\n" | 175 | "TS$Y <- as.character(TS$Y)\n" |
| 178 | "CMC$Y <- as.numeric(as.character(CMC$Y))\n" | 176 | "CMC$Y <- as.numeric(as.character(CMC$Y))\n" |
| 179 | "\n" | 177 | "\n" |
| 178 | + "if (%1) {\n\tsummarySE <- function(data=NULL, measurevar, groupvars=NULL, na.rm=FALSE, conf.interval=.95, .drop=TRUE) {\n\t\t" | ||
| 179 | + "require(plyr)\n\n\t\tlength2 <- function (x, na.rm=FALSE) {\n\t\t\tif (na.rm) sum(!is.na(x))\n\t\t\telse length(x)" | ||
| 180 | + "\n\t\t}\n\n\t\tdatac <- ddply(data, groupvars, .drop=.drop, .fun = function(xx, col) {\n\t\t\t" | ||
| 181 | + "c(N=length2(xx[[col]], na.rm=na.rm), mean=mean(xx[[col]], na.rm=na.rm), sd=sd(xx[[col]], na.rm=na.rm))\n\t\t\t}," | ||
| 182 | + "\n\t\t\tmeasurevar\n\t\t)\n\n\t\tdatac <- rename(datac, c(\"mean\" = measurevar))\n\t\tdatac$se <- datac$sd / sqrt(datac$N)" | ||
| 183 | + "\n\t\tciMult <- qt(conf.interval/2 + .5, datac$N-1)\n\t\tdatac$ci <- datac$se * ciMult\n\n\t\treturn(datac)\n\t}\n\t" | ||
| 184 | + "DET <- summarySE(DET, measurevar=\"Y\", groupvars=c(\"%2\", \"X\"))\n\t" | ||
| 185 | + "ERR <- summarySE(ERR, measurevar=\"X\", groupvars=c(\"Error\", \"%2\", \"Y\"))\n\t" | ||
| 186 | + "FT <- summarySE(FT, measurevar=\"Y\", groupvars=c(\"%2\", \"X\"))\n\t" | ||
| 187 | + "CT <- summarySE(CT, measurevar=\"Y\", groupvars=c(\"%2\", \"X\"))\n}\n\n" | ||
| 180 | "# Code to format FAR values\n" | 188 | "# Code to format FAR values\n" |
| 181 | "far_names <- list('0.001'=\"FAR = 0.1%\", '0.01'=\"FAR = 1%\")\n" | 189 | "far_names <- list('0.001'=\"FAR = 0.1%\", '0.01'=\"FAR = 1%\")\n" |
| 182 | "far_labeller <- function(variable,value) { return(far_names[as.character(value)]) }\n" | 190 | "far_labeller <- function(variable,value) { return(far_names[as.character(value)]) }\n" |
| 183 | "\n" | 191 | "\n" |
| 184 | "# Code to format TAR@FAR table\n" | 192 | "# Code to format TAR@FAR table\n" |
| 185 | - "algs <- unique(FT$%1)\n" | 193 | + "algs <- unique(FT$%2)\n" |
| 186 | "algs <- algs[!duplicated(algs)]\n" | 194 | "algs <- algs[!duplicated(algs)]\n" |
| 187 | - "mat <- matrix(FT$Y,nrow=6,ncol=length(algs),byrow=FALSE)\n" | 195 | + "mat <- matrix(%3,nrow=6,ncol=length(algs),byrow=FALSE)\n" |
| 188 | "colnames(mat) <- algs \n" | 196 | "colnames(mat) <- algs \n" |
| 189 | "rownames(mat) <- c(\"FAR = 1e-06\", \"FAR = 1e-05\", \"FAR = 1e-04\", \"FAR = 1e-03\", \"FAR = 1e-02\", \"FAR = 1e-01\")\n" | 197 | "rownames(mat) <- c(\"FAR = 1e-06\", \"FAR = 1e-05\", \"FAR = 1e-04\", \"FAR = 1e-03\", \"FAR = 1e-02\", \"FAR = 1e-01\")\n" |
| 190 | "FTtable <- as.table(mat)\n" | 198 | "FTtable <- as.table(mat)\n" |
| 191 | "\n" | 199 | "\n" |
| 192 | "# Code to format CMC Table\n" | 200 | "# Code to format CMC Table\n" |
| 193 | - "mat <- matrix(CT$Y,nrow=6,ncol=length(algs),byrow=FALSE)\n" | 201 | + "mat <- matrix(%4,nrow=6,ncol=length(algs),byrow=FALSE)\n" |
| 194 | "colnames(mat) <- algs \n" | 202 | "colnames(mat) <- algs \n" |
| 195 | "rownames(mat) <- c(\" Rank 1\", \"Rank 5\", \"Rank 10\", \"Rank 20\", \"Rank 50\", \"Rank 100\")\n" | 203 | "rownames(mat) <- c(\" Rank 1\", \"Rank 5\", \"Rank 10\", \"Rank 20\", \"Rank 50\", \"Rank 100\")\n" |
| 196 | "CMCtable <- as.table(mat)\n" | 204 | "CMCtable <- as.table(mat)\n" |
| 197 | "\n" | 205 | "\n" |
| 198 | "# Code to format Template Size Table\n" | 206 | "# Code to format Template Size Table\n" |
| 199 | - "mat <- matrix(TS$Y,nrow=1,ncol=length(algs),byrow=FALSE)\n" | ||
| 200 | - "colnames(mat) <- algs\n" | ||
| 201 | - "rownames(mat) <- c(\"Template Size (bytes):\")\n" | ||
| 202 | - "TStable <- as.table(mat)\n").arg(major.header))); | 207 | + "if (nrow(TS) != 0) {\n\t" |
| 208 | + "mat <- matrix(TS$Y,nrow=1,ncol=length(algs),byrow=FALSE)\n\t" | ||
| 209 | + "colnames(mat) <- algs\n\t" | ||
| 210 | + "rownames(mat) <- c(\"Template Size (bytes):\")\n\t" | ||
| 211 | + "TStable <- as.table(mat)\n}\n").arg(((major.smooth || minor.smooth) ? "TRUE" : "FALSE"), major.size > 1 ? major.header : (minor.header.isEmpty() ? major.header : minor.header), | ||
| 212 | + (major.smooth || minor.smooth) ? "paste(as.character(round(FT$Y, 3)), round(FT$ci, 3), sep=\"\\u00b1\")" : "FT$Y", | ||
| 213 | + (major.smooth || minor.smooth) ? "paste(as.character(round(CT$Y, 3)), round(CT$ci, 3), sep=\"\\u00b1\")" : "CT$Y"))); | ||
| 203 | 214 | ||
| 204 | // Open output device | 215 | // Open output device |
| 205 | file.write(qPrintable(QString("\n" | 216 | file.write(qPrintable(QString("\n" |
| @@ -231,8 +242,9 @@ struct RPlot | @@ -231,8 +242,9 @@ struct RPlot | ||
| 231 | "print(title(\"Table of True Accept Rates at various False Accept Rates\"))\n" | 242 | "print(title(\"Table of True Accept Rates at various False Accept Rates\"))\n" |
| 232 | "print(textplot(CMCtable))\n" | 243 | "print(textplot(CMCtable))\n" |
| 233 | "print(title(\"Table of retrieval rate at various ranks\"))\n" | 244 | "print(title(\"Table of retrieval rate at various ranks\"))\n" |
| 234 | - "print(textplot(TStable, cex=1.15))\n" | ||
| 235 | - "print(title(\"Template Size by Algorithm\"))\n"; | 245 | + "if (nrow(TS) != 0) {\n\t" |
| 246 | + "print(textplot(TStable, cex=1.15))\n\t" | ||
| 247 | + "print(title(\"Template Size by Algorithm\"))\n}\n"; | ||
| 236 | file.write(qPrintable(textplot.arg(PRODUCT_NAME, PRODUCT_VERSION))); | 248 | file.write(qPrintable(textplot.arg(PRODUCT_NAME, PRODUCT_VERSION))); |
| 237 | } | 249 | } |
| 238 | 250 | ||
| @@ -281,11 +293,12 @@ bool Plot(const QStringList &files, const File &destination, bool show) | @@ -281,11 +293,12 @@ bool Plot(const QStringList &files, const File &destination, bool show) | ||
| 281 | 293 | ||
| 282 | RPlot p(files, destination); | 294 | RPlot p(files, destination); |
| 283 | 295 | ||
| 284 | - p.file.write(qPrintable(QString("qplot(X, 1-Y, data=DET%1, main=\"%2\"").arg((p.major.smooth || p.minor.smooth) ? ", geom=\"smooth\", method=loess, level=0.99" : ", geom=\"line\"", rocOpts.get<QString>("title",QString())) + | 296 | + p.file.write(qPrintable(QString("qplot(X, 1-Y, data=DET, geom=\"line\", main=\"%1\"").arg(rocOpts.get<QString>("title",QString())) + |
| 285 | (p.major.size > 1 ? QString(", colour=factor(%1)").arg(p.major.header) : QString()) + | 297 | (p.major.size > 1 ? QString(", colour=factor(%1)").arg(p.major.header) : QString()) + |
| 286 | (p.minor.size > 1 ? QString(", linetype=factor(%1)").arg(p.minor.header) : QString()) + | 298 | (p.minor.size > 1 ? QString(", linetype=factor(%1)").arg(p.minor.header) : QString()) + |
| 287 | QString(", xlab=\"False Accept Rate\", ylab=\"True Accept Rate\") + theme_minimal()") + | 299 | QString(", xlab=\"False Accept Rate\", ylab=\"True Accept Rate\") + theme_minimal()") + |
| 288 | - (p.major.size > 1 ? getScale("colour", "Algorithm", p.major.size) : QString()) + | 300 | + ((p.major.smooth || p.minor.smooth) ? " + geom_errorbar(data=DET[seq(1, NROW(DET), by = 29),], aes(x=X, ymin=(1-Y)-ci, ymax=(1-Y)+ci), width=0.1, alpha=I(1/2))" : QString()) + |
| 301 | + (p.major.size > 1 ? getScale("colour", p.major.header, p.major.size) : QString()) + | ||
| 289 | (p.minor.size > 1 ? QString(" + scale_linetype_discrete(\"%1\")").arg(p.minor.header) : QString()) + | 302 | (p.minor.size > 1 ? QString(" + scale_linetype_discrete(\"%1\")").arg(p.minor.header) : QString()) + |
| 290 | QString(" + scale_x_log10(labels=trans_format(\"log10\", math_format()))") + | 303 | QString(" + scale_x_log10(labels=trans_format(\"log10\", math_format()))") + |
| 291 | (rocOpts.contains("yLimits") ? QString(" + scale_y_continuous(labels=percent) + coord_cartesian(ylim=%1)").arg("c"+QtUtils::toString(rocOpts.get<QPointF>("yLimits",QPointF()))) : QString(" + scale_y_continuous(labels=percent)")) + | 304 | (rocOpts.contains("yLimits") ? QString(" + scale_y_continuous(labels=percent) + coord_cartesian(ylim=%1)").arg("c"+QtUtils::toString(rocOpts.get<QPointF>("yLimits",QPointF()))) : QString(" + scale_y_continuous(labels=percent)")) + |
| @@ -293,12 +306,14 @@ bool Plot(const QStringList &files, const File &destination, bool show) | @@ -293,12 +306,14 @@ bool Plot(const QStringList &files, const File &destination, bool show) | ||
| 293 | QString(" + theme(legend.title = element_text(size = %1), plot.title = element_text(size = %1), axis.text = element_text(size = %1), axis.title.x = element_text(size = %1), axis.title.y = element_text(size = %1)," | 306 | QString(" + theme(legend.title = element_text(size = %1), plot.title = element_text(size = %1), axis.text = element_text(size = %1), axis.title.x = element_text(size = %1), axis.title.y = element_text(size = %1)," |
| 294 | " legend.position=%2, legend.background = element_rect(fill = 'white'), panel.grid.major = element_line(colour = \"gray\"), panel.grid.minor = element_line(colour = \"gray\", linetype = \"dashed\"), legend.text = element_text(size = %1))\n\n").arg(QString::number(rocOpts.get<float>("textSize",12)), rocOpts.contains("legendPosition") ? "c"+QtUtils::toString(rocOpts.get<QPointF>("legendPosition")) : "'bottom'"))); | 307 | " legend.position=%2, legend.background = element_rect(fill = 'white'), panel.grid.major = element_line(colour = \"gray\"), panel.grid.minor = element_line(colour = \"gray\", linetype = \"dashed\"), legend.text = element_text(size = %1))\n\n").arg(QString::number(rocOpts.get<float>("textSize",12)), rocOpts.contains("legendPosition") ? "c"+QtUtils::toString(rocOpts.get<QPointF>("legendPosition")) : "'bottom'"))); |
| 295 | 308 | ||
| 296 | - p.file.write(qPrintable(QString("qplot(X, Y, data=DET%1").arg((p.major.smooth || p.minor.smooth) ? ", geom=\"smooth\", method=loess, level=0.99" : ", geom=\"line\"") + | 309 | + p.file.write(qPrintable(QString("qplot(X, Y, data=DET, geom=\"line\"") + |
| 297 | (p.major.size > 1 ? QString(", colour=factor(%1)").arg(p.major.header) : QString()) + | 310 | (p.major.size > 1 ? QString(", colour=factor(%1)").arg(p.major.header) : QString()) + |
| 298 | (p.minor.size > 1 ? QString(", linetype=factor(%1)").arg(p.minor.header) : QString()) + | 311 | (p.minor.size > 1 ? QString(", linetype=factor(%1)").arg(p.minor.header) : QString()) + |
| 299 | QString(", xlab=\"False Accept Rate\", ylab=\"False Reject Rate\") + geom_abline(alpha=0.5, colour=\"grey\", linetype=\"dashed\") + theme_minimal()") + | 312 | QString(", xlab=\"False Accept Rate\", ylab=\"False Reject Rate\") + geom_abline(alpha=0.5, colour=\"grey\", linetype=\"dashed\") + theme_minimal()") + |
| 300 | - (p.major.size > 1 ? getScale("colour", "Algorithm", p.major.size) : QString()) + | 313 | + ((p.major.smooth || p.minor.smooth) ? " + geom_errorbar(data=DET[seq(1, NROW(DET), by = 29),], aes(x=X, ymin=Y-ci, ymax=Y+ci), width=0.1, alpha=I(1/2))" : QString()) + |
| 314 | + (p.major.size > 1 ? getScale("colour", p.major.header, p.major.size) : QString()) + | ||
| 301 | (p.minor.size > 1 ? QString(" + scale_linetype_discrete(\"%1\")").arg(p.minor.header) : QString()) + | 315 | (p.minor.size > 1 ? QString(" + scale_linetype_discrete(\"%1\")").arg(p.minor.header) : QString()) + |
| 316 | + QString(" + theme(legend.position=%1)").arg(rocOpts.contains("legendPosition") ? "c"+QtUtils::toString(rocOpts.get<QPointF>("legendPosition")) : "'bottom'") + | ||
| 302 | QString(" + scale_x_log10(labels=trans_format(\"log10\", math_format())) + scale_y_log10(labels=trans_format(\"log10\", math_format())) + annotation_logticks()\n\n"))); | 317 | QString(" + scale_x_log10(labels=trans_format(\"log10\", math_format())) + scale_y_log10(labels=trans_format(\"log10\", math_format())) + annotation_logticks()\n\n"))); |
| 303 | 318 | ||
| 304 | p.file.write(qPrintable(QString("qplot(X, data=SD, geom=\"histogram\", fill=Y, position=\"identity\", alpha=I(1/2)") + | 319 | p.file.write(qPrintable(QString("qplot(X, data=SD, geom=\"histogram\", fill=Y, position=\"identity\", alpha=I(1/2)") + |
| @@ -311,7 +326,7 @@ bool Plot(const QStringList &files, const File &destination, bool show) | @@ -311,7 +326,7 @@ bool Plot(const QStringList &files, const File &destination, bool show) | ||
| 311 | QString(((p.major.smooth || p.minor.smooth) ? (!uncertainty ? " + stat_summary(geom=\"line\", fun.y=mean, size=%1)" : " + stat_summary(geom=\"line\", fun.y=min, aes(linetype=\"Min/Max\"), size=%1) + stat_summary(geom=\"line\", " | 326 | QString(((p.major.smooth || p.minor.smooth) ? (!uncertainty ? " + stat_summary(geom=\"line\", fun.y=mean, size=%1)" : " + stat_summary(geom=\"line\", fun.y=min, aes(linetype=\"Min/Max\"), size=%1) + stat_summary(geom=\"line\", " |
| 312 | "fun.y=max, aes(linetype=\"Min/Max\"), size=%1) + stat_summary(geom=\"line\", fun.y=mean, aes(linetype=\"Mean\"), size=%1) + scale_linetype_manual(\"Legend\", values=c(\"Mean\"=1, \"Min/Max\"=2))") : " + geom_line(size=%1)")).arg(QString::number(cmcOpts.get<float>("thickness",1))) + | 327 | "fun.y=max, aes(linetype=\"Min/Max\"), size=%1) + stat_summary(geom=\"line\", fun.y=mean, aes(linetype=\"Mean\"), size=%1) + scale_linetype_manual(\"Legend\", values=c(\"Mean\"=1, \"Min/Max\"=2))") : " + geom_line(size=%1)")).arg(QString::number(cmcOpts.get<float>("thickness",1))) + |
| 313 | (minimalist ? "" : " + scale_x_log10(labels=c(1,5,10,50,100), breaks=c(1,5,10,50,100)) + annotation_logticks(sides=\"b\")") + | 328 | (minimalist ? "" : " + scale_x_log10(labels=c(1,5,10,50,100), breaks=c(1,5,10,50,100)) + annotation_logticks(sides=\"b\")") + |
| 314 | - (p.major.size > 1 ? getScale("colour", "Algorithm", p.major.size) : QString()) + | 329 | + (p.major.size > 1 ? getScale("colour", p.major.header, p.major.size) : QString()) + |
| 315 | (p.minor.size > 1 ? QString(" + scale_linetype_discrete(\"%1\")").arg(p.minor.header) : QString()) + | 330 | (p.minor.size > 1 ? QString(" + scale_linetype_discrete(\"%1\")").arg(p.minor.header) : QString()) + |
| 316 | (cmcOpts.contains("yLimits") ? QString(" + scale_y_continuous(labels=percent) + coord_cartesian(ylim=%1)").arg("c"+QtUtils::toString(cmcOpts.get<QPointF>("yLimits",QPointF()))) : QString(" + scale_y_continuous(labels=percent)")) + | 331 | (cmcOpts.contains("yLimits") ? QString(" + scale_y_continuous(labels=percent) + coord_cartesian(ylim=%1)").arg("c"+QtUtils::toString(cmcOpts.get<QPointF>("yLimits",QPointF()))) : QString(" + scale_y_continuous(labels=percent)")) + |
| 317 | QString(" + theme_minimal() + theme(legend.title = element_text(size = %1), plot.title = element_text(size = %1), axis.text = element_text(size = %1), axis.title.x = element_text(size = %1), axis.title.y = element_text(size = %1)," | 332 | QString(" + theme_minimal() + theme(legend.title = element_text(size = %1), plot.title = element_text(size = %1), axis.text = element_text(size = %1), axis.title.x = element_text(size = %1), axis.title.y = element_text(size = %1)," |
| @@ -320,14 +335,14 @@ bool Plot(const QStringList &files, const File &destination, bool show) | @@ -320,14 +335,14 @@ bool Plot(const QStringList &files, const File &destination, bool show) | ||
| 320 | p.file.write(qPrintable(QString("qplot(factor(%1)%2, data=BC, %3").arg(p.major.smooth ? (p.minor.header.isEmpty() ? "Algorithm" : p.minor.header) : p.major.header, (p.major.smooth || p.minor.smooth) ? ", Y" : "", (p.major.smooth || p.minor.smooth) ? "geom=\"boxplot\"" : "geom=\"bar\", position=\"dodge\", weight=Y") + | 335 | p.file.write(qPrintable(QString("qplot(factor(%1)%2, data=BC, %3").arg(p.major.smooth ? (p.minor.header.isEmpty() ? "Algorithm" : p.minor.header) : p.major.header, (p.major.smooth || p.minor.smooth) ? ", Y" : "", (p.major.smooth || p.minor.smooth) ? "geom=\"boxplot\"" : "geom=\"bar\", position=\"dodge\", weight=Y") + |
| 321 | (p.major.size > 1 ? QString(", fill=factor(%1)").arg(p.major.header) : QString()) + | 336 | (p.major.size > 1 ? QString(", fill=factor(%1)").arg(p.major.header) : QString()) + |
| 322 | QString(", xlab=\"False Accept Rate\", ylab=\"True Accept Rate\") + theme_minimal()") + | 337 | QString(", xlab=\"False Accept Rate\", ylab=\"True Accept Rate\") + theme_minimal()") + |
| 323 | - (p.major.size > 1 ? getScale("fill", "Algorithm", p.major.size) : QString()) + | 338 | + (p.major.size > 1 ? getScale("fill", p.major.header, p.major.size) : QString()) + |
| 324 | (p.minor.size > 1 ? QString(" + facet_grid(%2 ~ X)").arg(p.minor.header) : QString(" + facet_grid(. ~ X, labeller=far_labeller)")) + | 339 | (p.minor.size > 1 ? QString(" + facet_grid(%2 ~ X)").arg(p.minor.header) : QString(" + facet_grid(. ~ X, labeller=far_labeller)")) + |
| 325 | QString(" + scale_y_continuous(labels=percent) + theme(legend.position=\"none\", axis.text.x=element_text(angle=-90, hjust=0))%1").arg((p.major.smooth || p.minor.smooth) ? "" : " + geom_text(data=BC, aes(label=Y, y=0.05))") + "\n\n")); | 340 | QString(" + scale_y_continuous(labels=percent) + theme(legend.position=\"none\", axis.text.x=element_text(angle=-90, hjust=0))%1").arg((p.major.smooth || p.minor.smooth) ? "" : " + geom_text(data=BC, aes(label=Y, y=0.05))") + "\n\n")); |
| 326 | 341 | ||
| 327 | - p.file.write(qPrintable(QString("qplot(X, Y, data=ERR%1, linetype=Error").arg((p.major.smooth || p.minor.smooth) ? ", geom=\"smooth\", method=loess, level=0.99" : ", geom=\"line\"") + | 342 | + p.file.write(qPrintable(QString("qplot(X, Y, data=ERR, geom=\"line\", linetype=Error") + |
| 328 | ((p.flip ? p.major.size : p.minor.size) > 1 ? QString(", colour=factor(%1)").arg(p.flip ? p.major.header : p.minor.header) : QString()) + | 343 | ((p.flip ? p.major.size : p.minor.size) > 1 ? QString(", colour=factor(%1)").arg(p.flip ? p.major.header : p.minor.header) : QString()) + |
| 329 | QString(", xlab=\"Score\", ylab=\"Error Rate\") + theme_minimal()") + | 344 | QString(", xlab=\"Score\", ylab=\"Error Rate\") + theme_minimal()") + |
| 330 | - ((p.flip ? p.major.size : p.minor.size) > 1 ? getScale("colour", p.flip ? "Algorithm" : "Algorithm", p.flip ? p.major.size : p.minor.size) : QString()) + | 345 | + ((p.flip ? p.major.size : p.minor.size) > 1 ? getScale("colour", p.flip ? p.major.header : p.minor.header, p.flip ? p.major.size : p.minor.size) : QString()) + |
| 331 | QString(" + scale_y_log10(labels=percent) + annotation_logticks(sides=\"l\")") + | 346 | QString(" + scale_y_log10(labels=percent) + annotation_logticks(sides=\"l\")") + |
| 332 | ((p.flip ? p.minor.size : p.major.size) > 1 ? QString(" + facet_wrap(~ %1, scales=\"free_x\")").arg(p.flip ? p.minor.header : p.major.header) : QString()) + | 347 | ((p.flip ? p.minor.size : p.major.size) > 1 ? QString(" + facet_wrap(~ %1, scales=\"free_x\")").arg(p.flip ? p.minor.header : p.major.header) : QString()) + |
| 333 | QString(" + theme(aspect.ratio=1)\n\n"))); | 348 | QString(" + theme(aspect.ratio=1)\n\n"))); |