diff --git a/Manifest.toml b/Manifest.toml
index 806d3cbb0b7fcddc57e80246238347cf7915582c..cb947fc7d597428061bd6555a34cd6150c0c3161 100644
--- a/Manifest.toml
+++ b/Manifest.toml
@@ -2,7 +2,7 @@
 
 julia_version = "1.9.3"
 manifest_format = "2.0"
-project_hash = "ef26157ea1ae4a93e96b1c8d299fd2a6058b6b45"
+project_hash = "5a2d131ebba9918c9648a958a8d008d9dd7bc967"
 
 [[deps.AbstractFFTs]]
 deps = ["LinearAlgebra"]
@@ -195,10 +195,10 @@ uuid = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0"
 version = "0.8.13"
 
 [[deps.Cairo_jll]]
-deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"]
-git-tree-sha1 = "d3cc53959197e659a85f4fac191045245db8c39b"
+deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"]
+git-tree-sha1 = "4b859a208b2397a7a623a03449e4636bdb17bcf2"
 uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a"
-version = "1.18.0+0"
+version = "1.16.1+1"
 
 [[deps.Calculus]]
 deps = ["LinearAlgebra"]
@@ -1890,9 +1890,9 @@ version = "0.16.0+0"
 
 [[deps.TiffImages]]
 deps = ["ColorTypes", "DataStructures", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "Mmap", "OffsetArrays", "PkgVersion", "ProgressMeter", "UUIDs"]
-git-tree-sha1 = "7fd97bd1c5b1ff53a291cbd351d1d3d6ff4da5a5"
+git-tree-sha1 = "34cc045dd0aaa59b8bbe86c644679bc57f1d5bd0"
 uuid = "731e570b-9d59-4bfa-96dc-6df516fadf69"
-version = "0.6.7"
+version = "0.6.8"
 
 [[deps.TranscodingStreams]]
 deps = ["Random", "Test"]
diff --git a/Project.toml b/Project.toml
index e04592da3971109d42b7a241390dea8c575fa40b..78a3fcd702b19285fda855c4664414ff351e4ede 100644
--- a/Project.toml
+++ b/Project.toml
@@ -9,7 +9,6 @@ CxxWrap = "1f15a43c-97ca-5a2a-ae31-89f07a497df4"
 Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
 FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549"
 GLMakie = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a"
-GeoStatsBase = "323cb8eb-fbf6-51c0-afd0-f8fba70507b2"
 GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326"
 Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a"
 Observables = "510215fc-4207-5dde-b226-833fc4488ee2"
@@ -17,5 +16,3 @@ Persefone = "039acd1d-2a07-4b33-b082-83a1ff0fd136"
 QML = "2db162a6-7e43-52c3-8d84-290c1c42d82a"
 Qt6Base_jll = "c0090381-4147-56d7-9ebc-da0b1113ec56"
 TOML = "fa267f1f-6049-4f14-aa54-33bafae1ed76"
-TableTransforms = "0d432bfd-3ee1-4ac1-886a-39f05cc69a3e"
-jlqml_jll = "6b5019fb-a83d-5b4e-a9f7-678a36c28df7"
diff --git a/run.jl b/run.jl
index 1c6b05bbdc92ca0d882a1a9c454a65d465dba335..09d304a16fdf4cd1549b5a974538959de3526a5c 100755
--- a/run.jl
+++ b/run.jl
@@ -11,4 +11,3 @@ using PersefoneDesktop
 ENV["QSG_RENDER_LOOP"] = "basic"
 
 launch()
-
diff --git a/src/GUI.jl b/src/GUI.jl
index 6e0b2176f8e6dcaed6f4ac2510c5300396bcd50b..e0c4c35e8c3f3a7beb70aca868a9b45286031cee 100644
--- a/src/GUI.jl
+++ b/src/GUI.jl
@@ -8,7 +8,8 @@
 ## - https://github.com/barche/QmlJuliaExamples
 ## - https://doc.qt.io/qt-6/qtquick-index.html
 
-global model::Union{AgentBasedModel,Missing} = missing
+global model = nothing
+global landcovermap = nothing
 #loadmodelobject(joinpath(dirname(@__FILE__), "../sampleinit.dat")) #initialise()
 const running = Observable(false)
 const date = Observable(today())
@@ -18,10 +19,11 @@ const runbuttontext = Observable(">>")
 const runbuttontip = Observable("Run")
 
 function newsimulation()
