diff --git a/.gitignore b/.gitignore
index 812aa06dd54ee8bb81e87796deb8ee05160fec72..893f786506ed168565fb995812136bcb7f1305f1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,11 +26,13 @@ examples/*/*.xmf
 examples/*/*.hdf5
 examples/*/*.png
 examples/*/*.txt
+examples/*/*.dot
 examples/*/used_parameters.yml
 examples/*/*/*.xmf
 examples/*/*/*.hdf5
 examples/*/*/*.png
 examples/*/*/*.txt
+examples/*/*/*.dot
 examples/*/*/used_parameters.yml
 examples/*/gravity_checks_*.dat
 
diff --git a/examples/plot_task_dependencies.sh b/examples/plot_task_dependencies.sh
new file mode 100755
index 0000000000000000000000000000000000000000..77784d8a9cdd3720621c9ad35c4cfbdaf0167ff1
--- /dev/null
+++ b/examples/plot_task_dependencies.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+#  Creates a graphic from the task graph file dependency_graph.dot.
+#  Requires the graphviz command "dot".
+
+if [ ! -e dependency_graph.dot ]; then
+    echo "Missing task-graph output 'dependency_graph.dot'! Cannot generate figure."
+else 
+    dot -Tpng dependency_graph.dot -o task_graph.png
+    echo "Output written to task_graph.png"
+fi
+
+exit
diff --git a/src/engine.c b/src/engine.c
index 725f9a7e0cc738417632b5a24993ea6865537575..6b46b0e9ee5673df2dc329c47e9ab820fbef3579 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -3596,6 +3596,8 @@ void engine_init_particles(struct engine *e, int flag_entropy_ICs,
     gravity_exact_force_compute(e->s, e);
 #endif
 
+  if (e->nodeID == 0) scheduler_write_dependencies(&e->sched, e->verbose);
+
   /* Run the 0th time-step */
   engine_launch(e);
 
diff --git a/src/scheduler.c b/src/scheduler.c
index 943d4582cb8cbaa3390514197ddcde02f64f4de6..5af9e9c9e19248838bb98c3ee2305d7dc54324f0 100644
--- a/src/scheduler.c
+++ b/src/scheduler.c
@@ -50,6 +50,7 @@
 #include "space.h"
 #include "task.h"
 #include "timers.h"
+#include "version.h"
 
 /**
  * @brief Re-set the list of active tasks.
@@ -111,6 +112,125 @@ void scheduler_addunlock(struct scheduler *s, struct task *ta,
   atomic_inc(&s->completed_unlock_writes);
 }
 
+/**
+ * @brief Write a dot file with the task dependencies.
+ *
+ * Run plot_task_dependencies.sh for an example of how to use it
+ * to generate the figure.
+ *
+ * @param s The #scheduler we are working in.
+ * @param verbose Are we verbose about this?
+ */
+void scheduler_write_dependencies(struct scheduler *s, int verbose) {
+
+  const ticks tic = getticks();
+
+  /* Conservative number of dependencies per task type */
+  const int max_nber_dep = 128;
+
+  /* Number of possible relations between tasks */
+  const int nber_relation =
+      2 * task_type_count * task_subtype_count * max_nber_dep;
+
+  /* To get the table of max_nber_dep for a task:
+   * ind = (ta * task_subtype_count + sa) * max_nber_dep * 2
+   * where ta is the value of task_type and sa is the value of
+   * task_subtype  */
+  int *table = malloc(nber_relation * sizeof(int));
+  if (table == NULL)
+    error("Error allocating memory for task-dependency graph.");
+
+  /* Reset everything */
+  for (int i = 0; i < nber_relation; i++) table[i] = -1;
+
+  /* Create file */
+  char filename[200] = "dependency_graph.dot";
+  FILE *f = fopen(filename, "w");
+  if (f == NULL) error("Error opening dependency graph file.");
+
+  /* Write header */
+  fprintf(f, "digraph task_dep {\n");
+  fprintf(f, "label=\"Task dependencies for SWIFT %s\"", git_revision());
+  fprintf(f, "\t compound=true;\n");
+  fprintf(f, "\t ratio=0.66;\n");
+  fprintf(f, "\t node[nodesep=0.15];\n");
+
+  /* loop over all tasks */
+  for (int i = 0; i < s->nr_tasks; i++) {
+    const struct task *ta = &s->tasks[i];
+
+    /* and their dependencies */
+    for (int j = 0; j < ta->nr_unlock_tasks; j++) {
+      const struct task *tb = ta->unlock_tasks[j];
+
+      /* check if dependency already written */
+      int written = 0;
+
+      /* Current index */
+      int ind = ta->type * task_subtype_count + ta->subtype;
+      ind *= 2 * max_nber_dep;
+
+      int k = 0;
+      int *cur = &table[ind];
+      while (k < max_nber_dep) {
+
+        /* not written yet */
+        if (cur[0] == -1) {
+          cur[0] = tb->type;
+          cur[1] = tb->subtype;
+          break;
+        }
+
+        /* already written */
+        if (cur[0] == tb->type && cur[1] == tb->subtype) {
+          written = 1;
+          break;
+        }
+
+        k += 1;
+        cur = &cur[3];
+      }
+
+      /* max_nber_dep is too small */
+      if (k == max_nber_dep)
+        error("Not enough memory, please increase max_nber_dep");
+
+      /* Not written yet => write it */
+      if (!written) {
+
+        /* text to write */
+        char ta_name[200];
+        char tb_name[200];
+
+        /* construct line */
+        if (ta->subtype == task_subtype_none)
+          sprintf(ta_name, "%s", taskID_names[ta->type]);
+        else
+          sprintf(ta_name, "\"%s %s\"", taskID_names[ta->type],
+                  subtaskID_names[ta->subtype]);
+
+        if (tb->subtype == task_subtype_none)
+          sprintf(tb_name, "%s", taskID_names[tb->type]);
+        else
+          sprintf(tb_name, "\"%s %s\"", taskID_names[tb->type],
+                  subtaskID_names[tb->subtype]);
+
+        /* Write to the ffile */
+        fprintf(f, "\t %s->%s;\n", ta_name, tb_name);
+      }
+    }
+  }
+
+  /* Be clean */
+  fprintf(f, "}");
+  fclose(f);
+  free(table);
+
+  if (verbose)
+    message("Printing task graph took %.3f %s.",
+            clocks_from_ticks(getticks() - tic), clocks_getunit());
+}
+
 /**
  * @brief Split a hydrodynamic task if too large.
  *
diff --git a/src/scheduler.h b/src/scheduler.h
index 5f7ffa70cff09d9ec90194bd0de91019bec8b9f0..1a75544de12b8402e553e3ae2b84e2d8a65c56e8 100644
--- a/src/scheduler.h
+++ b/src/scheduler.h
@@ -172,5 +172,6 @@ void scheduler_dump_queue(struct scheduler *s);
 void scheduler_print_tasks(const struct scheduler *s, const char *fileName);
 void scheduler_clean(struct scheduler *s);
 void scheduler_free_tasks(struct scheduler *s);
+void scheduler_write_dependencies(struct scheduler *s, int verbose);
 
 #endif /* SWIFT_SCHEDULER_H */