diff --git a/bob/measure/plot.py b/bob/measure/plot.py
index 26aa239f017a74816052e9a8c0bc047a15e1e3af..5d414327111535e3a7d36facbe29bdf72dd0a1cb 100644
--- a/bob/measure/plot.py
+++ b/bob/measure/plot.py
@@ -481,9 +481,9 @@ def cmc(cmc_scores, logx=True, **kwargs):
   out = calc(cmc_scores)
 
   if logx:
-    pyplot.semilogx(range(1, len(out) + 1), out * 100, **kwargs)
+    pyplot.semilogx(range(1, len(out) + 1), out, **kwargs)
   else:
-    pyplot.plot(range(1, len(out) + 1), out * 100, **kwargs)
+    pyplot.plot(range(1, len(out) + 1), out, **kwargs)
 
   return len(out)
 
diff --git a/bob/measure/script/common_options.py b/bob/measure/script/common_options.py
index d2d0a8c8f614fdcf91d60d58fd30eb22097b9c4f..648f295397764ae7f70972d3cc922dedb4da673c 100644
--- a/bob/measure/script/common_options.py
+++ b/bob/measure/script/common_options.py
@@ -109,8 +109,10 @@ def axes_val_option(dflt=None, **kwargs):
                     raise click.BadParameter('Axis limits must be floats')
                 if None in value:
                     value = None
