diff --git a/bob/measure/script/commands.py b/bob/measure/script/commands.py index 262b107ed49079e0f39547bf0f5737c1cbc33bc9..21e4d9680ee10c65abbf3baf245a2413e77fb2bd 100644 --- a/bob/measure/script/commands.py +++ b/bob/measure/script/commands.py @@ -44,7 +44,7 @@ def metrics(ctx, scores, evaluation, **kwargs): @click.command() @common_options.scores_argument(nargs=-1) -@common_options.title_option() +@common_options.titles_option() @common_options.legends_option() @common_options.no_legend_option() @common_options.legend_loc_option(dflt=None) @@ -89,7 +89,7 @@ def roc(ctx, scores, evaluation, **kwargs): @click.command() @common_options.scores_argument(nargs=-1) @common_options.output_plot_file_option(default_out='det.pdf') -@common_options.title_option() +@common_options.titles_option() @common_options.legends_option() @common_options.no_legend_option() @common_options.legend_loc_option(dflt='upper-right') @@ -132,7 +132,7 @@ def det(ctx, scores, evaluation, **kwargs): @click.command() @common_options.scores_argument(min_arg=1, force_eval=True, nargs=-1) @common_options.output_plot_file_option(default_out='epc.pdf') -@common_options.title_option() +@common_options.titles_option() @common_options.legends_option() @common_options.no_legend_option() @common_options.legend_loc_option(dflt='upper-center') @@ -172,7 +172,6 @@ def epc(ctx, scores, **kwargs): @common_options.thresholds_option() @common_options.const_layout_option() @common_options.print_filenames_option() -@common_options.title_option() @common_options.legends_option() @common_options.figsize_option(dflt=None) @common_options.style_option() diff --git a/bob/measure/script/common_options.py b/bob/measure/script/common_options.py index e3549f9758181d91e1271d28fd0c884eac893b00..780b85fd133feddde7cd18d7d64bdf3f0adf574a 100644 --- a/bob/measure/script/common_options.py +++ b/bob/measure/script/common_options.py @@ -461,6 +461,25 @@ def title_option(**kwargs): return custom_title_option +def titles_option(**kwargs): + '''Get the titles option for the different plots''' + def custom_title_option(func): + def callback(ctx, param, value): + if value is not None: + value = value.split(',') + ctx.meta['titles'] = value or [] + return value or [] + return click.option( + '-ts', '--titles', type=click.STRING, default=None, + help='The titles of the plots seperated by commas. ' + 'For example, if the figure has two plots, \"MyTitleA,MyTitleB\" ' + 'is a possible input' + '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): diff --git a/bob/measure/script/figure.py b/bob/measure/script/figure.py index d6f8040f9e6ab961eda430479f6e686202de44eb..1fe241e324a384b71d029af547ba9cdf3760a394 100644 --- a/bob/measure/script/figure.py +++ b/bob/measure/script/figure.py @@ -294,8 +294,13 @@ class PlotBase(MeasureBase): self._line_linestyles = ctx.meta.get('line_linestyles', False) self._linestyles = utils.get_linestyles( self.n_systems, self._line_linestyles) - self._states = ['Development', 'Evaluation'] + self._titles = ctx.meta.get('titles', []) * 2 + # for compatibility self._title = ctx.meta.get('title') + if not self._titles and self._title is not None: + self._titles = [self._title] * 2 + + self._x_label = ctx.meta.get('x_label') self._y_label = ctx.meta.get('y_label') self._grid_color = 'silver' @@ -343,12 +348,8 @@ class PlotBase(MeasureBase): if self._end_setup_plot: for i in range(self._nb_figs): fig = mpl.figure(i + 1) - title = self._title - if not self._eval: - title += (" (%s)" % self._states[0]) - elif self._split: - title += (" (%s)" % self._states[i]) - mpl.title(title if self._title.replace(' ', '') else '') + title = '' if not self._titles else self._titles[i] + mpl.title(title if title.replace(' ', '') else '') mpl.xlabel(self._x_label) mpl.ylabel(self._y_label) mpl.grid(True, color=self._grid_color) @@ -382,7 +383,7 @@ class Roc(PlotBase): def __init__(self, ctx, scores, evaluation, func_load): super(Roc, self).__init__(ctx, scores, evaluation, func_load) - self._title = self._title or 'ROC' + self._titles = self._titles or ['ROC dev', 'ROC eval'] self._x_label = self._x_label or 'False Positive Rate' self._y_label = self._y_label or "1 - False Negative Rate" self._semilogx = ctx.meta.get('semilogx', True) @@ -409,7 +410,7 @@ class Roc(PlotBase): far_values=plot.log_values(self._min_dig or -4), CAR=self._semilogx, color=self._colors[idx], linestyle=self._linestyles[idx], - label=self._label('development', dev_file, idx) + label=self._label('dev', dev_file, idx) ) if self._split: mpl.figure(2) @@ -437,7 +438,7 @@ class Roc(PlotBase): far_values=plot.log_values(self._min_dig or -4), CAR=self._semilogx, color=self._colors[idx], linestyle=self._linestyles[idx], - label=self._label('development', dev_file, idx) + label=self._label('dev', dev_file, idx) ) @@ -446,7 +447,7 @@ class Det(PlotBase): def __init__(self, ctx, scores, evaluation, func_load): super(Det, self).__init__(ctx, scores, evaluation, func_load) - self._title = self._title or 'DET' + self._titles = self._titles or ['DET dev', 'DET eval'] self._x_label = self._x_label or 'False Positive Rate (%)' self._y_label = self._y_label or 'False Negative Rate (%)' self._legend_loc = self._legend_loc or 'upper right' @@ -514,7 +515,7 @@ class Epc(PlotBase): super(Epc, self).__init__(ctx, scores, evaluation, func_load) if self._min_arg != 2: raise click.UsageError("EPC requires dev and eval score files") - self._title = self._title or 'EPC' + self._titles = self._titles or ['EPC'] * 2 self._x_label = self._x_label or r'$\alpha$' self._y_label = self._y_label or 'HTER (%)' self._legend_loc = self._legend_loc or 'upper center' @@ -603,9 +604,8 @@ class Hist(PlotBase): def _get_title(self, idx, dev_file, eval_file): title = self._legends[idx] if self._legends is not None else None - title = title or self._title or self._title_base - title = '' if self._title is not None and not self._title.replace( - ' ', '') else title + title = title or self._title_base + title = '' if title is not None and not title.replace(' ', '') else title return title or '' def _plot_legends(self): diff --git a/bob/measure/test_script.py b/bob/measure/test_script.py index d047b25540d1a9a7eec0881ed6f32535e2715810..4f8611f2fa5691c412b16c72f19dcfd3c6969bf4 100644 --- a/bob/measure/test_script.py +++ b/bob/measure/test_script.py @@ -56,6 +56,7 @@ def test_roc(): with runner.isolated_filesystem(): result = runner.invoke(commands.roc, ['--split', '--output', 'test.pdf', + '-ts', 'A,', dev1, test1, dev2, test2]) if result.output: click.echo(result.output) @@ -113,6 +114,7 @@ def test_epc(): with runner.isolated_filesystem(): result = runner.invoke(commands.epc, ['--output', 'test.pdf', '--legends', 'A,B', + '--titles', 'TA,TB', '-lc', 'upper-right', dev1, test1, dev2, test2]) if result.output: @@ -143,7 +145,7 @@ def test_hist(): with runner.isolated_filesystem(): result = runner.invoke(commands.hist, ['--criterion', 'eer','--output', 'HISTO.pdf', '-b', '30,20', - '-sp', 221, + '-sp', 221, '-lg', 'A,B', dev1, test1, dev2, test2]) if result.output: click.echo(result.output) diff --git a/doc/guide.rst b/doc/guide.rst index 9be9424d58b597e8065911f45ad682a5598de8c0..752b26bf914f18af0f80aa925d3be00d308ccf09 100644 --- a/doc/guide.rst +++ b/doc/guide.rst @@ -575,8 +575,8 @@ For example, to generate a DET curve from development and evaluation datasets: .. code-block:: sh - $bob measure det -v --output 'my_det.pdf' dev-1.txt eval-1.txt - dev-2.txt eval-2.txt + $bob measure det -v --output "my_det.pdf" -ts "DetDev1,DetEval1,DetDev2,DetEval2" + dev-1.txt eval-1.txt dev-2.txt eval-2.txt where `my_det.pdf` will contain DET plots for the two experiments.