Commit 6384d856 authored by Theophile GENTILHOMME's avatar Theophile GENTILHOMME

Modify the display of histograms: now can use subplots to display several...

Modify the display of histograms: now can use subplots to display several histograms on one page, can no longer display both dev and eval histo at the same time, can control the number of columns in the legend
parent b4e207e4
Pipeline #19717 passed with stage
in 74 minutes
......@@ -160,13 +160,14 @@ def epc(ctx, scores, **kwargs):
@common_options.criterion_option()
@common_options.thresholds_option()
@common_options.const_layout_option()
@common_options.show_dev_option()
@common_options.print_filenames_option()
@common_options.title_option()
@common_options.legends_option()
@common_options.figsize_option()
@common_options.figsize_option(dflt=None)
@common_options.style_option()
@common_options.linestyles_option()
@common_options.subplot_option()
@common_options.legend_ncols_option()
@verbosity_option()
@click.pass_context
def hist(ctx, scores, evaluation, **kwargs):
......
......@@ -84,11 +84,6 @@ def semilogx_option(dflt=False, **kwargs):
return bool_option('semilogx', 'G', 'If set, use semilog on X axis', dflt,
**kwargs)
def show_dev_option(dflt=False, **kwargs):
'''Option to tell if should show dev histo'''
return bool_option('show-dev', 'D', 'If set, show dev histograms', 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,
......@@ -129,7 +124,7 @@ 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 veritcal lines at the given axis positions',
desc='If given, draw vertical lines at the given axis positions',
nitems=None, dflt='1e-3', **kwargs
)
......@@ -146,6 +141,35 @@ def x_rotation_option(dflt=0, **kwargs):
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):
def callback(ctx, param, value):
value = abs(value)
ctx.meta['legends_ncol'] = value
return value
return click.option(
'-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):
def callback(ctx, param, value):
value = abs(value)
nrows = value // 10
nrows, ncols = divmod(nrows, 10)
ctx.meta['n_col'] = ncols
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.',
callback=callback, **kwargs)(func)
return custom_subplot_option
def cost_option(**kwargs):
'''Get option to get cost for FAR'''
def custom_cost_option(func):
......@@ -330,18 +354,6 @@ def figsize_option(dflt='4,3', **kwargs):
callback=callback, **kwargs)(func)
return custom_figsize_option
def legend_ncols_option(**kwargs):
'''Get the number of columns to set in the legend of the plot'''
def custom_legend_ncols_option(func):
def callback(ctx, param, value):
ctx.meta['legend_ncol'] = value
return value
return click.option(
'--legend-ncol', default=3, show_default=True,
type=INT, help='The number of columns of the legend layout.',
callback=callback, **kwargs)(func)
return custom_legend_ncols_option
def legend_loc_option(**kwargs):
'''Get tthe legend location of the plot'''
def custom_legend_loc_option(func):
......
......@@ -533,8 +533,6 @@ class Hist(PlotBase):
super(Hist, self).__init__(ctx, scores, evaluation, func_load)
self._nbins = [] if 'n_bins' not in ctx.meta else ctx.meta['n_bins']
self._thres = None if 'thres' not in ctx.meta else ctx.meta['thres']
self._show_dev = ((not self._eval) if 'show_dev' not in ctx.meta else\
ctx.meta['show_dev']) or not self._eval
if self._thres is not None and len(self._thres) != self.n_systems:
if len(self._thres) == 1:
self._thres = self._thres * self.n_systems
......@@ -545,8 +543,13 @@ class Hist(PlotBase):
)
self._criterion = None if 'criterion' not in ctx.meta else \
ctx.meta['criterion']
self._nrows = 1 if 'n_row' not in ctx.meta else ctx.meta['n_row']
self._ncols = 1 if 'n_col' not in ctx.meta else ctx.meta['n_col']
self._nlegends = 10 if 'legends_ncol' not in ctx.meta else \
ctx.meta['legends_ncol']
self._step_print = int(self._nrows * self._ncols)
self._title_base = 'Scores'
self._y_label = 'Probability Density'
self._y_label = 'Probability density'
self._x_label = 'Scores values'
self._end_setup_plot = False
......@@ -556,43 +559,30 @@ class Hist(PlotBase):
self._get_neg_pos_thres(idx, input_scores, input_names)
dev_file = input_names[0]
eval_file = None if len(input_names) != 2 else input_names[1]
fig = mpl.figure()
if eval_neg is not None and self._show_dev:
mpl.subplot(2, 1, 1)
if self._show_dev:
self._setup_hist(dev_neg, dev_pos)
mpl.title(self._get_title(idx, dev_file, eval_file))
mpl.ylabel(self._y_label)
if not self._eval:
mpl.xlabel(self._x_label)
if eval_neg is not None and self._show_dev:
ax = mpl.gca()
ax.axes.get_xaxis().set_ticklabels([])
#Setup lines, corresponding axis and legends
label = "%s threshold" % ('' if self._criterion is None else
self._criterion.upper())
self._lines(threshold, label, dev_neg, dev_pos)
n = idx % self._step_print
col = n % self._ncols
sub_plot_idx = n + 1
axis = mpl.subplot(self._nrows, self._ncols, sub_plot_idx)
neg = eval_neg if eval_neg is not None else dev_neg
pos = eval_pos if eval_pos is not None else dev_pos
self._setup_hist(neg, pos)
if col == 0:
axis.set_ylabel(self._y_label)
if n + self._ncols >= min(self._step_print, self.n_systems):
axis.set_xlabel(self._x_label)
axis.set_title(self._get_title(idx, dev_file, eval_file))
label = "%s threshold%s" % (
'' if self._criterion is None else\
self._criterion.upper(), ' (dev)' if self._eval else ''
)
self._lines(threshold, label, neg, pos)
if sub_plot_idx == 1:
self._plot_legends()
if eval_neg is not None:
if self._show_dev:
mpl.subplot(2, 1, 2)
self._setup_hist(
eval_neg, eval_pos
)
if not self._show_dev:
mpl.title(self._get_title(idx, dev_file, eval_file))
mpl.ylabel('Probability density')
mpl.xlabel(self._x_label)
#Setup lines, corresponding axis and legends
label = "%s threshold (dev)" % ('' if self._criterion is None else
self._criterion.upper())
self._lines(threshold, label, eval_neg, eval_pos)
if not self._show_dev:
self._plot_legends()
self._pdf_page.savefig(fig)
if self._step_print == sub_plot_idx or idx == self.n_systems - 1:
mpl.tight_layout()
self._pdf_page.savefig(mpl.gcf(), bbox_inches="tight")
mpl.clf()
mpl.figure()
def _get_title(self, idx, dev_file, eval_file):
title = self._legends[idx] if self._legends is not None else None
......@@ -607,14 +597,10 @@ class Hist(PlotBase):
li, la = ax.get_legend_handles_labels()
lines += li
labels += la
if self._show_dev and self._eval:
mpl.legend(
lines, labels, loc='upper center', ncol=6,
bbox_to_anchor=(0.5, -0.01), fontsize=6
)
else:
mpl.legend(lines, labels,
loc='best', fancybox=True, framealpha=0.5)
mpl.gcf().legend(
lines, labels, fontsize=6, loc='lower center', fancybox=True,
framealpha=0.5, ncol=self._nlegends,
)
def _get_neg_pos_thres(self, idx, input_scores, input_names):
neg_list, pos_list, _ = utils.get_fta_list(input_scores)
......@@ -658,4 +644,3 @@ class Hist(PlotBase):
pos[0], n=1,
label='Positives', alpha=0.5, color='C0'
)
......@@ -140,6 +140,7 @@ def test_hist():
with runner.isolated_filesystem():
result = runner.invoke(commands.hist, ['--criterion', 'eer','--output',
'HISTO.pdf', '-b', '30,20',
'-sp', 221,
dev1, test1, dev2, test2])
if result.output:
click.echo(result.output)
......
......@@ -126,7 +126,6 @@ CLI options
bob.measure.script.common_options.eval_option
bob.measure.script.common_options.sep_dev_eval_option
bob.measure.script.common_options.cmc_option
bob.measure.script.common_options.show_dev_option
bob.measure.script.common_options.print_filenames_option
bob.measure.script.common_options.const_layout_option
bob.measure.script.common_options.axes_val_option
......@@ -151,6 +150,8 @@ CLI options
bob.measure.script.common_options.x_label_option
bob.measure.script.common_options.y_label_option
bob.measure.script.common_options.style_option
bob.measure.script.common_options.subplot_option
bob.measure.script.common_options.legend_ncols_option
Details
-------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment