plot.py 19.7 KB
 André Anjos committed Nov 21, 2013 1 2 3 4 ``````#!/usr/bin/env python # vim: set fileencoding=utf-8 : # Mon 23 May 2011 14:36:14 CEST `````` André Anjos committed Sep 28, 2016 5 `````` `````` 6 ``````def log_values(min_step = -4, counts_per_step = 4): `````` André Anjos committed Sep 28, 2016 7 8 9 10 11 12 13 14 `````` """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``. `````` 15 `````` `````` André Anjos committed Sep 28, 2016 16 `````` Parameters: `````` 17 `````` `````` André Anjos committed Sep 29, 2016 18 19 20 `````` 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%`` `````` 21 `````` `````` André Anjos committed Sep 29, 2016 22 23 24 25 `````` 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``. `````` 26 27 `````` `````` André Anjos committed Sep 28, 2016 28 29 30 `````` Returns: list: A list of logarithmically scaled values between :math:`10^{M}` and 1. `````` 31 32 `````` """ `````` André Anjos committed Sep 28, 2016 33 `````` `````` 34 35 36 `````` import math return [math.pow(10., i * 1./counts_per_step) for i in range(min_step*counts_per_step,0)] + [1.] `````` André Anjos committed Nov 21, 2013 37 38 `````` def roc(negatives, positives, npoints=100, CAR=False, **kwargs): `````` 39 `````` """Plots Receiver Operating Characteristic (ROC) curve. `````` André Anjos committed Nov 21, 2013 40 `````` `````` Manuel Günther committed Nov 25, 2015 41 `````` This method will call ``matplotlib`` to plot the ROC curve for a system which `````` André Anjos committed Nov 21, 2013 42 `````` contains a particular set of negatives (impostors) and positives (clients) `````` André Anjos committed Sep 28, 2016 43 44 45 `````` 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 46 `````` `````` André Anjos committed Sep 28, 2016 47 48 49 `````` 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 50 `````` `````` Manuel Günther committed Nov 25, 2015 51 `````` .. note:: `````` André Anjos committed Nov 21, 2013 52 `````` `````` Manuel Günther committed Nov 25, 2015 53 54 55 `````` 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 56 57 `````` `````` André Anjos committed Sep 28, 2016 58 `````` Parameters: `````` André Anjos committed Nov 21, 2013 59 `````` `````` André Anjos committed Sep 28, 2016 60 61 62 `````` 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 63 `````` `````` André Anjos committed Sep 28, 2016 64 65 66 `````` 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 67 `````` `````` André Anjos committed Sep 29, 2016 68 `````` npoints (:py:class:`int`, optional): The number of points for the plot. See `````` André Anjos committed Sep 28, 2016 69 `````` (:py:func:`bob.measure.roc`) `````` André Anjos committed Nov 21, 2013 70 `````` `````` André Anjos committed Sep 29, 2016 71 72 73 `````` CAR (:py:class:`bool`, optional): If set to ``True``, it will plot the CAR over FAR in using :py:func:`matplotlib.pyplot.semilogx`, otherwise the FAR over FRR linearly using :py:func:`matplotlib.pyplot.plot`. `````` André Anjos committed Sep 28, 2016 74 `````` `````` André Anjos committed Sep 29, 2016 75 76 `````` kwargs (:py:class:`dict`, optional): Extra plotting parameters, which are passed directly to :py:func:`matplotlib.pyplot.plot`. `````` André Anjos committed Sep 28, 2016 77 78 79 80 `````` Returns: `````` André Anjos committed Sep 29, 2016 81 82 83 `````` :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 84 85 86 `````` """ `````` Manuel Günther committed Nov 25, 2015 87 `````` from matplotlib import pyplot `````` André Anjos committed Nov 21, 2013 88 `````` from . import roc as calc `````` André Anjos committed Dec 12, 2013 89 `````` out = calc(negatives, positives, npoints) `````` André Anjos committed Nov 21, 2013 90 `````` if not CAR: `````` Manuel Günther committed Nov 25, 2015 91 `````` return pyplot.plot(100.0*out[0,:], 100.0*out[1,:], **kwargs) `````` André Anjos committed Nov 21, 2013 92 `````` else: `````` Manuel Günther committed Nov 25, 2015 93 94 `````` return pyplot.semilogx(100.0*out[0,:], 100.0*(1-out[1,:]), **kwargs) `````` André Anjos committed Nov 21, 2013 95 `````` `````` 96 ``````def roc_for_far(negatives, positives, far_values = log_values(), **kwargs): `````` André Anjos committed Sep 28, 2016 97 `````` """Plots the ROC curve for the given list of False Acceptance Rates (FAR). `````` 98 99 100 `````` 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 101 102 103 `````` 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. `````` 104 `````` `````` André Anjos committed Sep 28, 2016 105 106 107 `````` The plot will represent the False Acceptance Rate (FAR) on the horizontal axis and the Correct Acceptance Rate (CAR) on the vertical axis. The values for the axis will be computed using :py:func:`bob.measure.roc_for_far`. `````` 108 109 110 111 112 113 114 115 `````` .. 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 116 117 118 119 120 `````` 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`) `````` 121 `````` `````` André Anjos committed Sep 28, 2016 122 123 124 `````` positives (array): 1D float array that contains the scores of the "positive" (signal, class) samples of your classifier. See (:py:func:`bob.measure.roc`) `````` 125 `````` `````` André Anjos committed Sep 29, 2016 126 127 `````` far_values (:py:class:`list`, optional): The values for the FAR, where the CAR should be plotted; each value should be in range [0,1]. `````` 128 `````` `````` André Anjos committed Sep 29, 2016 129 130 `````` kwargs (:py:class:`dict`, optional): Extra plotting parameters, which are passed directly to :py:func:`matplotlib.pyplot.plot`. `````` André Anjos committed Sep 28, 2016 131 132 133 134 `````` Returns: `````` André Anjos committed Sep 29, 2016 135 136 137 `````` :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`. `````` 138 139 140 141 142 143 144 145 146 `````` """ from matplotlib import pyplot from . import roc_for_far as calc out = calc(negatives, positives, far_values) return pyplot.semilogx(100.0*out[0,:], 100.0*(1-out[1,:]), **kwargs) `````` André Anjos committed Nov 21, 2013 147 ``````def precision_recall_curve(negatives, positives, npoints=100, **kwargs): `````` André Anjos committed Sep 28, 2016 148 `````` """Plots a Precision-Recall curve. `````` André Anjos committed Nov 21, 2013 149 `````` `````` André Anjos committed Sep 28, 2016 150 151 152 153 154 155 `````` 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 156 `````` `````` Manuel Günther committed Nov 25, 2015 157 `````` .. note:: `````` André Anjos committed Nov 21, 2013 158 `````` `````` Manuel Günther committed Nov 25, 2015 159 160 161 `````` 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 162 163 `````` `````` André Anjos committed Sep 28, 2016 164 165 166 167 168 169 170 171 172 `````` 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 173 `````` `````` André Anjos committed Sep 29, 2016 174 `````` npoints (:py:class:`int`, optional): The number of points for the plot. See `````` André Anjos committed Sep 28, 2016 175 `````` (:py:func:`bob.measure.precision_recall_curve`) `````` André Anjos committed Nov 21, 2013 176 `````` `````` André Anjos committed Sep 29, 2016 177 178 `````` kwargs (:py:class:`dict`, optional): Extra plotting parameters, which are passed directly to :py:func:`matplotlib.pyplot.plot`. `````` André Anjos committed Nov 21, 2013 179 180 `````` `````` André Anjos committed Sep 28, 2016 181 182 `````` Returns: `````` André Anjos committed Sep 29, 2016 183 184 185 `````` :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 186 `````` `````` André Anjos committed Nov 21, 2013 187 188 `````` """ `````` Manuel Günther committed Nov 25, 2015 189 `````` from matplotlib import pyplot `````` André Anjos committed Nov 21, 2013 190 191 `````` from . import precision_recall_curve as calc out = calc(negatives, positives, npoints) `````` Manuel Günther committed Nov 25, 2015 192 `````` return pyplot.plot(100.0*out[0,:], 100.0*out[1,:], **kwargs) `````` André Anjos committed Nov 21, 2013 193 194 195 196 197 198 199 200 201 202 203 `````` def epc(dev_negatives, dev_positives, test_negatives, test_positives, npoints=100, **kwargs): """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 204 `````` This method will call ``matplotlib`` to plot the EPC curve for a system which `````` André Anjos committed Nov 21, 2013 205 206 `````` 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 207 208 209 `````` :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 210 `````` `````` André Anjos committed Sep 28, 2016 211 212 `````` The plot will represent the minimum HTER on the vertical axis and the cost on the horizontal axis. `````` André Anjos committed Nov 21, 2013 213 `````` `````` Manuel Günther committed Nov 25, 2015 214 `````` .. note:: `````` André Anjos committed Nov 21, 2013 215 `````` `````` Manuel Günther committed Nov 25, 2015 216 217 218 `````` 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 219 220 `````` `````` André Anjos committed Sep 28, 2016 221 222 223 224 225 226 227 228 229 `````` 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 230 `````` `````` André Anjos committed Sep 28, 2016 231 232 233 `````` 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 234 `````` `````` André Anjos committed Sep 28, 2016 235 236 237 `````` 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 238 `````` `````` André Anjos committed Sep 29, 2016 239 `````` npoints (:py:class:`int`, optional): The number of points for the plot. See `````` André Anjos committed Sep 28, 2016 240 241 `````` (:py:func:`bob.measure.epc`) `````` André Anjos committed Sep 29, 2016 242 243 `````` kwargs (:py:class:`dict`, optional): Extra plotting parameters, which are passed directly to :py:func:`matplotlib.pyplot.plot`. `````` André Anjos committed Sep 28, 2016 244 245 246 247 `````` Returns: `````` André Anjos committed Sep 29, 2016 248 249 250 `````` :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 251 252 253 `````` """ `````` Manuel Günther committed Nov 25, 2015 254 `````` from matplotlib import pyplot `````` André Anjos committed Nov 21, 2013 255 256 `````` from . import epc as calc `````` André Anjos committed Sep 28, 2016 257 258 `````` out = calc(dev_negatives, dev_positives, test_negatives, test_positives, npoints) `````` Manuel Günther committed Nov 25, 2015 259 260 `````` return pyplot.plot(out[0,:], 100.0*out[1,:], **kwargs) `````` André Anjos committed Nov 21, 2013 261 262 263 264 265 266 267 268 269 `````` def det(negatives, positives, npoints=100, axisfontsize='x-small', **kwargs): """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 270 271 272 273 274 `````` 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 275 `````` `````` Manuel Günther committed Nov 25, 2015 276 277 `````` 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 278 279 280 281 282 283 284 285 286 287 288 289 290 291 `````` 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 292 `````` If you wish to reset axis zooming, you must use the Gaussian scale rather `````` André Anjos committed Nov 21, 2013 293 `````` than the visual marks showed at the plot, which are just there for `````` André Anjos committed Sep 28, 2016 294 295 296 `````` 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 297 298 299 `````` .. code-block:: python `````` André Anjos committed May 26, 2014 300 `````` import bob.measure `````` Manuel Günther committed Nov 25, 2015 301 `````` from matplotlib import pyplot `````` André Anjos committed May 26, 2014 302 `````` bob.measure.plot.det(...) #call this as many times as you need `````` André Anjos committed Nov 21, 2013 303 `````` #AFTER you plot the DET curve, just set the axis in this way: `````` Manuel Günther committed Nov 25, 2015 304 `````` pyplot.axis([bob.measure.ppndf(k/100.0) for k in (1, 40, 1, 40)]) `````` André Anjos committed Nov 21, 2013 305 306 `````` We provide a convenient way for you to do the above in this module. So, `````` André Anjos committed Sep 28, 2016 307 308 `````` optionally, you may use the :py:func:`bob.measure.plot.det_axis` method like this: `````` André Anjos committed Nov 21, 2013 309 310 311 `````` .. code-block:: python `````` André Anjos committed May 26, 2014 312 313 `````` import bob.measure bob.measure.plot.det(...) `````` André Anjos committed Nov 21, 2013 314 `````` # please note we convert percentage values in det_axis() `````` André Anjos committed May 26, 2014 315 `````` bob.measure.plot.det_axis([1, 40, 1, 40]) `````` André Anjos committed Nov 21, 2013 316 317 `````` `````` André Anjos committed Sep 28, 2016 318 319 320 321 322 `````` 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 323 `````` `````` André Anjos committed Sep 28, 2016 324 325 326 `````` 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 327 `````` `````` André Anjos committed Sep 29, 2016 328 `````` npoints (:py:class:`int`, optional): The number of points for the plot. See `````` André Anjos committed Sep 28, 2016 329 `````` (:py:func:`bob.measure.det`) `````` Manuel Günther committed Nov 25, 2015 330 `````` `````` André Anjos committed Sep 29, 2016 331 332 `````` 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 333 `````` `````` André Anjos committed Sep 29, 2016 334 335 `````` kwargs (:py:class:`dict`, optional): Extra plotting parameters, which are passed directly to :py:func:`matplotlib.pyplot.plot`. `````` André Anjos committed Sep 28, 2016 336 337 338 339 `````` Returns: `````` André Anjos committed Sep 29, 2016 340 341 342 `````` :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 343 344 `````` """ `````` André Anjos committed Nov 21, 2013 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 `````` # these are some constants required in this method desiredTicks = [ "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" ] desiredLabels = [ "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" ] # this will actually do the plotting `````` Manuel Günther committed Nov 25, 2015 372 `````` from matplotlib import pyplot `````` André Anjos committed Nov 21, 2013 373 374 375 `````` from . import det as calc from . import ppndf `````` André Anjos committed Dec 12, 2013 376 `````` out = calc(negatives, positives, npoints) `````` Manuel Günther committed Nov 25, 2015 377 `````` retval = pyplot.plot(out[0,:], out[1,:], **kwargs) `````` André Anjos committed Nov 21, 2013 378 379 380 `````` # now the trick: we must plot the tick marks by hand using the PPNDF method pticks = [ppndf(float(v)) for v in desiredTicks] `````` Manuel Günther committed Nov 25, 2015 381 `````` ax = pyplot.gca() #and finally we set our own tick marks `````` André Anjos committed Nov 21, 2013 382 383 384 385 386 387 388 `````` ax.set_xticks(pticks) ax.set_xticklabels(desiredLabels, size=axisfontsize) ax.set_yticks(pticks) ax.set_yticklabels(desiredLabels, size=axisfontsize) return retval `````` Manuel Günther committed Nov 25, 2015 389 `````` `````` André Anjos committed Nov 21, 2013 390 391 392 ``````def det_axis(v, **kwargs): """Sets the axis in a DET plot. `````` Manuel Günther committed Nov 25, 2015 393 `````` This method wraps the :py:func:`matplotlib.pyplot.axis` by calling `````` André Anjos committed Sep 28, 2016 394 395 396 397 398 `````` :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 399 `````` `````` André Anjos committed Sep 29, 2016 400 401 402 403 404 `````` v (:py:class:`list`, :py:class:`tuple`): A sequence contaiing 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 405 `````` `````` André Anjos committed Sep 29, 2016 406 407 `````` kwargs (:py:class:`dict`, optional): Extra plotting parameters, which are passed directly to :py:func:`matplotlib.pyplot.axis`. `````` André Anjos committed Nov 21, 2013 408 409 `````` `````` André Anjos committed Sep 28, 2016 410 411 412 `````` Returns: object: Whatever is returned by :py:func:`matplotlib.pyplot.axis`. `````` André Anjos committed Nov 21, 2013 413 414 415 416 `````` """ import logging `````` Manuel Günther committed Nov 25, 2015 417 `````` logger = logging.getLogger("bob.measure") `````` André Anjos committed Nov 21, 2013 418 `````` `````` Manuel Günther committed Nov 25, 2015 419 `````` from matplotlib import pyplot `````` André Anjos committed Nov 21, 2013 420 421 422 423 424 425 426 `````` from . import ppndf # treat input try: 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 427 `````` cur = pyplot.axis() `````` André Anjos committed Nov 21, 2013 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 `````` # 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 446 447 `````` return pyplot.axis(tv, **kwargs) `````` André Anjos committed Nov 21, 2013 448 449 `````` def cmc(cmc_scores, logx = True, **kwargs): `````` André Anjos committed Sep 28, 2016 450 451 452 453 454 455 456 457 458 459 `````` """Plots the (cumulative) match characteristics and returns the maximum rank. This function plots a CMC curve using the given CMC scores, which can be read from the our score files using the :py:func:`bob.measure.load.cmc_four_column` or :py:func:`bob.measure.load.cmc_five_column` methods. The structure of the ``cmc_scores`` parameter is relatively complex. It contains a list of pairs of lists. For each probe object, a pair of list negative and positive scores is required. `````` Manuel Günther committed Sep 17, 2015 460 `````` `````` André Anjos committed Sep 28, 2016 461 `````` Parameters: `````` Manuel Günther committed Sep 17, 2015 462 `````` `````` André Anjos committed Sep 28, 2016 463 464 `````` cmc_scores (array): 1D float array containing the CMC values (See :py:func:`bob.measure.cmc`) `````` Manuel Günther committed Sep 17, 2015 465 `````` `````` André Anjos committed Sep 29, 2016 466 467 468 `````` 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 469 `````` `````` André Anjos committed Sep 29, 2016 470 471 `````` 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 472 `````` `````` Manuel Günther committed Nov 25, 2015 473 `````` `````` André Anjos committed Sep 28, 2016 474 475 476 `````` Returns: int: The number of classes (clients) in the given scores. `````` André Anjos committed Nov 21, 2013 477 `````` `````` Manuel Günther committed Nov 25, 2015 478 `````` """ `````` André Anjos committed Sep 28, 2016 479 `````` `````` Manuel Günther committed Nov 25, 2015 480 `````` from matplotlib import pyplot `````` André Anjos committed Nov 21, 2013 481 `````` from . import cmc as calc `````` Manuel Günther committed Nov 25, 2015 482 `````` `````` André Anjos committed Nov 21, 2013 483 484 485 `````` out = calc(cmc_scores) if logx: `````` Manuel Günther committed Nov 25, 2015 486 `````` pyplot.semilogx(range(1, len(out)+1), out * 100, **kwargs) `````` André Anjos committed Nov 21, 2013 487 `````` else: `````` Manuel Günther committed Nov 25, 2015 488 `````` pyplot.plot(range(1, len(out)+1), out * 100, **kwargs) `````` André Anjos committed Nov 21, 2013 489 490 `````` return len(out) `````` 491 492 `````` `````` André Anjos committed Sep 28, 2016 493 494 495 ``````def detection_identification_curve(cmc_scores, far_values = log_values(), rank = 1, logx = True, **kwargs): """Plots the Detection & Identification curve over the FAR `````` 496 `````` `````` André Anjos committed Sep 28, 2016 497 498 499 500 `````` 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``. `````` 501 `````` `````` André Anjos committed Sep 28, 2016 502 503 504 505 506 `````` The detection and identification curve first computes FAR thresholds based on 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. `````` 507 `````` `````` André Anjos committed Sep 28, 2016 508 `````` .. [LiJain2005] **Stan Li and Anil K. Jain**, *Handbook of Face Recognition*, Springer, 2005 `````` 509 510 `````` `````` André Anjos committed Sep 28, 2016 511 `````` Parameters: `````` 512 `````` `````` André Anjos committed Sep 28, 2016 513 514 `````` cmc_scores (array): 1D float array containing the CMC values (See :py:func:`bob.measure.cmc`) `````` 515 `````` `````` André Anjos committed Sep 29, 2016 516 517 `````` rank (:py:class:`int`, optional): The rank for which the curve should be plotted `````` 518 `````` `````` André Anjos committed Sep 29, 2016 519 520 `````` far_values (:py:class:`list`, optional): The values for the FAR, where the CAR should be plotted; each value should be in range [0,1]. `````` 521 `````` `````` André Anjos committed Sep 29, 2016 522 523 524 `````` 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 525 `````` `````` André Anjos committed Sep 29, 2016 526 527 `````` kwargs (:py:class:`dict`, optional): Extra plotting parameters, which are passed directly to :py:func:`matplotlib.pyplot.plot`. `````` André Anjos committed Sep 28, 2016 528 529 530 531 `````` Returns: `````` André Anjos committed Sep 29, 2016 532 533 534 `````` :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`. `````` 535 536 537 `````` """ `````` 538 `````` import numpy `````` 539 `````` from matplotlib import pyplot `````` 540 `````` from . import far_threshold, detection_identification_rate `````` 541 `````` `````` 542 543 544 545 `````` # 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) if not negatives: raise ValueError("There need to be at least one pair with only negative scores") `````` 546 547 548 549 `````` # compute thresholds based on FAR values thresholds = [far_threshold(negatives, [], v, True) for v in far_values] `````` 550 551 `````` # compute detection and identification rate based on the thresholds for the given rank rates = [100.*detection_identification_rate(cmc_scores, t, rank) for t in thresholds] `````` 552 553 554 555 556 557 `````` # plot curve if logx: return pyplot.semilogx(far_values, rates, **kwargs) else: return pyplot.plot(far_values, rates, **kwargs)``````