plot.py 20.2 KB
 André Anjos committed Nov 21, 2013 1 2 3 ``````#!/usr/bin/env python # vim: set fileencoding=utf-8 : # Mon 23 May 2011 14:36:14 CEST `````` Amir MOHAMMADI committed May 17, 2018 4 ``````import numpy `````` André Anjos committed Nov 21, 2013 5 `````` `````` André Anjos committed Sep 28, 2016 6 `````` `````` Amir MOHAMMADI committed Apr 20, 2017 7 ``````def log_values(min_step=-4, counts_per_step=4): `````` André Anjos committed Sep 28, 2016 8 9 10 11 12 13 14 15 `````` """Computes log-scaled values between :math:`10^{M}` and 1 This function computes log-scaled values between :math:`10^{M}` and 1 (including), where :math:`M` is the ``min_ste`` argument, which needs to be a negative integer. The integral ``counts_per_step`` value defines how many values between two adjacent powers of 10 will be created. The total number of values will be ``-min_step * counts_per_step + 1``. `````` 16 `````` `````` André Anjos committed Sep 28, 2016 17 `````` Parameters: `````` 18 `````` `````` André Anjos committed Sep 29, 2016 19 20 21 `````` min_step (:py:class:`int`, optional): The power of 10 that will be the minimum value. E.g., the default ``-4`` will result in the first number to be :math:`10^{-4}` = ``0.00001`` or ``0.01%`` `````` 22 `````` `````` André Anjos committed Sep 29, 2016 23 24 25 26 `````` counts_per_step (:py:class:`int`, optional): The number of values that will be put between two adjacent powers of 10. With the default value ``4`` (and default values of ``min_step``), we will get ``log_list[0] == 1e-4``, ``log_list[4] == 1e-3``, ..., ``log_list[16] == 1``. `````` 27 28 `````` `````` André Anjos committed Sep 28, 2016 29 30 `````` Returns: `````` André Anjos committed May 22, 2017 31 32 `````` :py:class:`list`: A list of logarithmically scaled values between :math:`10^{M}` and 1. `````` 33 34 `````` """ `````` André Anjos committed Sep 28, 2016 35 `````` `````` 36 `````` import math `````` Amir MOHAMMADI committed Apr 20, 2017 37 `````` return [math.pow(10., i * 1. / counts_per_step) for i in range(min_step * counts_per_step, 0)] + [1.] `````` 38 `````` `````` André Anjos committed Nov 21, 2013 39 `````` `````` Amir MOHAMMADI committed May 17, 2018 40 41 ``````def _semilogx(x, y, **kwargs): # remove points were x is 0 `````` Amir MOHAMMADI committed May 17, 2018 42 `````` x, y = numpy.asarray(x), numpy.asarray(y) `````` Amir MOHAMMADI committed May 17, 2018 43 44 45 46 47 48 49 `````` zero_index = x == 0 x = x[~zero_index] y = y[~zero_index] from matplotlib import pyplot return pyplot.semilogx(x, y, **kwargs) `````` André Anjos committed Nov 21, 2013 50 ``````def roc(negatives, positives, npoints=100, CAR=False, **kwargs): `````` 51 `````` """Plots Receiver Operating Characteristic (ROC) curve. `````` André Anjos committed Nov 21, 2013 52 `````` `````` Manuel Günther committed Nov 25, 2015 53 `````` This method will call ``matplotlib`` to plot the ROC curve for a system which `````` André Anjos committed Nov 21, 2013 54 `````` contains a particular set of negatives (impostors) and positives (clients) `````` André Anjos committed Sep 28, 2016 55 56 57 `````` scores. We use the standard :py:func:`matplotlib.pyplot.plot` command. All parameters passed with exception of the three first parameters of this method will be directly passed to the plot command. `````` André Anjos committed Nov 21, 2013 58 `````` `````` André Anjos committed Sep 28, 2016 59 60 61 `````` The plot will represent the false-alarm on the horizontal axis and the false-rejection on the vertical axis. The values for the axis will be computed using :py:func:`bob.measure.roc`. `````` André Anjos committed Nov 21, 2013 62 `````` `````` Manuel Günther committed Nov 25, 2015 63 `````` .. note:: `````` André Anjos committed Nov 21, 2013 64 `````` `````` Manuel Günther committed Nov 25, 2015 65 66 67 `````` This function does not initiate and save the figure instance, it only issues the plotting command. You are the responsible for setting up and saving the figure as you see fit. `````` André Anjos committed Nov 21, 2013 68 69 `````` `````` André Anjos committed Sep 28, 2016 70 `````` Parameters: `````` André Anjos committed Nov 21, 2013 71 `````` `````` André Anjos committed Sep 28, 2016 72 73 74 `````` negatives (array): 1D float array that contains the scores of the "negative" (noise, non-class) samples of your classifier. See (:py:func:`bob.measure.roc`) `````` André Anjos committed Nov 21, 2013 75 `````` `````` André Anjos committed Sep 28, 2016 76 77 78 `````` positives (array): 1D float array that contains the scores of the "positive" (signal, class) samples of your classifier. See (:py:func:`bob.measure.roc`) `````` André Anjos committed Nov 21, 2013 79 `````` `````` André Anjos committed Sep 29, 2016 80 `````` npoints (:py:class:`int`, optional): The number of points for the plot. See `````` André Anjos committed Sep 28, 2016 81 `````` (:py:func:`bob.measure.roc`) `````` André Anjos committed Nov 21, 2013 82 `````` `````` Theophile GENTILHOMME committed Jul 17, 2018 83 84 `````` CAR (:py:class:`bool`, optional): If set to ``True``, it will plot the CPR (CAR) over FPR in using :py:func:`matplotlib.pyplot.semilogx`, otherwise the `````` Theophile GENTILHOMME committed Jul 10, 2018 85 `````` FPR over FNR linearly using :py:func:`matplotlib.pyplot.plot`. `````` André Anjos committed Sep 28, 2016 86 `````` `````` André Anjos committed Sep 29, 2016 87 88 `````` kwargs (:py:class:`dict`, optional): Extra plotting parameters, which are passed directly to :py:func:`matplotlib.pyplot.plot`. `````` André Anjos committed Sep 28, 2016 89 90 91 92 `````` Returns: `````` André Anjos committed Sep 29, 2016 93 94 95 `````` :py:class:`list` of :py:class:`matplotlib.lines.Line2D`: The lines that were added as defined by the return value of :py:func:`matplotlib.pyplot.plot`. `````` André Anjos committed Nov 21, 2013 96 97 98 `````` """ `````` Manuel Günther committed Nov 25, 2015 99 `````` from matplotlib import pyplot `````` André Anjos committed Nov 21, 2013 100 `````` from . import roc as calc `````` André Anjos committed Dec 12, 2013 101 `````` out = calc(negatives, positives, npoints) `````` André Anjos committed Nov 21, 2013 102 `````` if not CAR: `````` 103 `````` return pyplot.plot(out[0, :], out[1, :], **kwargs) `````` André Anjos committed Nov 21, 2013 104 `````` else: `````` Amir MOHAMMADI committed May 17, 2018 105 `````` return _semilogx(out[0, :], (1 - out[1, :]), **kwargs) `````` Manuel Günther committed Nov 25, 2015 106 `````` `````` André Anjos committed Nov 21, 2013 107 `````` `````` Amir MOHAMMADI committed May 17, 2018 108 109 ``````def roc_for_far(negatives, positives, far_values=log_values(), CAR=True, **kwargs): `````` Theophile GENTILHOMME committed Jul 17, 2018 110 `````` """Plots the ROC curve for the given list of False Positive Rates (FAR). `````` 111 112 113 `````` This method will call ``matplotlib`` to plot the ROC curve for a system which contains a particular set of negatives (impostors) and positives (clients) `````` André Anjos committed Sep 28, 2016 114 115 116 `````` scores. We use the standard :py:func:`matplotlib.pyplot.semilogx` command. All parameters passed with exception of the three first parameters of this method will be directly passed to the plot command. `````` 117 `````` `````` Theophile GENTILHOMME committed Jul 17, 2018 118 119 `````` The plot will represent the False Positive Rate (FPR) on the horizontal axis and the Correct Positive Rate (CPR) on the vertical axis. The values `````` André Anjos committed Sep 28, 2016 120 `````` for the axis will be computed using :py:func:`bob.measure.roc_for_far`. `````` 121 122 123 124 125 126 127 128 `````` .. note:: This function does not initiate and save the figure instance, it only issues the plotting command. You are the responsible for setting up and saving the figure as you see fit. `````` André Anjos committed Sep 28, 2016 129 130 131 132 133 `````` Parameters: negatives (array): 1D float array that contains the scores of the "negative" (noise, non-class) samples of your classifier. See (:py:func:`bob.measure.roc`) `````` 134 `````` `````` André Anjos committed Sep 28, 2016 135 136 137 `````` positives (array): 1D float array that contains the scores of the "positive" (signal, class) samples of your classifier. See (:py:func:`bob.measure.roc`) `````` 138 `````` `````` Theophile GENTILHOMME committed Jul 10, 2018 139 `````` far_values (:py:class:`list`, optional): The values for the FPR, where the `````` Theophile GENTILHOMME committed Jul 17, 2018 140 `````` CPR (CAR) should be plotted; each value should be in range [0,1]. `````` 141 `````` `````` Theophile GENTILHOMME committed Jul 17, 2018 142 143 `````` CAR (:py:class:`bool`, optional): If set to ``True``, it will plot the CPR (CAR) over FPR in using :py:func:`matplotlib.pyplot.semilogx`, otherwise the `````` Theophile GENTILHOMME committed Jul 10, 2018 144 `````` FPR over FNR linearly using :py:func:`matplotlib.pyplot.plot`. `````` Amir MOHAMMADI committed May 17, 2018 145 `````` `````` André Anjos committed Sep 29, 2016 146 147 `````` kwargs (:py:class:`dict`, optional): Extra plotting parameters, which are passed directly to :py:func:`matplotlib.pyplot.plot`. `````` André Anjos committed Sep 28, 2016 148 149 150 151 `````` Returns: `````` André Anjos committed Sep 29, 2016 152 153 154 `````` :py:class:`list` of :py:class:`matplotlib.lines.Line2D`: The lines that were added as defined by the return value of :py:func:`matplotlib.pyplot.semilogx`. `````` 155 156 157 158 159 160 `````` """ from matplotlib import pyplot from . import roc_for_far as calc out = calc(negatives, positives, far_values) `````` Amir MOHAMMADI committed May 17, 2018 161 162 163 164 `````` if not CAR: return pyplot.plot(out[0, :], out[1, :], **kwargs) else: return _semilogx(out[0, :], (1 - out[1, :]), **kwargs) `````` 165 166 `````` `````` André Anjos committed Nov 21, 2013 167 ``````def precision_recall_curve(negatives, positives, npoints=100, **kwargs): `````` André Anjos committed Sep 28, 2016 168 `````` """Plots a Precision-Recall curve. `````` André Anjos committed Nov 21, 2013 169 `````` `````` André Anjos committed Sep 28, 2016 170 171 172 173 174 175 `````` This method will call ``matplotlib`` to plot the precision-recall curve for a system which contains a particular set of ``negatives`` (impostors) and ``positives`` (clients) scores. We use the standard :py:func:`matplotlib.pyplot.plot` command. All parameters passed with exception of the three first parameters of this method will be directly passed to the plot command. `````` André Anjos committed Nov 21, 2013 176 `````` `````` Manuel Günther committed Nov 25, 2015 177 `````` .. note:: `````` André Anjos committed Nov 21, 2013 178 `````` `````` Manuel Günther committed Nov 25, 2015 179 180 181 `````` This function does not initiate and save the figure instance, it only issues the plotting command. You are the responsible for setting up and saving the figure as you see fit. `````` André Anjos committed Nov 21, 2013 182 183 `````` `````` André Anjos committed Sep 28, 2016 184 185 186 187 188 189 190 191 192 `````` Parameters: negatives (array): 1D float array that contains the scores of the "negative" (noise, non-class) samples of your classifier. See (:py:func:`bob.measure.precision_recall_curve`) positives (array): 1D float array that contains the scores of the "positive" (signal, class) samples of your classifier. See (:py:func:`bob.measure.precision_recall_curve`) `````` André Anjos committed Nov 21, 2013 193 `````` `````` André Anjos committed Sep 29, 2016 194 `````` npoints (:py:class:`int`, optional): The number of points for the plot. See `````` André Anjos committed Sep 28, 2016 195 `````` (:py:func:`bob.measure.precision_recall_curve`) `````` André Anjos committed Nov 21, 2013 196 `````` `````` André Anjos committed Sep 29, 2016 197 198 `````` kwargs (:py:class:`dict`, optional): Extra plotting parameters, which are passed directly to :py:func:`matplotlib.pyplot.plot`. `````` André Anjos committed Nov 21, 2013 199 200 `````` `````` André Anjos committed Sep 28, 2016 201 202 `````` Returns: `````` André Anjos committed Sep 29, 2016 203 204 205 `````` :py:class:`list` of :py:class:`matplotlib.lines.Line2D`: The lines that were added as defined by the return value of :py:func:`matplotlib.pyplot.plot`. `````` André Anjos committed Sep 28, 2016 206 `````` `````` André Anjos committed Nov 21, 2013 207 208 `````` """ `````` Manuel Günther committed Nov 25, 2015 209 `````` from matplotlib import pyplot `````` André Anjos committed Nov 21, 2013 210 211 `````` from . import precision_recall_curve as calc out = calc(negatives, positives, npoints) `````` Amir MOHAMMADI committed Apr 20, 2017 212 `````` return pyplot.plot(100.0 * out[0, :], 100.0 * out[1, :], **kwargs) `````` André Anjos committed Nov 21, 2013 213 214 215 `````` def epc(dev_negatives, dev_positives, test_negatives, test_positives, `````` Amir MOHAMMADI committed Apr 20, 2017 216 `````` npoints=100, **kwargs): `````` André Anjos committed Nov 21, 2013 217 218 219 220 221 222 223 `````` """Plots Expected Performance Curve (EPC) as defined in the paper: Bengio, S., Keller, M., Mariéthoz, J. (2004). The Expected Performance Curve. International Conference on Machine Learning ICML Workshop on ROC Analysis in Machine Learning, 136(1), 1963–1966. IDIAP RR. Available: http://eprints.pascal-network.org/archive/00000670/ `````` Manuel Günther committed Nov 25, 2015 224 `````` This method will call ``matplotlib`` to plot the EPC curve for a system which `````` André Anjos committed Nov 21, 2013 225 226 `````` contains a particular set of negatives (impostors) and positives (clients) for both the development and test sets. We use the standard `````` André Anjos committed Sep 28, 2016 227 228 229 `````` :py:func:`matplotlib.pyplot.plot` command. All parameters passed with exception of the five first parameters of this method will be directly passed to the plot command. `````` André Anjos committed Nov 21, 2013 230 `````` `````` André Anjos committed Sep 28, 2016 231 232 `````` The plot will represent the minimum HTER on the vertical axis and the cost on the horizontal axis. `````` André Anjos committed Nov 21, 2013 233 `````` `````` Manuel Günther committed Nov 25, 2015 234 `````` .. note:: `````` André Anjos committed Nov 21, 2013 235 `````` `````` Manuel Günther committed Nov 25, 2015 236 237 238 `````` This function does not initiate and save the figure instance, it only issues the plotting commands. You are the responsible for setting up and saving the figure as you see fit. `````` André Anjos committed Nov 21, 2013 239 240 `````` `````` André Anjos committed Sep 28, 2016 241 242 243 244 245 246 247 248 249 `````` Parameters: dev_negatives (array): 1D float array that contains the scores of the "negative" (noise, non-class) samples of your classifier, from the development set. See (:py:func:`bob.measure.epc`) dev_positives (array): 1D float array that contains the scores of the "positive" (signal, class) samples of your classifier, from the development set. See (:py:func:`bob.measure.epc`) `````` André Anjos committed Nov 21, 2013 250 `````` `````` André Anjos committed Sep 28, 2016 251 252 253 `````` test_negatives (array): 1D float array that contains the scores of the "negative" (noise, non-class) samples of your classifier, from the test set. See (:py:func:`bob.measure.epc`) `````` André Anjos committed Nov 21, 2013 254 `````` `````` André Anjos committed Sep 28, 2016 255 256 257 `````` test_positives (array): 1D float array that contains the scores of the "positive" (signal, class) samples of your classifier, from the test set. See (:py:func:`bob.measure.epc`) `````` André Anjos committed Nov 21, 2013 258 `````` `````` André Anjos committed Sep 29, 2016 259 `````` npoints (:py:class:`int`, optional): The number of points for the plot. See `````` André Anjos committed Sep 28, 2016 260 261 `````` (:py:func:`bob.measure.epc`) `````` André Anjos committed Sep 29, 2016 262 263 `````` kwargs (:py:class:`dict`, optional): Extra plotting parameters, which are passed directly to :py:func:`matplotlib.pyplot.plot`. `````` André Anjos committed Sep 28, 2016 264 265 266 267 `````` Returns: `````` André Anjos committed Sep 29, 2016 268 269 270 `````` :py:class:`list` of :py:class:`matplotlib.lines.Line2D`: The lines that were added as defined by the return value of :py:func:`matplotlib.pyplot.plot`. `````` André Anjos committed Nov 21, 2013 271 272 273 `````` """ `````` Manuel Günther committed Nov 25, 2015 274 `````` from matplotlib import pyplot `````` André Anjos committed Nov 21, 2013 275 276 `````` from . import epc as calc `````` André Anjos committed Sep 28, 2016 277 `````` out = calc(dev_negatives, dev_positives, test_negatives, test_positives, `````` Amir MOHAMMADI committed Apr 20, 2017 278 279 `````` npoints) return pyplot.plot(out[0, :], 100.0 * out[1, :], **kwargs) `````` Manuel Günther committed Nov 25, 2015 280 `````` `````` André Anjos committed Nov 21, 2013 281 `````` `````` 282 ``````def det(negatives, positives, npoints=100, **kwargs): `````` André Anjos committed Nov 21, 2013 283 284 285 286 287 288 289 `````` """Plots Detection Error Trade-off (DET) curve as defined in the paper: Martin, A., Doddington, G., Kamm, T., Ordowski, M., & Przybocki, M. (1997). The DET curve in assessment of detection task performance. Fifth European Conference on Speech Communication and Technology (pp. 1895-1898). Available: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.117.4489&rep=rep1&type=pdf `````` André Anjos committed Sep 28, 2016 290 291 292 293 294 `````` This method will call ``matplotlib`` to plot the DET curve(s) for a system which contains a particular set of negatives (impostors) and positives (clients) scores. We use the standard :py:func:`matplotlib.pyplot.plot` command. All parameters passed with exception of the three first parameters of this method will be directly passed to the plot command. `````` André Anjos committed Nov 21, 2013 295 `````` `````` Manuel Günther committed Nov 25, 2015 296 297 `````` The plot will represent the false-alarm on the horizontal axis and the false-rejection on the vertical axis. `````` André Anjos committed Nov 21, 2013 298 299 300 301 302 303 304 305 306 307 308 309 310 311 `````` This method is strongly inspired by the NIST implementation for Matlab, called DETware, version 2.1 and available for download at the NIST website: http://www.itl.nist.gov/iad/mig/tools/ .. note:: This function does not initiate and save the figure instance, it only issues the plotting commands. You are the responsible for setting up and saving the figure as you see fit. .. note:: `````` Manuel Günther committed Nov 25, 2015 312 `````` If you wish to reset axis zooming, you must use the Gaussian scale rather `````` André Anjos committed Nov 21, 2013 313 `````` than the visual marks showed at the plot, which are just there for `````` André Anjos committed Sep 28, 2016 314 315 316 `````` displaying purposes. The real axis scale is based on :py:func:`bob.measure.ppndf`. For example, if you wish to set the x and y axis to display data between 1% and 40% here is the recipe: `````` André Anjos committed Nov 21, 2013 317 318 319 `````` .. code-block:: python `````` André Anjos committed May 26, 2014 320 `````` import bob.measure `````` Manuel Günther committed Nov 25, 2015 321 `````` from matplotlib import pyplot `````` André Anjos committed May 26, 2014 322 `````` bob.measure.plot.det(...) #call this as many times as you need `````` André Anjos committed Nov 21, 2013 323 `````` #AFTER you plot the DET curve, just set the axis in this way: `````` Manuel Günther committed Nov 25, 2015 324 `````` pyplot.axis([bob.measure.ppndf(k/100.0) for k in (1, 40, 1, 40)]) `````` André Anjos committed Nov 21, 2013 325 326 `````` We provide a convenient way for you to do the above in this module. So, `````` André Anjos committed Sep 28, 2016 327 328 `````` optionally, you may use the :py:func:`bob.measure.plot.det_axis` method like this: `````` André Anjos committed Nov 21, 2013 329 330 331 `````` .. code-block:: python `````` André Anjos committed May 26, 2014 332 333 `````` import bob.measure bob.measure.plot.det(...) `````` André Anjos committed Nov 21, 2013 334 `````` # please note we convert percentage values in det_axis() `````` André Anjos committed May 26, 2014 335 `````` bob.measure.plot.det_axis([1, 40, 1, 40]) `````` André Anjos committed Nov 21, 2013 336 337 `````` `````` André Anjos committed Sep 28, 2016 338 339 340 341 342 `````` Parameters: negatives (array): 1D float array that contains the scores of the "negative" (noise, non-class) samples of your classifier. See (:py:func:`bob.measure.det`) `````` Manuel Günther committed Nov 25, 2015 343 `````` `````` André Anjos committed Sep 28, 2016 344 345 346 `````` positives (array): 1D float array that contains the scores of the "positive" (signal, class) samples of your classifier. See (:py:func:`bob.measure.det`) `````` Manuel Günther committed Nov 25, 2015 347 `````` `````` André Anjos committed Sep 29, 2016 348 `````` npoints (:py:class:`int`, optional): The number of points for the plot. See `````` André Anjos committed Sep 28, 2016 349 `````` (:py:func:`bob.measure.det`) `````` Manuel Günther committed Nov 25, 2015 350 `````` `````` André Anjos committed Sep 29, 2016 351 352 `````` axisfontsize (:py:class:`str`, optional): The size to be used by x/y-tick-labels to set the font size on the axis `````` Manuel Günther committed Nov 25, 2015 353 `````` `````` André Anjos committed Sep 29, 2016 354 355 `````` kwargs (:py:class:`dict`, optional): Extra plotting parameters, which are passed directly to :py:func:`matplotlib.pyplot.plot`. `````` André Anjos committed Sep 28, 2016 356 357 358 359 `````` Returns: `````` André Anjos committed Sep 29, 2016 360 361 362 `````` :py:class:`list` of :py:class:`matplotlib.lines.Line2D`: The lines that were added as defined by the return value of :py:func:`matplotlib.pyplot.plot`. `````` Manuel Günther committed Nov 25, 2015 363 364 `````` """ `````` André Anjos committed Nov 21, 2013 365 366 367 `````` # these are some constants required in this method desiredTicks = [ `````` 368 `````` "0.000001", "0.000002", "0.000005", `````` André Anjos committed Nov 21, 2013 369 370 371 372 373 374 375 376 377 `````` "0.00001", "0.00002", "0.00005", "0.0001", "0.0002", "0.0005", "0.001", "0.002", "0.005", "0.01", "0.02", "0.05", "0.1", "0.2", "0.4", "0.6", "0.8", "0.9", "0.95", "0.98", "0.99", "0.995", "0.998", "0.999", "0.9995", "0.9998", "0.9999", "0.99995", "0.99998", "0.99999" `````` Amir MOHAMMADI committed Apr 20, 2017 378 `````` ] `````` André Anjos committed Nov 21, 2013 379 380 `````` desiredLabels = [ `````` 381 `````` "0.0001", "0.0002", "0.0005", `````` André Anjos committed Nov 21, 2013 382 383 384 385 386 387 388 389 390 `````` "0.001", "0.002", "0.005", "0.01", "0.02", "0.05", "0.1", "0.2", "0.5", "1", "2", "5", "10", "20", "40", "60", "80", "90", "95", "98", "99", "99.5", "99.8", "99.9", "99.95", "99.98", "99.99", "99.995", "99.998", "99.999" `````` Amir MOHAMMADI committed Apr 20, 2017 391 `````` ] `````` André Anjos committed Nov 21, 2013 392 393 `````` # this will actually do the plotting `````` Manuel Günther committed Nov 25, 2015 394 `````` from matplotlib import pyplot `````` André Anjos committed Nov 21, 2013 395 396 397 `````` from . import det as calc from . import ppndf `````` André Anjos committed Dec 12, 2013 398 `````` out = calc(negatives, positives, npoints) `````` Amir MOHAMMADI committed Apr 20, 2017 399 `````` retval = pyplot.plot(out[0, :], out[1, :], **kwargs) `````` André Anjos committed Nov 21, 2013 400 401 402 `````` # now the trick: we must plot the tick marks by hand using the PPNDF method pticks = [ppndf(float(v)) for v in desiredTicks] `````` Amir MOHAMMADI committed Apr 20, 2017 403 `````` ax = pyplot.gca() # and finally we set our own tick marks `````` André Anjos committed Nov 21, 2013 404 `````` ax.set_xticks(pticks) `````` 405 `````` ax.set_xticklabels(desiredLabels) `````` André Anjos committed Nov 21, 2013 406 `````` ax.set_yticks(pticks) `````` 407 `````` ax.set_yticklabels(desiredLabels) `````` André Anjos committed Nov 21, 2013 408 409 410 `````` return retval `````` Manuel Günther committed Nov 25, 2015 411 `````` `````` André Anjos committed Nov 21, 2013 412 413 414 ``````def det_axis(v, **kwargs): """Sets the axis in a DET plot. `````` Manuel Günther committed Nov 25, 2015 415 `````` This method wraps the :py:func:`matplotlib.pyplot.axis` by calling `````` André Anjos committed Sep 28, 2016 416 417 418 419 420 `````` :py:func:`bob.measure.ppndf` on the values passed by the user so they are meaningful in a DET plot as performed by :py:func:`bob.measure.plot.det`. Parameters: `````` Manuel Günther committed Nov 25, 2015 421 `````` `````` André Anjos committed Sep 29, 2016 422 423 424 425 426 `````` v (``sequence``): A sequence (list, tuple, array or the like) containing the X and Y limits in the order ``(xmin, xmax, ymin, ymax)``. Expected values should be in percentage (between 0 and 100%). If ``v`` is not a list or tuple that contains 4 numbers it is passed without further inspection to :py:func:`matplotlib.pyplot.axis`. `````` André Anjos committed Nov 21, 2013 427 `````` `````` André Anjos committed Sep 29, 2016 428 429 `````` kwargs (:py:class:`dict`, optional): Extra plotting parameters, which are passed directly to :py:func:`matplotlib.pyplot.axis`. `````` André Anjos committed Nov 21, 2013 430 431 `````` `````` André Anjos committed Sep 28, 2016 432 433 434 `````` Returns: object: Whatever is returned by :py:func:`matplotlib.pyplot.axis`. `````` André Anjos committed Nov 21, 2013 435 436 437 438 `````` """ import logging `````` Manuel Günther committed Nov 25, 2015 439 `````` logger = logging.getLogger("bob.measure") `````` André Anjos committed Nov 21, 2013 440 `````` `````` Manuel Günther committed Nov 25, 2015 441 `````` from matplotlib import pyplot `````` André Anjos committed Nov 21, 2013 442 443 444 445 `````` from . import ppndf # treat input try: `````` Amir MOHAMMADI committed Apr 20, 2017 446 447 448 449 `````` tv = list(v) # normal input if len(tv) != 4: raise IndexError tv = [ppndf(float(k) / 100) for k in tv] `````` Manuel Günther committed Nov 25, 2015 450 `````` cur = pyplot.axis() `````` André Anjos committed Nov 21, 2013 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 `````` # limits must be within bounds if tv[0] < cur[0]: logger.warn("Readjusting xmin: the provided value is out of bounds") tv[0] = cur[0] if tv[1] > cur[1]: logger.warn("Readjusting xmax: the provided value is out of bounds") tv[1] = cur[1] if tv[2] < cur[2]: logger.warn("Readjusting ymin: the provided value is out of bounds") tv[2] = cur[2] if tv[3] > cur[3]: logger.warn("Readjusting ymax: the provided value is out of bounds") tv[3] = cur[3] except: tv = v `````` Manuel Günther committed Nov 25, 2015 469 470 `````` return pyplot.axis(tv, **kwargs) `````` André Anjos committed Nov 21, 2013 471 `````` `````` Amir MOHAMMADI committed Apr 20, 2017 472 ``````def cmc(cmc_scores, logx=True, **kwargs): `````` André Anjos committed Sep 28, 2016 473 474 `````` """Plots the (cumulative) match characteristics and returns the maximum rank. `````` Amir MOHAMMADI committed May 17, 2018 475 `````` This function plots a CMC curve using the given CMC scores (:py:class:`list`: `````` Theophile GENTILHOMME committed Mar 16, 2018 476 477 `````` A list of tuples, where each tuple contains the ``negative`` and ``positive`` scores for one probe of the database). `````` André Anjos committed Sep 28, 2016 478 `````` `````` Manuel Günther committed Sep 17, 2015 479 `````` `````` André Anjos committed Sep 28, 2016 480 `````` Parameters: `````` Manuel Günther committed Sep 17, 2015 481 `````` `````` André Anjos committed Sep 28, 2016 482 483 `````` cmc_scores (array): 1D float array containing the CMC values (See :py:func:`bob.measure.cmc`) `````` Manuel Günther committed Sep 17, 2015 484 `````` `````` André Anjos committed Sep 29, 2016 485 486 487 `````` logx (:py:class:`bool`, optional): If set (the default), plots the rank axis in logarithmic scale using :py:func:`matplotlib.pyplot.semilogx` or in linear scale using :py:func:`matplotlib.pyplot.plot` `````` Manuel Günther committed Sep 17, 2015 488 `````` `````` André Anjos committed Sep 29, 2016 489 490 `````` kwargs (:py:class:`dict`, optional): Extra plotting parameters, which are passed directly to :py:func:`matplotlib.pyplot.plot`. `````` Manuel Günther committed Sep 17, 2015 491 `````` `````` Manuel Günther committed Nov 25, 2015 492 `````` `````` André Anjos committed Sep 28, 2016 493 494 495 `````` Returns: int: The number of classes (clients) in the given scores. `````` André Anjos committed Nov 21, 2013 496 `````` `````` Manuel Günther committed Nov 25, 2015 497 `````` """ `````` André Anjos committed Sep 28, 2016 498 `````` `````` Manuel Günther committed Nov 25, 2015 499 `````` from matplotlib import pyplot `````` André Anjos committed Nov 21, 2013 500 `````` from . import cmc as calc `````` Manuel Günther committed Nov 25, 2015 501 `````` `````` André Anjos committed Nov 21, 2013 502 503 504 `````` out = calc(cmc_scores) if logx: `````` Amir MOHAMMADI committed May 17, 2018 505 `````` _semilogx(range(1, len(out) + 1), out, **kwargs) `````` André Anjos committed Nov 21, 2013 506 `````` else: `````` Theophile GENTILHOMME committed Apr 06, 2018 507 `````` pyplot.plot(range(1, len(out) + 1), out, **kwargs) `````` André Anjos committed Nov 21, 2013 508 509 `````` return len(out) `````` 510 511 `````` `````` Amir MOHAMMADI committed Apr 20, 2017 512 ``````def detection_identification_curve(cmc_scores, far_values=log_values(), rank=1, logx=True, **kwargs): `````` Theophile GENTILHOMME committed Jul 10, 2018 513 `````` """Plots the Detection & Identification curve over the FPR `````` 514 `````` `````` André Anjos committed Sep 28, 2016 515 516 517 518 `````` This curve is designed to be used in an open set identification protocol, and defined in Chapter 14.1 of [LiJain2005]_. It requires to have at least one open set probe item, i.e., with no corresponding gallery, such that the positives for that pair are ``None``. `````` 519 `````` `````` Theophile GENTILHOMME committed Jul 10, 2018 520 `````` The detection and identification curve first computes FPR thresholds based on `````` André Anjos committed Sep 28, 2016 521 522 523 524 `````` the out-of-set probe scores (negative scores). For each probe item, the **maximum** negative score is used. Then, it plots the detection and identification rates for those thresholds, which are based on the in-set probe scores only. See [LiJain2005]_ for more details. `````` 525 `````` `````` André Anjos committed Sep 28, 2016 526 `````` .. [LiJain2005] **Stan Li and Anil K. Jain**, *Handbook of Face Recognition*, Springer, 2005 `````` 527 528 `````` `````` André Anjos committed Sep 28, 2016 529 `````` Parameters: `````` 530 `````` `````` André Anjos committed Sep 28, 2016 531 532 `````` cmc_scores (array): 1D float array containing the CMC values (See :py:func:`bob.measure.cmc`) `````` 533 `````` `````` André Anjos committed Sep 29, 2016 534 535 `````` rank (:py:class:`int`, optional): The rank for which the curve should be plotted `````` 536 `````` `````` Theophile GENTILHOMME committed Jul 17, 2018 537 538 `````` far_values (:py:class:`list`, optional): The values for the FPR (FAR), where the CPR (CAR) should be plotted; each value should be in range [0,1]. `````` 539 `````` `````` André Anjos committed Sep 29, 2016 540 541 542 `````` logx (:py:class:`bool`, optional): If set (the default), plots the rank axis in logarithmic scale using :py:func:`matplotlib.pyplot.semilogx` or in linear scale using :py:func:`matplotlib.pyplot.plot` `````` André Anjos committed Sep 28, 2016 543 `````` `````` André Anjos committed Sep 29, 2016 544 545 `````` kwargs (:py:class:`dict`, optional): Extra plotting parameters, which are passed directly to :py:func:`matplotlib.pyplot.plot`. `````` André Anjos committed Sep 28, 2016 546 547 548 549 `````` Returns: `````` André Anjos committed Sep 29, 2016 550 551 552 `````` :py:class:`list` of :py:class:`matplotlib.lines.Line2D`: The lines that were added as defined by the return value of :py:func:`matplotlib.pyplot.plot`. `````` 553 554 555 `````` """ `````` 556 `````` import numpy `````` Manuel Günther committed Aug 31, 2017 557 `````` import math `````` 558 `````` from matplotlib import pyplot `````` 559 `````` from . import far_threshold, detection_identification_rate `````` 560 `````` `````` Amir MOHAMMADI committed Apr 20, 2017 561 562 563 564 `````` # for each probe, for which no positives exists, get the highest negative # score; and sort them to compute the FAR thresholds negatives = sorted(max(neg) for neg, pos in cmc_scores if ( pos is None or not numpy.array(pos).size) and neg is not None) `````` 565 `````` if not negatives: `````` Amir MOHAMMADI committed Apr 20, 2017 566 567 `````` raise ValueError( "There need to be at least one pair with only negative scores") `````` 568 569 570 571 `````` # compute thresholds based on FAR values thresholds = [far_threshold(negatives, [], v, True) for v in far_values] `````` Amir MOHAMMADI committed Apr 20, 2017 572 573 `````` # compute detection and identification rate based on the thresholds for # the given rank `````` Manuel Günther committed Aug 31, 2017 574 575 `````` rates = [detection_identification_rate(cmc_scores, t, rank) if not math.isnan(t) else numpy.nan for t in thresholds] `````` 576 577 578 `````` # plot curve if logx: `````` Amir MOHAMMADI committed May 17, 2018 579 `````` return _semilogx(far_values, rates, **kwargs) `````` 580 581 `````` else: return pyplot.plot(far_values, rates, **kwargs)``````