-    global model
+    global model, landcovermap
     running[] = false
     progress[] = 0.0
     model = initialise() #TODO configure
+    landcovermap = load(@param(world.landcovermap))
     date[] = model.date
     println("Model initialised.")
 end
@@ -79,12 +81,12 @@ function togglerunning()
 end
 
 function render_map(screen)
-    global model
-    figure = visualisemap(model, date[])
+    global model, landcovermap
+    figure = visualisemap(model, date[], landcovermap)
     display(screen, figure.scene)
 end
 
-function render_map(screen)
+function render_plot(screen)
     global model
     figure = populationtrends(model)
     display(screen, figure.scene)
@@ -95,6 +97,7 @@ end
 @qmlfunction previousstep
 @qmlfunction togglerunning
 @qmlfunction render_map
+@qmlfunction render_plot
 
 on(delay) do d
     println("Delay is now $(round(d, digits=1)) seconds.")
@@ -104,12 +107,25 @@ on(running) do r
     r ? println("Simulation started.") : println("Simulation stopped.")
 end
 
+function splashscreen()
+    qmlfile = joinpath(dirname(@__FILE__), "splash.qml")
+    quick_view = init_qquickview()
+    set_source(quick_view, QUrlFromLocalFile(qmlfile))
+    QML.show(quick_view)
+    #XXX exec_async() is currently still broken, but should be fixed soon
+    # (https://github.com/JuliaGraphics/QML.jl/issues/174)
+    exec_async()
+end
+
 """
     launch()
 
 The main function that creates the application.
 """
 function launch()
+    global model
+    splashscreen()
+    newsimulation()
     # absolute path in case working dir is overridden
     qmlfile = joinpath(dirname(@__FILE__), "main.qml")
     loadqml(qmlfile,
diff --git a/src/PersefoneDesktop.jl b/src/PersefoneDesktop.jl
index 1596175dbee52eb1d82faa500624d6d943dff0f5..3dc670bef8394bf92e54527182feb8990ae54d2c 100644
--- a/src/PersefoneDesktop.jl
+++ b/src/PersefoneDesktop.jl
@@ -18,6 +18,7 @@ using
     Dates,
     Makie,
     Agents,
+    FileIO,
     CxxWrap,
     GLMakie,
     Persefone,
diff --git a/src/main.qml b/src/main.qml
index 2e9bf3a2a75c23ebabc0f190d74c99594b348fc3..fbaf1aff9c27eddb73ebb60437a23033bde46d7f 100644
--- a/src/main.qml
+++ b/src/main.qml
@@ -71,7 +71,6 @@ Distributed under the MIT license."
 		/* } */
 
 		ColumnLayout {
-			anchors.fill: parent
 
 			// the calendar is no longer a single widget, but needs to be
 			// constructed manually :-(
@@ -118,6 +117,8 @@ Distributed under the MIT license."
 	// bar and a speed slider
 	footer: ToolBar {
 		RowLayout {
+			//TODO change button texts to icons
+			// (https://doc.qt.io/qt-6/qtquickcontrols-icons.html)
 			id: controlBar
 			anchors.fill: parent
 			Layout.alignment: Qt.AlignVCenter
diff --git a/src/persefonejl_logo_v3_splash.png b/src/persefonejl_logo_v3_splash.png
new file mode 100644
index 0000000000000000000000000000000000000000..c2ec0ece3a50394ac3dafa2f5baa0250846a7c61
Binary files /dev/null and b/src/persefonejl_logo_v3_splash.png differ
diff --git a/src/splash.qml b/src/splash.qml
new file mode 100644
index 0000000000000000000000000000000000000000..b731adc71d4b26c1a9377f511d62248328513d19
--- /dev/null
+++ b/src/splash.qml
@@ -0,0 +1,24 @@
+/// PersefoneDesktop - a GUI to the Persefone model of agriculture and ecosystems
+///
+/// This file creates the splash screen. Load it using a QQuickView.
+///
+
+import QtQuick
+import QtQuick.Controls
+import org.julialang
+
+Rectangle {
+	width: 1200
+	height: 500
+	
+    Image {
+        source: "persefonejl_logo_v3_splash.png"
+		fillMode: Image.PreserveAspectFit
+    }
+    Timer {
+		// Show the splash screen while the model object is initialised
+		//XXX is 15s a good time here?
+        interval: 15000; running: true; repeat: false
+        onTriggered: parent.Window.window.close()
+    }
+}