-            elif None not in dflt or len(dflt) == 4:
-                value = dflt if not all(isinstance(x, float) for x in dflt) else None
+                elif None not in dflt and len(dflt) == 4:
+                    value = dflt if not all(
+                        isinstance(x, float) for x in dflt
+                    ) else None
             ctx.meta['axlim'] = value
             return value
         return click.option(
diff --git a/bob/measure/script/figure.py b/bob/measure/script/figure.py
index 7c73b4d39f4ac8860741cce53e0531aa8fac12b2..c8e9cc55ecf9e5a2a593193a4e61eb23dba545c8 100644
--- a/bob/measure/script/figure.py
+++ b/bob/measure/script/figure.py
@@ -92,11 +92,8 @@ class MeasureBase(object):
             test_score = self.test_scores[idx] if self.test_scores is not None\
             else None
             test_file = None if self.test_names is None else self.test_names[idx]
-            dev_neg, dev_pos, dev_fta, test_neg, test_pos, test_fta =\
-                self._process_scores(dev_score, test_score)
             #does the main computations/plottings here
-            self.compute(idx, dev_neg, dev_pos, dev_fta, dev_file,
-                          test_neg, test_pos, test_fta, test_file)
+            self.compute(idx, dev_score, dev_file, test_score, test_file)
         #setup final configuration, plotting properties, ...
         self.end_process()
 
@@ -109,9 +106,9 @@ class MeasureBase(object):
 
     #Main computations are done here in the subclasses
     @abstractmethod
-    def compute(self, idx, dev_neg, dev_pos, dev_fta=None, dev_file=None,
-                test_neg=None, test_pos=None, test_fta=None, test_file=None):
-        """Compute metrics or plots from the inputs given by
+    def compute(self, idx, dev_score, dev_file=None,
+                test_score=None, test_file=None):
+        """Compute metrics or plots from the given scores provided by
         :py:func:`~bob.measure.script.figure.MeasureBase.run`.
         Should reimplemented in derived classes
 
@@ -121,20 +118,18 @@ class MeasureBase(object):
         idx : :obj:`int`
             index of the system
 
-        dev_neg : :py:class:`numpy.ndarray`
-            negative dev scores
-        dev_pos : :py:class:`numpy.ndarray`
-            positive dev scores
-        dev_fta : :obj:`float`
-            failure to acquire rate
+        dev_score:
+            Development scores. Can be a tuple (neg, pos) of
+            :py:class:`numpy.ndarray` (e.g.
+            :py:func:`~bob.measure.script.Roc.compute`) or
+            a :any:`list` of tuples of :py:class:`numpy.ndarray` (e.g. cmc)
         dev_file : str
             name of the dev file without extension
-        test_neg : :py:class:`numpy.ndarray`
-            negative test scores
-        test_pos : :py:class:`numpy.ndarray`
-            positive test scores
-        test_fta : :obj:`float`
-            failure to acquire rate for test scores
+        test_score:
+            Test scores. Can be a tuple (neg, pos) of
+            :py:class:`numpy.ndarray` (e.g.
+            :py:func:`~bob.measure.script.Roc.compute`) or
+            a :any:`list` of tuples of :py:class:`numpy.ndarray` (e.g. cmc)
         test_file : str
             name of the test file without extension
         """
@@ -143,6 +138,9 @@ class MeasureBase(object):
     #Things to do after the main iterative computations are done
     @abstractmethod
     def end_process(self):
+        """ Called in :py:func:`~bob.measure.script.figure.MeasureBase`.run
+        after iterating through the different sytems.
+        Should reimplemented in derived classes"""
         pass
 
     #common protected functions
@@ -153,7 +151,7 @@ class MeasureBase(object):
         Returns
         -------
 
-            :any:`list`: A list of tuples, where each tuple contains the
+            :any:`list`: A list (of list) of tuples, where each tuple contains the
             ``negative`` and ``positive`` scores for one probe of the database. Both
             ``negatives`` and ``positives`` can be either an 1D'''
 
@@ -228,10 +226,12 @@ class Metrics(MeasureBase):
         if self._log is not None:
             self.log_file = open(self._log, self._open_mode)
 
-    def compute(self, idx, dev_neg, dev_pos, dev_fta=None, dev_file=None,
-                test_neg=None, test_pos=None, test_fta=None, test_file=None):
+    def compute(self, idx, dev_score, dev_file=None,
+                test_score=None, test_file=None):
         ''' Compute metrics thresholds and tables (FAR, FMR, FMNR, HTER) for
         given system inputs'''
+        dev_neg, dev_pos, dev_fta, test_neg, test_pos, test_fta =\
+                self._process_scores(dev_score, test_score)
         threshold = utils.get_thres(self._criter, dev_neg, dev_pos) \
                 if self._thres is None else self._thres
         if self._thres is None:
@@ -419,10 +419,14 @@ class Roc(PlotBase):
 
     _semilogx: :obj:`bool`
         If true, X-axis will be semilog10
+
+    _fmr_at: :obj:`float`
+        If not None, plot a vertical line at this value on the dev plot and
+        corresponding dots on the test plot (if any).
     '''
     def __init__(self, ctx, scores, test, func_load):
         super(Roc, self).__init__(ctx, scores, test, func_load)
-        self._semilogx = None if 'semilogx' not in ctx.meta else\
+        self._semilogx = True if 'semilogx' not in ctx.meta else\
         ctx.meta['semilogx']
         self._fmr_at = None if 'fmr_at' not in ctx.meta else\
         ctx.meta['fmr_at']
@@ -433,10 +437,12 @@ class Roc(PlotBase):
         if self._axlim is None:
             self._axlim = [1e-4, 1.0, 1e-4, 1.0]
 
-    def compute(self, idx, dev_neg, dev_pos, dev_fta=None, dev_file=None,
-                test_neg=None, test_pos=None, test_fta=None, test_file=None):
+    def compute(self, idx, dev_score, dev_file=None,
+                test_score=None, test_file=None):
         ''' Plot ROC for dev and eval data using
         :py:func:`bob.measure.plot.roc`'''
+        dev_neg, dev_pos, _, test_neg, test_pos, _ =\
+                self._process_scores(dev_score, test_score)
         mpl.figure(1)
         if self._test:
             linestyle = '-' if not self._split else LINESTYLES[idx % 14]
@@ -486,10 +492,12 @@ class Det(PlotBase):
         if self._x_rotation is None:
             self._x_rotation = 50
 
-    def compute(self, idx, dev_neg, dev_pos, dev_fta=None, dev_file=None,
-                test_neg=None, test_pos=None, test_fta=None, test_file=None):
+    def compute(self, idx, dev_score, dev_file=None,
+                test_score=None, test_file=None):
         ''' Plot DET for dev and eval data using
         :py:func:`bob.measure.plot.det`'''
+        dev_neg, dev_pos, _, test_neg, test_pos, _ =\
+                self._process_scores(dev_score, test_score)
         mpl.figure(1)
         if self._test and test_neg is not None:
             linestyle = '-' if not self._split else LINESTYLES[idx % 14]
@@ -531,10 +539,11 @@ class Epc(PlotBase):
         self._test = True #always test data with EPC
         self._nb_figs = 1
 
-    def compute(self, idx, dev_neg, dev_pos, dev_fta=None, dev_file=None,
-                test_neg=None, test_pos=None, test_fta=None, test_file=None):
+    def compute(self, idx, dev_score, dev_file, test_score, test_file=None):
         ''' Plot EPC using
         :py:func:`bob.measure.plot.epc`'''
+        dev_neg, dev_pos, _, test_neg, test_pos, _ =\
+                self._process_scores(dev_score, test_score)
         plot.epc(
             dev_neg, dev_pos, test_neg, test_pos, self._points,
             color=self._colors[idx], linestyle=LINESTYLES[idx % 14],
@@ -566,9 +575,11 @@ class Hist(PlotBase):
         self._x_label = 'Score values' if not self._test else ''
         self._end_setup_plot = False
 
-    def compute(self, idx, dev_neg, dev_pos, dev_fta=None, dev_file=None,
-                test_neg=None, test_pos=None, test_fta=None, test_file=None):
+    def compute(self, idx, dev_score, dev_file=None,
+                test_score=None, test_file=None):
         ''' Draw histograms of negative and positive scores.'''
+        dev_neg, dev_pos, _, test_neg, test_pos, _ =\
+                self._process_scores(dev_score, test_score)
         threshold = utils.get_thres(self._criter, dev_neg, dev_pos) \
                 if self._thres is None else self._thres