diff --git a/build.gradle b/build.gradle
index 629e5bd35f8068eae889f10d3c30ca2d2d05213d..3c9a22f9a3d570b9ca88f0e6764ecd22149e7915 100644
--- a/build.gradle
+++ b/build.gradle
@@ -142,6 +142,7 @@ dependencies {
 	runtime 'ch.qos.logback:logback-classic:1+'
 
 	testCompile 'org.testng:testng:6+'
+	testCompile 'net.sf.jchart2d:jchart2d:3+'
 //	testCompile 'org.apache.jmeter:ApacheJMeter:2.+'
 }
 
diff --git a/src/test/java/it/unibz/inf/isochrone/network/AlgorithmRuntimeTest.java b/src/test/java/it/unibz/inf/isochrone/network/AlgorithmRuntimeTest.java
index 2018a9cecd35941b8488c6c8e6dc2b389b0b37f3..0e3ad513b884d645789e7d3d1aca2b6527727c55 100644
--- a/src/test/java/it/unibz/inf/isochrone/network/AlgorithmRuntimeTest.java
+++ b/src/test/java/it/unibz/inf/isochrone/network/AlgorithmRuntimeTest.java
@@ -1,5 +1,10 @@
 package it.unibz.inf.isochrone.network;
 
+import info.monitorenter.gui.chart.Chart2D;
+import info.monitorenter.gui.chart.IAxis;
+import info.monitorenter.gui.chart.IAxis.AxisTitle;
+import info.monitorenter.gui.chart.ITrace2D;
+import info.monitorenter.gui.chart.traces.Trace2DSimple;
 import it.unibz.inf.isochrone.algorithm.Isochrone;
 import it.unibz.inf.isochrone.algorithm.MDijkstra;
 import it.unibz.inf.isochrone.algorithm.MineX;
@@ -8,6 +13,9 @@ import it.unibz.inf.isochrone.config.ConfigDataset;
 import it.unibz.inf.isochrone.util.EnumContainer.Direction;
 import it.unibz.inf.isochrone.util.EnumContainer.Mode;
 
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Stroke;
 import java.io.BufferedWriter;
 import java.io.File;
 import java.io.IOException;
@@ -25,6 +33,8 @@ import java.util.Map.Entry;
 import java.util.Set;
 import java.util.TreeSet;
 
