diff --git a/src/GUI.jl b/src/GUI.jl
index a20f05b62e34e810d6d5e9e0824ce84642e1d4e9..6e0b2176f8e6dcaed6f4ac2510c5300396bcd50b 100644
--- a/src/GUI.jl
+++ b/src/GUI.jl
@@ -31,20 +31,37 @@ end
 
 function nextstep()
     global model
-    stepsimulation!(model)
-    date[] = model.date
-    progress[] = (model.date-@param(core.startdate)) / (@param(core.enddate)-model.date)
-    println("Updated model: $(model.date-Day(1))")
+    if date[] < model.date
+        # If we've "scrolled back" in time, step forward again without
+        # having to resimulate (see `previousstep()`)
+        date[] += Day(1)
+    else
+        # If we're already displaying the newest model update, we need to
+        # keep simulating
+        stepsimulation!(model)
+        date[] = model.date
+    end
+    progress[] = (date[]-@param(core.startdate)) /
+        (@param(core.enddate)-@param(core.startdate))
+    println("Updated model: $(date[]-Day(1))")
 end
 
-function runsimulation()
+function previousstep()
+    # Since we store all model output in a dataframe, we can simply
+    # "scroll back" in time and visualise the state of the model at
+    # a previous date
     global model
-    while running[] #FIXME how can I interrupt this?
-        stepsimulation!(model)
-        date[] = model.date
-        progress[] = (model.date-@param(core.startdate)) / (@param(core.enddate)-model.date)
+    date[] -= Day(1)
+    progress[] = (date[]-@param(core.startdate)) /
+        (@param(core.enddate)-@param(core.startdate))
+    println("Backtracked model: $(date[]-Day(1))")
+end
+    
+function runsimulation()
+    #XXX is this all I need to interrupt a run?
+    while running[]
+        nextstep()
         sleep(delay)
-        println("Updated model: $(model.date-Day(1))")
     end
 end
 
@@ -60,17 +77,22 @@ function togglerunning()
         runsimulation()
     end
 end
-    
-#TODO previousstep() - needs adjustments to nextstep() and runsimulation()
 
 function render_map(screen)
     global model
-    figure = visualisemap(model)
+    figure = visualisemap(model, date[])
+    display(screen, figure.scene)
+end
+
+function render_map(screen)
+    global model
+    figure = populationtrends(model)
     display(screen, figure.scene)
 end
 
 @qmlfunction newsimulation
 @qmlfunction nextstep
+@qmlfunction previousstep
 @qmlfunction togglerunning
 @qmlfunction render_map
 
@@ -89,8 +111,8 @@ The main function that creates the application.
 """
 function launch()
     # absolute path in case working dir is overridden
-    qml_file = joinpath(dirname(@__FILE__), "main.qml")
-    loadqml(qml_file,
+    qmlfile = joinpath(dirname(@__FILE__), "main.qml")
+    loadqml(qmlfile,
             vars = JuliaPropertyMap("running" => running,
                                     "date" => date,
                                     "delay" => delay,
diff --git a/src/main.qml b/src/main.qml
index d8c442af9c74f0915ad24bf480084f9524ea18ef..2e9bf3a2a75c23ebabc0f190d74c99594b348fc3 100644
--- a/src/main.qml
+++ b/src/main.qml
@@ -64,41 +64,53 @@ Distributed under the MIT license."
 
 		// visualise the model map and the locations of animals
 		/* MakieViewport { */
-		/* 	id: viewport */
+		/* 	id: mapviewport */
 		/* 	Layout.fillWidth: true */
 		/* 	Layout.fillHeight: true */
 		/* 	renderFunction: Julia.render_map() //TODO */
 		/* } */
 
-		// the calendar is no longer a single widget, but needs to be
-		// constructed manually :-(
 		ColumnLayout {
-			id: calenderWidget
-			Layout.alignment: Qt.AlignHCenter
-			Text {
-				text: "<b>"+Qt.formatDate(new Date(), "MMM yyyy")+"</b>" //FIXME
-			}
-			DayOfWeekRow {
-				locale: grid.locale
-				Layout.column: 1
-				Layout.fillWidth: true
-			}
-			MonthGrid {
-				id: grid
-				//month: Calendar.December //FIXME
-				//year: 2015 //FIXME
-				locale: Qt.locale("en_GB")
-				Layout.fillWidth: true
-				Layout.fillHeight: true
-				delegate: Text {
-					horizontalAlignment: Text.AlignHCenter
-					verticalAlignment: Text.AlignVCenter
-					opacity: model.month === grid.month ? 1 : 0
-					text: model.today ? "<b>"+model.day+"</b>" : model.day
-					font: grid.font
-					required property var model
+			anchors.fill: parent
+
+			// the calendar is no longer a single widget, but needs to be
+			// constructed manually :-(
+			ColumnLayout {
+				id: calenderWidget
+				Layout.alignment: Qt.AlignHCenter
+				Text {
+					text: "<b>"+Qt.formatDate(new Date(), "MMM yyyy")+"</b>" //FIXME
+				}
+				DayOfWeekRow {
+					locale: grid.locale
+					Layout.column: 1
+					Layout.fillWidth: true
+				}
+				MonthGrid {
+					id: grid
+					//month: Calendar.December //FIXME
+					//year: 2015 //FIXME
+					locale: Qt.locale("en_GB")
+					Layout.fillWidth: true
+					Layout.fillHeight: true
+					delegate: Text {
+						horizontalAlignment: Text.AlignHCenter
+						verticalAlignment: Text.AlignVCenter
+						opacity: model.month === grid.month ? 1 : 0
+						text: model.today ? "<b>"+model.day+"</b>" : model.day
+						font: grid.font
+						required property var model
+					}
 				}
 			}
+			
+			// plot the population sizes over time
+			/* MakieViewport { */
+			/* 	id: plotviewport */
+			/* 	Layout.fillWidth: true */
+			/* 	Layout.fillHeight: true */
+			/* 	renderFunction: Julia.render_plot() //TODO */
+			/* } */
 		}
 	}
 
@@ -117,7 +129,7 @@ Distributed under the MIT license."
 				text: "<"
 				ToolTip.text: "Back"
 				ToolTip.visible: hovered
-				//onClicked: //TODO
+				onClicked: { Julia.previousstep() }
 			}
 			Button {
 				id: stepButton