diff --git a/beat/web/plotters/views.py b/beat/web/plotters/views.py
index 9cc7df14f2c8e441046439b13be0240d36b9bcf8..32fc2d41e61b690c60296617fcf6c75e09dfe2ab 100644
--- a/beat/web/plotters/views.py
+++ b/beat/web/plotters/views.py
@@ -450,6 +450,138 @@ def plot_sample(request):
 #----------------------------------------------------------
 
 
+def plot_sample_with_params(request):
+    """Plots sample data given as input plotter/plotterparameter/sample data
+
+    This view receives a single data payload with a GET or POST request
+    containing multiple keys.
+    We'll cycle through (with :py:func:`itertools.cycle`) them to recover a
+    dictionary like this::
+
+         {
+           'user/user/toolchain/1/label': {
+             "analyzer": "my_analysis",
+             "output" : "my_plot"
+           },
+           'user/user/toolchain/1/another': {
+             "analyzer": "my_analysis",
+             "output" : "my_plot"
+           },
+           'user/user/toolchain/3/xxx': {
+             "analyzer": "the_greatest_analysis",
+             "output" : "scatter"
+           }
+         }
+
+    A single ``plotter``, if passed, should reference the plotter to use. It
+    may be omitted, in which case we use the default plotter for the first
+    experiment in the list.
+
+
+    Returns:
+
+      A response with a single image inside, following the plotter
+      specifications.
+
+    """
+
+    if request.GET: use = request.GET
+    elif request.POST: use = request.POST
+    else:
+        return HttpResponseBadRequest('This view must be called with either a GET or POST request')
+
+    keywords = [
+            'experiment',
+            'experiment[]',
+            'analyzer',
+            'analyzer[]',
+            'output',
+            'output[]',
+            'plotter',
+            #'parameter',
+            'report_number',
+            ]
+
+    extra_parameters = {}
+    for key in [k for k in use.keys() if k not in keywords]:
+        extra_parameters[key] = '&'.join(use.getlist(key))
+
+    # Get the plotter and parameter, resolve if empty
+    final_plotter = None #use the default
+    #user_parameter = None #use the default
+    corefmt = None
+
+    if 'plotter' in use:
+        username, name, version = use['plotter'].split('/')
+        try:
+            final_plotter = Plotter.objects.get(author__username=username,
+                  name=name, version=version)
+        except Plotter.DoesNotExist as e:
+            message = "Plotter `%s' is not accessible" % \
+                    '/'.join((username, name, version))
+            logger.warn(message)
+            return HttpResponseBadRequest(message)
+
+    # Collect the data for the plot, check compatibility
+    default = None
+
+    # check compatibility, fill up defaults
+    if default is None:
+        default = DefaultPlotter.objects.filter(plotter=final_plotter)
+
+        if not default and not final_plotter:
+            message = 'No plotter specified and no default for plot format %s' % final_plotter.fullname()
+            return HttpResponseBadRequest(message)
+
+        default = default[0] #get the first and only
+
+        # set defaults, if specific values have not already been set
+        if not final_plotter: final_plotter = default.plotter
+
+        if corefmt is None: #loads it once
+            corefmt = final_plotter.core_format()
+
+    ## loads the data, for that particular result
+    parsed = simplejson.loads(use['sample_data'])
+    sample_data = corefmt.type().from_dict(parsed, casting='unsafe')
+
+    # checks the plotter is valid
+    core_plotter = final_plotter.core()
+    if not core_plotter.valid:
+        message = 'Plotter %s is invalid' % final_plotter.fullname()
+        return HttpResponseBadRequest(message)
+
+
+    # resolves parameters, in order of priority
+    final_parameters = {}
+    if default.parameter: #fills-up defaults for the type
+        final_parameters.update(simplejson.loads(default.parameter.data))
+    #get dynamic plotter params
+    final_parameters.update(simplejson.loads(use['dynamic_params']))
+    if extra_parameters: #fills-up defaults specified on the query
+        final_parameters.update(extra_parameters)
+
+    extra_parameters.setdefault('content_type', 'image/png') #in case not set
+
+    # for HTML display, you need to set this correctly
+    do_b64_encode = bool(extra_parameters.get('base64', False))
+
+    # we filter out parameters we can't handle
+    for key in final_parameters.keys():
+        if key not in core_plotter.parameters: del final_parameters[key]
+
+    runnable= core_plotter.runner()
+    runnable.setup(final_parameters)
+    assert runnable.ready
+    data_to_plot = [('sample_plot', sample_data)]
+    fig = runnable.process(data_to_plot)
+    if do_b64_encode: fig = base64.b64encode(fig)
+    return HttpResponse(fig, content_type=final_parameters['content_type'])
+
+
+#----------------------------------------------------------
+
+
 def view(request, author, name, version=None):
     """Shows the algorithm. The Web API is used to retrieve the details about
     the algorithm and check the accessibility.