+import javax.imageio.ImageIO;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.annotations.AfterClass;
@@ -42,6 +52,7 @@ public final class AlgorithmRuntimeTest {
 	private static final int REPEAT_COUNT = 5;
 	private static final String RESULTFILE_ENCODING = "UTF-8";
 	private static final String RESULTFILE_CSV_RUNTIME = "build/reports/tests/algorithm-runtimes.csv";
+	private static final String RESULTFILE_PNG_RUNTIME = "build/reports/tests/algorithm-runtimes.png";
 	private static final String RESULTFILE_XML_RUNTIME = "build/reports/tests/algorithm-runtimes.xml";
 	private static final int[] RUNTIME_OFFSETS = {
 		60,		// 1 minute (in sec)
@@ -105,8 +116,9 @@ public final class AlgorithmRuntimeTest {
 
 	@AfterClass
 	public void writeRuntimes() {
-		writeRuntimeXML();
 		writeRuntimeCSV();
+		writeRuntimePNG();
+		writeRuntimeXML();
 	}
 
 	@BeforeClass(alwaysRun = true)
@@ -257,7 +269,7 @@ public final class AlgorithmRuntimeTest {
 				final Set<Entry<String, Long>> timeSet = results.entrySet();
 				final Iterator<Entry<String, Long>> iter = timeSet.iterator();
 				while (iter.hasNext()) {
-					fw.write(String.valueOf(iter.next().getValue().longValue() / repeatCount));
+					fw.write(String.valueOf(iter.next().getValue().longValue() / (double) repeatCount));
 					if (iter.hasNext()) {
 						fw.write(separator);
 					}
@@ -271,6 +283,72 @@ public final class AlgorithmRuntimeTest {
 		}
 	}
 
+	private static void writeMapToPNG(final File file, final Set<Entry<String, Map<String, Long>>> resultSet, final int repeatCount) {
+		final int nrAlgorithms = resultSet.iterator().next().getValue().size();
+
+		final Map<String, ITrace2D> traceMap = new HashMap<>(nrAlgorithms);
+		final Stroke stroke = new BasicStroke(3);
+		final Chart2D chart = new Chart2D();
+
+		final IAxis<?> axisX = chart.getAxisX();
+		axisX.setAxisTitle(new AxisTitle("Isochrone runtime (sec)"));
+
+		final IAxis<?> axisY = chart.getAxisY();
+		axisY.setAxisTitle(new AxisTitle("Time (msec)"));
+		axisY.setPaintGrid(true);
+
+		// Create colors
+		final Color[] colorArr = new Color[nrAlgorithms];
+		for (int i = 0; i < nrAlgorithms; ++i) {
+			// CHECKSTYLE:OFF MagicNumber
+			colorArr[i] = Color.getHSBColor((float) i / (float) nrAlgorithms, 0.85f, 1.0f);
+			// CHECKSTYLE:ON MagicNumber
+		}
+
+		int nrAlgorithm = 0;
+		for (final Entry<String, Map<String, Long>> runtimeEntry : resultSet) {
+			final String time = runtimeEntry.getKey();
+			final Map<String, Long> results = runtimeEntry.getValue();
+
+			double dmax = -1;
+			try {
+				dmax = Float.parseFloat(time);
+			} catch (final NumberFormatException e) {
+				// runtime is not a number (most likely it is something like summed values... summed times will not be plotted)
+				continue;
+			}
+
+			if (dmax > RUNTIME_OFFSETS[1]) {
+				// only plot runtimes until first offset (because of axis scaling issues)
+				break;
+			}
+
+			final Set<Entry<String, Long>> timeSet = results.entrySet();
+			for (final Entry<String, Long> entry : timeSet) {
+				final String algorithmName = entry.getKey();
+				final double runtime = entry.getValue().longValue() / (double) repeatCount;
+
+				ITrace2D trace = traceMap.get(algorithmName);
+				if (trace == null) {
+					trace = new Trace2DSimple(algorithmName);
+					trace.setColor(colorArr[nrAlgorithm++]);
+					trace.setStroke(stroke);
+					traceMap.put(algorithmName, trace);
+
+					chart.addTrace(trace);
+				}
+
+				trace.addPoint(dmax, runtime);
+			}
+		}
+
+		try {
+			ImageIO.write(chart.snapShot(), "png", new File(RESULTFILE_PNG_RUNTIME));
+		} catch (final IOException e) {
+			e.printStackTrace();
+		}
+	}
+
 	private static void writeMapToXML(final File file, final Set<Entry<String, Map<String, Long>>> resultSet, final int repeatCount) {
 		try (final BufferedWriter fw = new BufferedWriter(new PrintWriter(file, RESULTFILE_ENCODING))) {
 			fw.write("<?xml version=\"1.0\" encoding=\"" + RESULTFILE_ENCODING + "\"?>");
@@ -286,7 +364,9 @@ public final class AlgorithmRuntimeTest {
 				fw.newLine();
 				final Set<Entry<String, Long>> timeSet = results.entrySet();
 				for (final Entry<String, Long> entry : timeSet) {
-					fw.write("\t\t<" + entry.getKey() + ">" + entry.getValue().longValue() / repeatCount + "</" + entry.getKey() + ">");
+					final String algorithmName = entry.getKey();
+					final double runtime = entry.getValue().longValue() / (double) repeatCount;
+					fw.write("\t\t<" + algorithmName + ">" + runtime + "</" + algorithmName + ">");
 					fw.newLine();
 				}
 				fw.write("\t</time_" + time + ">");
@@ -305,6 +385,11 @@ public final class AlgorithmRuntimeTest {
 		writeMapToCSV(new File(RESULTFILE_CSV_RUNTIME), resultSet, REPEAT_COUNT);
 	}
 
+	private static void writeRuntimePNG() {
+		final Set<Entry<String, Map<String, Long>>> resultSet = runtimes.entrySet();
+		writeMapToPNG(new File(RESULTFILE_CSV_RUNTIME), resultSet, REPEAT_COUNT);
+	}
+
 	private static void writeRuntimeXML() {
 		final Set<Entry<String, Map<String, Long>>> resultSet = runtimes.entrySet();
 		writeMapToXML(new File(RESULTFILE_XML_RUNTIME), resultSet, REPEAT_COUNT);