Commit 190eb6de authored by Amir MOHAMMADI's avatar Amir MOHAMMADI

lint

parent 5df44007
......@@ -8,6 +8,7 @@ from . import common_options
from bob.extension.scripts.click_helper import (verbosity_option,
open_file_mode_option)
@click.command()
@common_options.scores_argument(nargs=-1)
@common_options.eval_option()
......@@ -24,9 +25,9 @@ def metrics(ctx, scores, evaluation, **kwargs):
"""Prints a table that contains FtA, FAR, FRR, FMR, FMNR, HTER for a given
threshold criterion (eer or min-hter).
You need to provide one or more development score file(s) for each experiment.
You can also provide evaluation files along with dev files. If only dev scores
are provided, you must use flag `--no-evaluation`.
You need to provide one or more development score file(s) for each
experiment. You can also provide evaluation files along with dev files. If
only dev scores are provided, you must use flag `--no-evaluation`.
Resulting table format can be changed using the `--tablefmt`.
......@@ -40,6 +41,7 @@ def metrics(ctx, scores, evaluation, **kwargs):
process = figure.Metrics(ctx, scores, evaluation, load.split)
process.run()
@click.command()
@common_options.scores_argument(nargs=-1)
@common_options.title_option()
......@@ -66,9 +68,9 @@ def roc(ctx, scores, evaluation, **kwargs):
false non match rate on the vertical axis. The values for the axis will be
computed using :py:func:`bob.measure.roc`.
You need to provide one or more development score file(s) for each experiment.
You can also provide evaluation files along with dev files. If only dev scores
are provided, you must use flag `--no-evaluation`.
You need to provide one or more development score file(s) for each
experiment. You can also provide evaluation files along with dev files. If
only dev scores are provided, you must use flag `--no-evaluation`.
Examples:
$ bob measure roc dev-scores
......@@ -81,6 +83,7 @@ def roc(ctx, scores, evaluation, **kwargs):
process = figure.Roc(ctx, scores, evaluation, load.split)
process.run()
@click.command()
@common_options.scores_argument(nargs=-1)
@common_options.output_plot_file_option(default_out='det.pdf')
......@@ -106,9 +109,9 @@ def det(ctx, scores, evaluation, **kwargs):
modified ROC curve which plots error rates on both axes
(false positives on the x-axis and false negatives on the y-axis)
You need to provide one or more development score file(s) for each experiment.
You can also provide evaluation files along with dev files. If only dev scores
are provided, you must use flag `--no-evaluation`.
You need to provide one or more development score file(s) for each
experiment. You can also provide evaluation files along with dev files. If
only dev scores are provided, you must use flag `--no-evaluation`.
Examples:
$ bob measure det dev-scores
......@@ -121,6 +124,7 @@ def det(ctx, scores, evaluation, **kwargs):
process = figure.Det(ctx, scores, evaluation, load.split)
process.run()
@click.command()
@common_options.scores_argument(min_arg=1, force_eval=True, nargs=-1)
@common_options.output_plot_file_option(default_out='epc.pdf')
......@@ -152,6 +156,7 @@ def epc(ctx, scores, **kwargs):
process = figure.Epc(ctx, scores, True, load.split)
process.run()
@click.command()
@common_options.scores_argument(nargs=-1)
@common_options.output_plot_file_option(default_out='hist.pdf')
......@@ -174,9 +179,9 @@ def hist(ctx, scores, evaluation, **kwargs):
""" Plots histograms of positive and negatives along with threshold
criterion.
You need to provide one or more development score file(s) for each experiment.
You can also provide evaluation files along with dev files. If only dev scores
are provided, you must use flag `--no-evaluation`.
You need to provide one or more development score file(s) for each
experiment. You can also provide evaluation files along with dev files. If
only dev scores are provided, you must use flag `--no-evaluation`.
By default, when eval-scores are given, only eval-scores histograms are
displayed with threshold line
......@@ -194,6 +199,7 @@ def hist(ctx, scores, evaluation, **kwargs):
process = figure.Hist(ctx, scores, evaluation, load.split)
process.run()
@click.command()
@common_options.scores_argument(nargs=-1)
@common_options.legends_option()
......@@ -217,8 +223,8 @@ def evaluate(ctx, scores, evaluation, **kwargs):
\b
1. Computes the threshold using either EER or min. HTER criteria on
development set scores
2. Applies the above threshold on evaluation set scores to compute the HTER, if a
eval-score set is provided
2. Applies the above threshold on evaluation set scores to compute the
HTER, if a eval-score set is provided
3. Reports error rates on the console
4. Plots ROC, EPC, DET curves and score distributions to a multi-page PDF
file
......@@ -261,12 +267,12 @@ def evaluate(ctx, scores, evaluation, **kwargs):
click.echo("Starting evaluate with dev scores only...")
click.echo("Computing ROC...")
# set axes limits for ROC
ctx.forward(roc) # use class defaults plot settings
ctx.forward(roc) # use class defaults plot settings
click.echo("Computing DET...")
ctx.forward(det) # use class defaults plot settings
ctx.forward(det) # use class defaults plot settings
if evaluation:
click.echo("Computing EPC...")
ctx.forward(epc) # use class defaults plot settings
ctx.forward(epc) # use class defaults plot settings
# the last one closes the file
ctx.meta['closef'] = True
click.echo("Computing score histograms...")
......
......@@ -9,6 +9,7 @@ from bob.extension.scripts.click_helper import (bool_option, list_float_option)
LOGGER = logging.getLogger(__name__)
def scores_argument(min_arg=1, force_eval=False, **kwargs):
"""Get the argument for scores, and add `dev-scores` and `eval-scores` in
the context when `--evaluation` flag is on (default)
......@@ -35,7 +36,7 @@ def scores_argument(min_arg=1, force_eval=False, **kwargs):
if 'train' in ctx.meta and ctx.meta['train']:
mutli += 1
error += '- %d training file(s) \n' % min_a
#add more test here if other inputs are needed
# add more test here if other inputs are needed
min_a *= mutli
ctx.meta['min_arg'] = min_a
......@@ -54,6 +55,7 @@ def scores_argument(min_arg=1, force_eval=False, **kwargs):
)(func)
return custom_scores_argument
def eval_option(**kwargs):
'''Get option flag to say if eval-scores are provided'''
return bool_option(
......@@ -61,34 +63,40 @@ def eval_option(**kwargs):
dflt=True
)
def sep_dev_eval_option(dflt=True, **kwargs):
'''Get option flag to say if dev and eval plots should be in different
plots'''
return bool_option(
'split', 's','If set, evaluation and dev curve in different plots',
'split', 's', 'If set, evaluation and dev curve in different plots',
dflt
)
def linestyles_option(dflt=False, **kwargs):
''' Get option flag to turn on/off linestyles'''
return bool_option('line-linestyles', 'S', 'If given, applies a different '
'linestyles to each line.', dflt, **kwargs)
def cmc_option(**kwargs):
'''Get option flag to say if cmc scores'''
return bool_option('cmc', 'C', 'If set, CMC score files are provided',
**kwargs)
def semilogx_option(dflt=False, **kwargs):
'''Option to use semilog X-axis'''
return bool_option('semilogx', 'G', 'If set, use semilog on X axis', dflt,
**kwargs)
def print_filenames_option(dflt=True, **kwargs):
'''Option to tell if filenames should be in the title'''
return bool_option('show-fn', 'P', 'If set, show filenames in title', dflt,
**kwargs)
def const_layout_option(dflt=True, **kwargs):
'''Option to set matplotlib constrained_layout'''
def custom_layout_option(func):
......@@ -102,6 +110,7 @@ def const_layout_option(dflt=True, **kwargs):
callback=callback, **kwargs)(func)
return custom_layout_option
def axes_val_option(dflt=None, **kwargs):
''' Option for setting min/max values on axes '''
return list_float_option(
......@@ -111,6 +120,7 @@ def axes_val_option(dflt=None, **kwargs):
nitems=4, dflt=dflt, **kwargs
)
def thresholds_option(**kwargs):
''' Option to give a list of thresholds '''
return list_float_option(
......@@ -120,14 +130,17 @@ def thresholds_option(**kwargs):
nitems=None, dflt=None, **kwargs
)
def lines_at_option(**kwargs):
'''Get option to draw const far line'''
return list_float_option(
name='lines-at', short_name='la',
desc='If given, draw vertical lines at the given axis positions',
desc='If given, draw vertical lines at the given axis positions. '
'You can provide multiple values separated with a comma (,).',
nitems=None, dflt='1e-3', **kwargs
)
def x_rotation_option(dflt=0, **kwargs):
'''Get option for rotartion of the x axis lables'''
def custom_x_rotation_option(func):
......@@ -136,11 +149,12 @@ def x_rotation_option(dflt=0, **kwargs):
ctx.meta['x_rotation'] = value
return value
return click.option(
'-r', '--x-rotation', type=click.INT, default=dflt, show_default=True,
help='X axis labels ration',
'-r', '--x-rotation', type=click.INT, default=dflt,
show_default=True, help='X axis labels ration',
callback=callback, **kwargs)(func)
return custom_x_rotation_option
def legend_ncols_option(dflt=10, **kwargs):
'''Get option for number of columns for legends'''
def custom_legend_ncols_option(func):
......@@ -149,11 +163,13 @@ def legend_ncols_option(dflt=10, **kwargs):
ctx.meta['legends_ncol'] = value
return value
return click.option(
'-lc', '--legends-ncol', type=click.INT, default=dflt, show_default=True,
'-lc', '--legends-ncol', type=click.INT, default=dflt,
show_default=True,
help='The number of columns of the legend layout.',
callback=callback, **kwargs)(func)
return custom_legend_ncols_option
def subplot_option(dflt=111, **kwargs):
'''Get option to set subplots'''
def custom_subplot_option(func):
......@@ -165,11 +181,12 @@ def subplot_option(dflt=111, **kwargs):
ctx.meta['n_row'] = nrows
return value
return click.option(
'-sp', '--subplot', type=click.INT, default=dflt, show_default=True,
help='The order of subplots.',
'-sp', '--subplot', type=click.INT, default=dflt,
show_default=True, help='The order of subplots.',
callback=callback, **kwargs)(func)
return custom_subplot_option
def cost_option(**kwargs):
'''Get option to get cost for FAR'''
def custom_cost_option(func):
......@@ -184,14 +201,15 @@ def cost_option(**kwargs):
callback=callback, **kwargs)(func)
return custom_cost_option
def points_curve_option(**kwargs):
'''Get the number of points use to draw curves'''
def custom_points_curve_option(func):
def callback(ctx, param, value):
if value < 2:
raise click.BadParameter(
'Number of points to draw curves must be greater than 1'
, ctx=ctx
'Number of points to draw curves must be greater than 1',
ctx=ctx
)
ctx.meta['points'] = value
return value
......@@ -201,6 +219,7 @@ def points_curve_option(**kwargs):
callback=callback, **kwargs)(func)
return custom_points_curve_option
def n_bins_option(**kwargs):
'''Get the number of bins in the histograms'''
def custom_n_bins_option(func):
......@@ -223,6 +242,7 @@ def n_bins_option(**kwargs):
callback=callback, **kwargs)(func)
return custom_n_bins_option
def table_option(**kwargs):
'''Get table option for tabulate package
More informnations: https://pypi.python.org/pypi/tabulate
......@@ -238,9 +258,10 @@ def table_option(**kwargs):
'`jira`, `presto`, `psql`, `rst`, `mediawiki`, `moinmoin`, '
'`youtrack`, `html`, `latex`, '
'`latex_raw`, `latex_booktabs`, `textile`',
callback=callback,**kwargs)(func)
callback=callback, **kwargs)(func)
return custom_table_option
def output_plot_file_option(default_out='plots.pdf', **kwargs):
'''Get options for output file for plots'''
def custom_output_plot_file_option(func):
......@@ -258,6 +279,7 @@ def output_plot_file_option(default_out='plots.pdf', **kwargs):
callback=callback, **kwargs)(func)
return custom_output_plot_file_option
def output_log_metric_option(**kwargs):
'''Get options for output file for metrics'''
def custom_output_log_file_option(func):
......@@ -269,10 +291,11 @@ def output_log_metric_option(**kwargs):
return click.option(
'-l', '--log', default=None, type=click.STRING,
help='If provided, computed numbers are written to '
'this file instead of the standard output.',
'this file instead of the standard output.',
callback=callback, **kwargs)(func)
return custom_output_log_file_option
def criterion_option(lcriteria=['eer', 'min-hter', 'far'], **kwargs):
"""Get option flag to tell which criteriom is used (default:eer)
......@@ -284,7 +307,7 @@ def criterion_option(lcriteria=['eer', 'min-hter', 'far'], **kwargs):
def custom_criterion_option(func):
def callback(ctx, param, value):
list_accepted_crit = lcriteria if lcriteria is not None else \
['eer', 'min-hter', 'far']
['eer', 'min-hter', 'far']
if value not in list_accepted_crit:
raise click.BadParameter('Incorrect value for `--criterion`. '
'Must be one of [`%s`]' %
......@@ -295,9 +318,10 @@ def criterion_option(lcriteria=['eer', 'min-hter', 'far'], **kwargs):
'-c', '--criterion', default='eer',
help='Criterion to compute plots and '
'metrics: `eer`, `min-hter` or `far`',
callback=callback, is_eager=True ,**kwargs)(func)
callback=callback, is_eager=True, **kwargs)(func)
return custom_criterion_option
def far_option(**kwargs):
'''Get option to get far value'''
def custom_far_option(func):
......@@ -309,9 +333,10 @@ def far_option(**kwargs):
return click.option(
'-f', '--far-value', type=click.FLOAT, default=None,
help='The FAR value for which to compute metrics',
callback=callback, show_default=True,**kwargs)(func)
callback=callback, show_default=True, **kwargs)(func)
return custom_far_option
def min_far_option(dflt=1e-4, **kwargs):
'''Get option to get min far value'''
def custom_min_far_option(func):
......@@ -324,9 +349,10 @@ def min_far_option(dflt=1e-4, **kwargs):
'-M', '--min-far-value', type=click.FLOAT, default=dflt,
help='Select the minimum FAR value used in ROC and DET plots; '
'should be a power of 10.',
callback=callback, show_default=True,**kwargs)(func)
callback=callback, show_default=True, **kwargs)(func)
return custom_min_far_option
def figsize_option(dflt='4,3', **kwargs):
"""Get option for matplotlib figsize
......@@ -350,22 +376,25 @@ def figsize_option(dflt='4,3', **kwargs):
return value
return click.option(
'--figsize', default=dflt, help='If given, will run '
'``plt.rcParams[\'figure.figsize\']=figsize)``. Example: --fig-size 4,6',
'``plt.rcParams[\'figure.figsize\']=figsize)``. '
'Example: --fig-size 4,6',
callback=callback, **kwargs)(func)
return custom_figsize_option
def legend_loc_option(**kwargs):
'''Get tthe legend location of the plot'''
'''Get the legend location of the plot'''
def custom_legend_loc_option(func):
def callback(ctx, param, value):
ctx.meta['legend_loc'] = value
return value
return click.option(
'--legend-location', default=0, show_default=True,
type=INT, help='The lengend location code',
type=INT, help='The legend location code',
callback=callback, **kwargs)(func)
return custom_legend_loc_option
def line_width_option(**kwargs):
'''Get line width option for the plots'''
def custom_line_width_option(func):
......@@ -378,6 +407,7 @@ def line_width_option(**kwargs):
callback=callback, **kwargs)(func)
return custom_line_width_option
def marker_style_option(**kwargs):
'''Get marker style otpion for the plots'''
def custom_marker_style_option(func):
......@@ -390,6 +420,7 @@ def marker_style_option(**kwargs):
callback=callback, **kwargs)(func)
return custom_marker_style_option
def legends_option(**kwargs):
'''Get the legends option for the different systems'''
def custom_legends_option(func):
......@@ -405,6 +436,7 @@ def legends_option(**kwargs):
callback=callback, **kwargs)(func)
return custom_legends_option
def title_option(**kwargs):
'''Get the title option for the different systems'''
def custom_title_option(func):
......@@ -413,10 +445,12 @@ def title_option(**kwargs):
return value
return click.option(
'-t', '--title', type=click.STRING, default=None,
help='The title of the plots',
help="The title of the plots. Provide just a space (-t ' ') to "
"remove the titles from figures.",
callback=callback, **kwargs)(func)
return custom_title_option
def x_label_option(dflt=None, **kwargs):
'''Get the label option for X axis '''
def custom_x_label_option(func):
......@@ -429,6 +463,7 @@ def x_label_option(dflt=None, **kwargs):
callback=callback, **kwargs)(func)
return custom_x_label_option
def y_label_option(dflt=None, **kwargs):
'''Get the label option for Y axis '''
def custom_y_label_option(func):
......@@ -441,6 +476,7 @@ def y_label_option(dflt=None, **kwargs):
callback=callback, **kwargs)(func)
return custom_y_label_option
def style_option(**kwargs):
'''Get option for matplotlib style'''
def custom_style_option(func):
......@@ -449,7 +485,8 @@ def style_option(**kwargs):
plt.style.use(value)
return value
return click.option(
'--style', multiple=True, type=click.types.Choice(sorted(plt.style.available)),
'--style', multiple=True,
type=click.types.Choice(sorted(plt.style.available)),
help='The matplotlib style to use for plotting. You can provide '
'multiple styles by repeating this option',
callback=callback, **kwargs)(func)
......
......@@ -12,6 +12,7 @@ from matplotlib.backends.backend_pdf import PdfPages
from tabulate import tabulate
from .. import (far_threshold, plot, utils, ppndf)
class MeasureBase(object):
"""Base class for metrics and plots.
This abstract class define the framework to plot or compute metrics from a
......@@ -22,7 +23,8 @@ class MeasureBase(object):
func_load:
Function that is used to load the input files
"""
__metaclass__ = ABCMeta #for python 2.7 compatibility
__metaclass__ = ABCMeta # for python 2.7 compatibility
def __init__(self, ctx, scores, evaluation, func_load):
"""
Parameters
......@@ -69,7 +71,7 @@ class MeasureBase(object):
# Note that more than one dev or eval scores score can be passed to
# each system
for idx in range(self.n_systems):
# load scores for each system: get the corresponding arrays and
# load scores for each system: get the corresponding arrays and
# base-name of files
input_scores, input_names = self._load_files(
# Scores are given as followed:
......@@ -137,6 +139,7 @@ class MeasureBase(object):
scores.append(self.func_load(filename))
return scores, basenames
class Metrics(MeasureBase):
''' Compute metrics from score files
......@@ -145,25 +148,26 @@ class Metrics(MeasureBase):
log_file: str
output stream
'''
def __init__(self, ctx, scores, evaluation, func_load):
super(Metrics, self).__init__(ctx, scores, evaluation, func_load)
self._tablefmt = None if 'tablefmt' not in ctx.meta else\
ctx.meta['tablefmt']
ctx.meta['tablefmt']
self._criterion = None if 'criterion' not in ctx.meta else \
ctx.meta['criterion']
ctx.meta['criterion']
self._open_mode = None if 'open_mode' not in ctx.meta else\
ctx.meta['open_mode']
ctx.meta['open_mode']
self._thres = None if 'thres' not in ctx.meta else ctx.meta['thres']
if self._thres is not None :
if self._thres is not None:
if len(self._thres) == 1:
self._thres = self._thres * self.n_systems
elif len(self._thres) != self.n_systems:
raise click.BadParameter(
'#thresholds must be the same as #systems (%d)' \
'#thresholds must be the same as #systems (%d)'
% len(self.n_systems)
)
self._far = None if 'far_value' not in ctx.meta else \
ctx.meta['far_value']
ctx.meta['far_value']
self._log = None if 'log' not in ctx.meta else ctx.meta['log']
self.log_file = sys.stdout
if self._log is not None:
......@@ -180,23 +184,22 @@ class Metrics(MeasureBase):
eval_file = input_names[1]
threshold = utils.get_thres(self._criterion, dev_neg, dev_pos, self._far) \
if self._thres is None else self._thres[idx]
if self._thres is None else self._thres[idx]
title = self._legends[idx] if self._legends is not None else None
if self._thres is None:
far_str = ''
if self._criterion == 'far' and self._far is not None:
far_str = str(self._far)
click.echo("[Min. criterion: %s %s] Threshold on Development set `%s`: %e"\
click.echo("[Min. criterion: %s %s] Threshold on Development set `%s`: %e"
% (self._criterion.upper(),
far_str, title or dev_file,
threshold),
file=self.log_file)
else:
click.echo("[Min. criterion: user provider] Threshold on "
"Development set `%s`: %e"\
"Development set `%s`: %e"
% (dev_file or title, threshold), file=self.log_file)
from .. import farfrr
dev_fmr, dev_fnmr = farfrr(dev_neg, dev_pos, threshold)
dev_far = dev_fmr * (1 - dev_fta)
......@@ -232,11 +235,14 @@ class Metrics(MeasureBase):
eval_ni = eval_neg.shape[0] # number of impostors
eval_fm = int(round(eval_fmr * eval_ni)) # number of false accepts
eval_nc = eval_pos.shape[0] # number of clients
eval_fnm = int(round(eval_fnmr * eval_nc)) # number of false rejects
# number of false rejects
eval_fnm = int(round(eval_fnmr * eval_nc))
eval_fta_str = "%.1f%%" % (100 * eval_fta)
eval_fmr_str = "%.1f%% (%d/%d)" % (100 * eval_fmr, eval_fm, eval_ni)
eval_fnmr_str = "%.1f%% (%d/%d)" % (100 * eval_fnmr, eval_fnm, eval_nc)
eval_fmr_str = "%.1f%% (%d/%d)" % (100 *
eval_fmr, eval_fm, eval_ni)
eval_fnmr_str = "%.1f%% (%d/%d)" % (100 *
eval_fnmr, eval_fnm, eval_nc)
eval_far_str = "%.1f%%" % (100 * eval_far)
eval_frr_str = "%.1f%%" % (100 * eval_frr)
......@@ -257,10 +263,12 @@ class Metrics(MeasureBase):
if self._log is not None:
self.log_file.close()
class PlotBase(MeasureBase):
''' Base class for plots. Regroup several options and code
shared by the different plots
'''
def __init__(self, ctx, scores, evaluation, func_load):
super(PlotBase, self).__init__(ctx, scores, evaluation, func_load)
self._output = None if 'output' not in ctx.meta else ctx.meta['output']
......@@ -274,30 +282,31 @@ class PlotBase(MeasureBase):
self._min_dig = int(math.log10(self._axlim[0])
if self._axlim[0] != 0 else 0)
self._clayout = None if 'clayout' not in ctx.meta else\
ctx.meta['clayout']
ctx.meta['clayout']
self._far_at = None if 'lines_at' not in ctx.meta else\
ctx.meta['lines_at']
ctx.meta['lines_at']
self._trans_far_val = self._far_at
if self._far_at is not None:
self._eval_points = {line: [] for line in self._far_at}
self._lines_val = []
self._print_fn = True if 'show_fn' not in ctx.meta else\
ctx.meta['show_fn']
ctx.meta['show_fn']
self._x_rotation = None if 'x_rotation' not in ctx.meta else \
ctx.meta['x_rotation']
ctx.meta['x_rotation']
if 'style' in ctx.meta:
mpl.style.use(ctx.meta['style'])
self._nb_figs = 2 if self._eval and self._split else 1
self._colors = utils.get_colors(self.n_systems)
self._line_linestyles = False if 'line_linestyles' not in ctx.meta else \
ctx.meta['line_linestyles']
self._linestyles = utils.get_linestyles(self.n_systems, self._line_linestyles)
ctx.meta['line_linestyles']
self._linestyles = utils.get_linestyles(
self.n_systems, self._line_linestyles)
self._states = ['Development', 'Evaluation']
self._title = None if 'title' not in ctx.meta else ctx.meta['title']
self._x_label = None if 'x_label' not in ctx.meta else\
ctx.meta['x_label']
ctx.meta['x_label']
self._y_label = None if 'y_label' not in ctx.meta else\
ctx.meta['y_label']
ctx.meta['y_label']
self._grid_color = 'silver'
self._pdf_page = None
self._end_setup_plot = True
......@@ -308,11 +317,11 @@ class PlotBase(MeasureBase):
matplotlib.use('pdf')
self._pdf_page = self._ctx.meta['PdfPages'] if 'PdfPages'in \
self._ctx.meta else PdfPages(self._output)
self._ctx.meta else PdfPages(self._output)
for i in range(self._nb_figs):
fs = None if 'figsize' not in self._ctx.meta else\
self._ctx.meta['figsize']
self._ctx.meta['figsize']
fig = mpl.figure(i + 1, figsize=fs)
fig.set_constrained_layout(self._clayout)
fig.clear()
......@@ -320,7 +329,7 @@ class PlotBase(MeasureBase):
def end_process(self):
''' Set title, legend, axis labels, grid colors, save figures, drow
lines and close pdf if needed '''
#draw vertical lines
# draw vertical lines
if self._far_at is not None:
for (line, line_trans) in zip(self._far_at, self._trans_far_val):
mpl.figure(1)
......@@ -340,7 +349,7 @@ class PlotBase(MeasureBase):
mpl.plot(x_values,
y_values, '--',
color='black')
#only for plots
# only for plots
if self._end_setup_plot:
for i in range(self._nb_figs):
fig = mpl.figure(i + 1)
......@@ -358,12 +367,12 @@ class PlotBase(MeasureBase):
mpl.xticks(rotation=self._x_rotation)
self._pdf_page.savefig(fig)
#do not want to close PDF when running evaluate
# do not want to close PDF when running evaluate
if 'PdfPages' in self._ctx.meta and \
('closef' not in self._ctx.meta or self._ctx.meta['closef']):
self._pdf_page.close()
#common protected functions
# common protected functions
def _label(self, base, name, idx):
if self._legends is not None and len(self._legends) > idx:
......@@ -376,14 +385,16 @@ class PlotBase(MeasureBase):
if self._axlim is not None and None not in self._axlim:
mpl.axis(self._axlim)
class Roc(PlotBase):
''' Handles the plotting of ROC'''
def __init__(self, ctx, scores, evaluation, func_load):
super(Roc, self).__init__(ctx, scores, evaluation, func_load)
self._title = self._title or 'ROC'
self._x_label = self._x_label or 'False Positive Rate'
self._y_label = self._y_label or "1 - False Negative Rate"
#custom defaults
# custom defaults
if self._axlim is None:
self._axlim = [1e-4, 1.0, 0, 1.0]
......@@ -422,7 +433,8 @@ class Roc(PlotBase):
from .. import farfrr
for line in self._far_at:
thres_line = far_threshold(dev_neg, dev_pos, line)
eval_fmr, eval_fnmr = farfrr(eval_neg, eval_pos, thres_line)
eval_fmr, eval_fnmr = farfrr(
eval_neg, eval_pos, thres_line)
eval_fnmr = 1 - eval_fnmr
mpl.scatter(eval_fmr, eval_fnmr, c=self._colors[idx], s=30)
self._eval_points[line].append((eval_fmr, eval_fnmr))
......@@ -434,8 +446,10 @@ class Roc(PlotBase):
label=self._label('development', dev_file, idx)
)
class Det(PlotBase):
''' Handles the plotting of DET '''
def __init__(self, ctx, scores, evaluation, func_load):
super(Det, self).__init__(ctx, scores, evaluation, func_load)
self._title = self._title or 'DET'
......@@ -443,7 +457,7 @@ class Det(PlotBase):
self._y_label = self._y_label or 'False Negative Rate'
if self._far_at is not None:
self._trans_far_val = [ppndf(float(k)) for k in self._far_at]
#custom defaults here
# custom defaults here
if self._x_rotation is None:
self._x_rotation = 50
......@@ -482,7 +496,8 @@ class Det(PlotBase):
from .. import farfrr
for line in self._far_at:
thres_line = far_threshold(dev_neg, dev_pos, line)
eval_fmr, eval_fnmr = farfrr(eval_neg, eval_pos, thres_line)
eval_fmr, eval_fnmr = farfrr(