diff --git a/examples/plot_tasks.py b/examples/plot_tasks.py
new file mode 100644
index 0000000000000000000000000000000000000000..832de37e2e7c2a071d94c79d4bd34df3d6f994ce
--- /dev/null
+++ b/examples/plot_tasks.py
@@ -0,0 +1,260 @@
+#!/usr/bin/env python
+"""
+Usage:
+    plot_tasks.py input.dat output.png [time-range-ms]
+
+where input.dat is a thread info file for a step.  Use the '-y interval'
+flag of the swift MPI commands to create these. The output plot will be
+called 'output.png'. Use the time-range-ms in millisecs to produce
+plots with the same time span.
+
+This file is part of SWIFT.
+Copyright (c) 2015 Pedro Gonnet (pedro.gonnet@durham.ac.uk),
+                   Bert Vandenbroucke (bert.vandenbroucke@ugent.be)
+                   Matthieu Schaller (matthieu.schaller@durham.ac.uk)
+          (c) 2016 Peter W. Draper (p.w.draper@durham.ac.uk)
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published
+by the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+"""
+
+import matplotlib
+import matplotlib.pyplot as plt
+import matplotlib.colors as colors
+import matplotlib.collections as collections
+import matplotlib.cm as cmx
+from matplotlib import gridspec
+matplotlib.use('Agg')
+import pylab as pl
+import numpy as np
+import sys
+import math
+
+#  Basic plot configuration.
+PLOT_PARAMS = {"axes.labelsize": 10,
+               "axes.titlesize": 10,
+               "font.size": 12,
+               "legend.fontsize": 12,
+               "xtick.labelsize": 10,
+               "ytick.labelsize": 10,
+               "figure.figsize" : (16., 4.),
+               "figure.subplot.left" : 0.03,
+               "figure.subplot.right" : 0.995,
+               "figure.subplot.bottom" : 0.1,
+               "figure.subplot.top" : 0.99,
+               "figure.subplot.wspace" : 0.,
+               "figure.subplot.hspace" : 0.,
+               "lines.markersize" : 6,
+               "lines.linewidth" : 3.
+               }
+pl.rcParams.update(PLOT_PARAMS)
+
+#  Tasks and subtypes. Indexed as in tasks.h.
+TASKTYPES = ["none", "sort", "self", "pair", "sub_self", "sub_pair", "init", "ghost",
+             "extra_ghost", "kick", "send", "recv",
+             "grav_gather_m", "grav_fft", "grav_mm", "grav_up",
+             "grav_external", "cooling", "count"]
+
+TASKCOLOURS = {"none": "black",
+               "self": "lightblue",
+               "pair": "greenyellow",
+               "pair": "navy",
+               "sub_self": "greenyellow",
+               "sub_pair": "navy",
+               "init": "indigo",
+               "ghost": "cyan",
+               "extra_ghost": "cyan",
+               "kick": "green",
+               "send": "yellow",
+               "recv": "magenta",
+               "grav_gather_m": "mediumorchid",
+               "grav_fft": "mediumnightblue",
+               "grav_mm": "mediumturquoise",
+               "grav_up": "mediumvioletred",
+               "grav_external": "darkred",
+               "cooling": "darkblue",
+               "count": "powerblue"}
+
+SUBTYPES = ["none", "density", "gradient", "force", "grav", "tend", "count"]
+
+SUBCOLOURS = {"none": "black",
+              "density": "red",
+              "gradient": "powerblue",
+              "force": "blue",
+              "grav": "indigo",
+              "tend": "grey",
+              "count": "black"}
+
+#  Show docs if help is requested.
+if len( sys.argv ) == 2 and ( sys.argv[1][0:2] == "-h" or sys.argv[1][0:3] == "--h" ):
+    from pydoc import help
+    help( "__main__" )
+    sys.exit( 0 )
+
+#  Handle command-line.
+if len( sys.argv ) != 3 and len( sys.argv ) != 4:
+    print "Usage: ", sys.argv[0], "input.dat output.png [time-range-ms]"
+    sys.exit(1)
+
+infile = sys.argv[1]
+outpng = sys.argv[2]
+delta_t = 0
+if len( sys.argv ) == 4:
+    delta_t = int(sys.argv[3])
+
+#  Read input.
+data = pl.loadtxt( infile )
+
+nthread = int(max(data[:,1])) + 1
+print "Number of threads:", nthread
+
+jet = cm = plt.get_cmap('jet') 
+cNorm  = colors.Normalize(vmin=0, vmax=max(data[:,0]))
+scalarMap = cmx.ScalarMappable(norm=cNorm, cmap=jet)
+print scalarMap.get_clim()
+
+# Recover the start and end time
+#full_step = data[0,:]
+#tic_step = int(full_step[4])
+#toc_step = int(full_step[5])
+#CPU_CLOCK = float(full_step[-1])
+#data = data[1:,:]
+
+#print "CPU frequency:", CPU_CLOCK
+
+# Avoid start and end times of zero.
+#data = data[data[:,4] != 0]
+#data = data[data[:,5] != 0]
+
+# Calculate the time range, if not given.
+delta_t = max(data[:,3]) - min(data[:,2])
+print "Data range: ",delta_t, "ms"
+
+# Once more doing the real gather and plots this time.
+start_t = min(data[:,2])
+data[:,2] -= start_t
+data[:,3] -= start_t
+end_t = (max(data[:,3]))
+print "Start_t", start_t, "end_t", end_t
+
+tasks = {}
+tasks[-1] = []
+for i in range(nthread):
+    tasks[i] = []
+
+num_lines = len(data[:,0])
+for line in range(num_lines):
+    thread = int(data[line,1])
+    tasks[thread].append({})
+    tasks[thread][-1]["tic"] = data[line,2]
+    tasks[thread][-1]["toc"] = data[line,3]
+    tasks[thread][-1]["t"] = (data[line,1]+data[line,1])/2
+    tasks[thread][-1]["colour"] = data[line,0]
+
+combtasks = {}
+combtasks[-1] = []
+for i in range(nthread):
+    combtasks[i] = []
+
+for thread in range(nthread):
+    tasks[thread] = sorted(tasks[thread], key=lambda l: l["t"])
+    lastcolour = ""
+    colours = []
+    for task in tasks[thread]:
+        if task["colour"] not in colours:
+            colours.append(task["colour"])
+        #if(lastcolour == "" or not lastcolour == task["colour"]):
+        combtasks[thread].append({})
+        combtasks[thread][-1]["colour"] = task["colour"]
+        combtasks[thread][-1]["tic"] = task["tic"]
+        combtasks[thread][-1]["toc"] = task["toc"]
+        lastcolour = task["colour"]
+        #else:
+         #   combtasks[thread][-1]["toc"] = task["toc"]
+    
+    
+fig = pl.figure(figsize=(14, 6))
+gs = gridspec.GridSpec(1, 3, width_ratios=[12,1, 1]) 
+ax = pl.subplot(gs[0])
+ax2 = pl.subplot(gs[2])
+ax.set_xlim(-delta_t * 0.03, delta_t * 1.03)
+ax.set_ylim(0, nthread)
+tictoc = np.zeros(2)
+for i in range(nthread):
+
+    #  Collect ranges and colours into arrays.
+    tictocs = np.zeros(len(combtasks[i])*2)
+    colours = np.empty(len(combtasks[i])*2, dtype='object')
+    coloursseen = []
+    j = 0
+    for task in combtasks[i]:
+        tictocs[j] = task["tic"]
+        tictocs[j+1] = task["toc"]
+        colours[j] = task["colour"]
+        colours[j+1] = task["colour"]
+        j = j + 2
+        if task["colour"] not in coloursseen:
+            coloursseen.append(task["colour"])
+    
+        #  Legend support, collections don't add to this.
+#        if task["subtype"] != "none":
+#            qtask = task["type"] + "/" + task["subtype"]
+        #else:
+            #qtask = task["type"]
+        #if qtask not in typesseen:
+            #pl.plot([], [], color=task["colour"], label=qtask)
+            #typesseen.append(qtask)
+
+    #  Now plot each colour, faster to use a mask to select colour ranges.
+    for colour in coloursseen:
+#        for x in np.where(colours==colour):
+#            if i == 0:
+#                print tictocs[x], "\n: ",min(tictocs[x]), tictocs[np.where(tictocs == min(tictocs[x]))[0]+1]
+        collection = collections.BrokenBarHCollection.span_where(tictocs, ymin=i+0.05, ymax=i+0.95,
+                                                                 where=colours == colour,
+                                                                 facecolor=scalarMap.to_rgba(colour+1),
+                                                                 linewidths=0)
+        ax.add_collection(collection)
+
+#  Legend and room for it.
+#nrow = len(typesseen) / 5
+#if len(typesseen) * 5 < nrow:
+    #nrow = nrow + 1
+#ax.fill_between([0, 0], nthread+0.5, nthread + nrow + 0.5, facecolor="white")
+#ax.set_ylim(0, nthread + nrow + 1)
+#ax.legend(loc=1, shadow=True, mode="expand", ncol=5)
+
+# Start and end of time-step
+ax.plot([0, 0], [0, nthread], 'k--', linewidth=1)
+ax.plot([end_t, end_t], [0, nthread], 'k--', linewidth=1)
+
+ax.set_xlabel("Wall clock time [s]")
+ax.set_ylabel("Thread ID" )
+ax.set_yticks(pl.array(range(nthread)), True)
+
+
+dfge= matplotlib.colorbar.ColorbarBase(ax2, jet,norm=cNorm, ticks=[0, int(math.ceil(max(data[:,3])/2)), int(max(data[:,3]))] ,ticklocation='left', label='Number of taskyields')
+#dfge.set_ticks([0, max(data[:,6])/2, max(data[:,6])])
+#dfge.set_label("Number of taskyields")
+#ax2.set_ylabel("Number of taskyields")
+#ax2.set_yticks([0, max(data[:,6]) ])
+
+pl.savefig(outpng, format = 'png', dpi = 1000)
+pl.savefig('tasks.eps', format = 'eps', dpi = 1000)
+
+pl.show()
+
+print "Graphics done, output written to", outpng
+
+sys.exit(0)
+