{"id":2132,"date":"2019-09-06T08:33:54","date_gmt":"2019-09-06T07:33:54","guid":{"rendered":"http:\/\/www.meiotic.co.uk\/my\/?p=2132"},"modified":"2019-09-07T00:40:42","modified_gmt":"2019-09-06T23:40:42","slug":"animating-time-qgis-timemanager-ffmpeg-graticules","status":"publish","type":"post","link":"http:\/\/www.meiotic.co.uk\/my\/research\/animating-time-qgis-ffmpeg\/","title":{"rendered":"Animating Time: QGIS &#038; FFmpeg"},"content":{"rendered":"<p><script>document.getElementById('menu-item-102').className += \" current-menu-item current_page_item\";<\/script><script src=\"\/my\/wp-content\/uploads\/prism.js\"><\/script><link rel=\"stylesheet\" type=\"text\/css\" href=\"\/my\/wp-content\/uploads\/prism.css\">\n<p>I was recently asked if I could animate this summer&#8217;s records from the <a href=\"https:\/\/www.ceh.ac.uk\/algal-blooms\/bloomin-algae\" target=\"_blank\">Bloomin&#8217; Algae App<\/a>, to help show the spatial patterns as well as the impact of a <a href=\"https:\/\/www.theguardian.com\/uk-news\/2019\/aug\/16\/blue-green-algae-poses-blooming-danger-to-paddling-pets\" target=\"_blank\">recent<\/a> media interest in the <a href=\"https:\/\/www.bbc.co.uk\/news\/uk-49344232\" target=\"_blank\">subject<\/a> (and a feature on BBC Breakfast!). I&#8217;ve looked at doing something <a href=\"..\/animating-journeys\/\" target=\"_blank\">similar before<\/a>, but this time I wanted to create a higher-end output.<\/p>\n<h4>Animating with QGIS TimeManager<\/h4>\n<p>First up, we can import our time series data (in this case, point data with an associated date field and verification attribute) to QGIS. Then it&#8217;s just a case of installing the <a href=\"https:\/\/plugins.qgis.org\/plugins\/timemanager\/\" target=\"_blank\">TimeManger plugin<\/a>, opening it up and adding our data layer.<\/p>\n<p>You can tweek the output in the settings menu \/ time display options, then hit the play button to see how it looks. I found my background layers might flash on and off in this preview mode, but it didn&#8217;t affect the output once the video was exported.<\/p>\n<div id=\"attachment_2145\" style=\"width: 770px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-2145\" decoding=\"async\" loading=\"lazy\" src=\"http:\/\/www.meiotic.co.uk\/my\/wp-content\/uploads\/2019\/09\/time_manager.jpg\" alt=\"QGIS TimeManager settings\" width=\"760\" height=\"475\" class=\"size-full wp-image-2145\" \/><p id=\"caption-attachment-2145\" class=\"wp-caption-text\">The settings I used in TimeManager (including the time display options)<\/p><\/div>\n<h4>EPSG 102038 &#038; Graticules<\/h4>\n<p>After seeing this great <a href=\"http:\/\/www.statsmapsnpix.com\/2019\/09\/globe-projections-and-insets-in-qgis.html\" target=\"_blank\">blog post<\/a> from Alasdair Rae, I thought this &#8216;World_From_Space&#8217; projection would work nicely for this project. With his suggested addition of <a href=\"https:\/\/www.naturalearthdata.com\/downloads\/50m-physical-vectors\/50m-graticules\/\" target=\"_blank\">graticules<\/a>, we can add a bit more information to the background map too. Oh, and let&#8217;s add some <a href=\"https:\/\/ec.europa.eu\/eurostat\/cache\/GISCO\/distribution\/v2\/countries\/download\/ref-countries-2016-03m.shp.zip\" target=\"_blank\">country polygons<\/a> on there too!<\/p>\n<h4>FFmpeg &#8211; MP4, Legends &#038; GIF Output<\/h4>\n<p>In TimeManager, hit the &#8216;export video&#8217; button and select &#8216;frames only&#8217;. This will export a series of numbered PNGs, which we can stitch together using <a href=\"https:\/\/ffmpeg.org\/\" target=\"_blank\">FFmpeg<\/a> &#8211; this gives us maximum flexibility for our output. If you&#8217;ve not used FFmpeg before, it&#8217;s a hugely-flexible command line video converter. From here on in, I&#8217;ll presume you&#8217;ve added it to your <a href=\"http:\/\/blog.gregzaal.com\/how-to-install-ffmpeg-on-windows\/\" target=\"_blank\">Windows path<\/a>.<\/p>\n<p>One issue with using TimeManger is you can&#8217;t easily <a href=\"https:\/\/gis.stackexchange.com\/questions\/156861\/qgis-legend-without-print-composer\" target=\"_blank\">add a legend<\/a> as the output is created from the QGIS Map View. Instead, you can create a legend image (ideally a PNG with a transparent background) then add it to your output with FFmpeg.<\/p>\n<h6>MP4 video<\/h6>\n<p>Let&#8217;s create a basic video output first. The following code is modified from <a href=\"http:\/\/hamelot.io\/visualization\/using-ffmpeg-to-convert-a-set-of-images-into-a-video\/\" target=\"_blank\">this guide<\/a> and this <a href=\"https:\/\/stackoverflow.com\/questions\/20847674\/ffmpeg-libx264-height-not-divisible-by-2\" target=\"_blank\">Stack Overflow answer<\/a>. You can read those articles for more info on the options, but this should be roughly what you need to convert output from TimeManager:<\/p>\n<p><code class=\"language-clike\">$ ffmpeg -r 10 -s 1280x720 -i frame%03d.png -vcodec libx264 -crf 1 -vf \"pad=ceil(iw\/2)*2:ceil(ih\/2)*2\" -pix_fmt yuv420p blooms_2019.mp4<\/code><\/p>\n<h6>Add a legend<\/h6>\n<p>Now we&#8217;ve created an MP4, we can add out legend by adapting this guide on <a href=\"https:\/\/gist.github.com\/bennylope\/d5d6029fb63648582fed2367ae23cfd6\" target=\"_blank\">adding a watermark<\/a>. There&#8217;s not much to this, just the overlay options which decides the legend positioning:<\/p>\n<p><code class=\"language-clike\">$ ffmpeg -i blooms_2019.mp4 -i legend.png -filter_complex \"overlay=50:90\" blooms_2019_legend.mp4<\/code><\/p>\n<h6>Feedback from FFmpeg<\/h6>\n<p>Before we continue, I got a response after posting this article from the <a href=\"https:\/\/twitter.com\/FFmpeg\" target=\"_blank\">@FFmpeg Twitter account<\/a> suggesting the following combined code:<\/p>\n<blockquote class=\"twitter-tweet\">\n<p lang=\"en\" dir=\"ltr\">You can make the MP4 and overlay in one command:<\/p>\n<p>ffmpeg -framerate 10 -i %03d.png -i legend.png -filter_complex &quot;[0]pad=ceil(iw\/2)*2:ceil(ih\/2)*2[bg];[bg][1]overlay=50:90,format=yuv420p&quot; -c:v libx264 -movflags +faststart out.mp4<\/p>\n<p>&mdash; FFmpeg (@FFmpeg) <a href=\"https:\/\/twitter.com\/FFmpeg\/status\/1170062172753281024?ref_src=twsrc%5Etfw\">September 6, 2019<\/a><\/p><\/blockquote>\n<p> <script async src=\"https:\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"><\/script><\/p>\n<h6>Create a gif<\/h6>\n<p>Excellent. That&#8217;s the video output finished, but it would be nice to create an animated gif for ease of display on the web. This is one thing FFmpeg is less good at. Or more accurately, it needs more help than with most other output formats. Essentially, we need to give it some info on the colour palette of our video before it creates the gif, but this can be achieved in one line with a slight adjustment to this <a href=\"https:\/\/engineering.giphy.com\/how-to-make-gifs-with-ffmpeg\/\" target=\"_blank\">GIPHY Engineering<\/a> guide:<\/p>\n<p><code class=\"language-clike\">$ ffmpeg -i blooms_2019_legend.mp4 -filter_complex \"[0:v] scale=765:-1,split [a][b];[a] palettegen [p];[b][p] paletteuse\" blooms_2019_legend.gif<\/code><\/p>\n<div id=\"attachment_2146\" style=\"width: 775px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/www.meiotic.co.uk\/my\/wp-content\/uploads\/2019\/09\/blooms_2019_legend.gif\" rel=\"attachment wp-att-2146\" data-rel=\"lightbox-gallery-7yXZ1uv7\" data-rl_title=\"Bloomin&#039; Algae - 2019 records\" data-rl_caption=\"Bloomin&#039; Algae - 2019 records\" title=\"Bloomin&#039; Algae - 2019 records\"><img aria-describedby=\"caption-attachment-2146\" decoding=\"async\" loading=\"lazy\" src=\"http:\/\/www.meiotic.co.uk\/my\/wp-content\/uploads\/2019\/09\/blooms_2019_legend.gif\" alt=\"Bloomin&#039; Algae - 2019 records\" width=\"765\" height=\"539\" class=\"size-medium wp-image-2146\" \/><\/a><p id=\"caption-attachment-2146\" class=\"wp-caption-text\">Et voila! Our final output in gif form.<\/p><\/div>\n","protected":false},"excerpt":{"rendered":"<p>I was recently asked if I could animate this summer&#8217;s records from the Bloomin&#8217; Algae App, to help show the spatial patterns as well as the impact of a recent media interest in the subject<\/p>\n","protected":false},"author":1,"featured_media":2151,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[18],"tags":[118,119,9,15,58,117],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v19.7.1 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Animating Time: QGIS &amp; FFmpeg | *meiotic*<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Animating Time: QGIS &amp; FFmpeg | *meiotic*\" \/>\n<meta property=\"og:description\" content=\"I was recently asked if I could animate this summer&#8217;s records from the Bloomin&#8217; Algae App, to help show the spatial patterns as well as the impact of a recent media interest in the subject\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.meiotic.co.uk\/my\/research\/animating-time-qgis-ffmpeg\/\" \/>\n<meta property=\"og:site_name\" content=\"*meiotic*\" \/>\n<meta property=\"article:published_time\" content=\"2019-09-06T07:33:54+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-09-06T23:40:42+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.meiotic.co.uk\/my\/wp-content\/uploads\/2019\/09\/frame072.png\" \/>\n\t<meta property=\"og:image:width\" content=\"973\" \/>\n\t<meta property=\"og:image:height\" content=\"686\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"meiotic\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@ScienceAndMaps\" \/>\n<meta name=\"twitter:site\" content=\"@ScienceAndMaps\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"meiotic\" \/>\n\t<meta name=\"twitter:label2\" content=\"Estimated reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.meiotic.co.uk\/my\/research\/animating-time-qgis-ffmpeg\/\",\"url\":\"https:\/\/www.meiotic.co.uk\/my\/research\/animating-time-qgis-ffmpeg\/\",\"name\":\"Animating Time: QGIS & FFmpeg | *meiotic*\",\"isPartOf\":{\"@id\":\"http:\/\/www.meiotic.co.uk\/my\/#website\"},\"datePublished\":\"2019-09-06T07:33:54+00:00\",\"dateModified\":\"2019-09-06T23:40:42+00:00\",\"author\":{\"@id\":\"http:\/\/www.meiotic.co.uk\/my\/#\/schema\/person\/1995e1cecd67d2ff1e6a638aa331d032\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.meiotic.co.uk\/my\/research\/animating-time-qgis-ffmpeg\/#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.meiotic.co.uk\/my\/research\/animating-time-qgis-ffmpeg\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.meiotic.co.uk\/my\/research\/animating-time-qgis-ffmpeg\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"http:\/\/www.meiotic.co.uk\/my\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Animating Time: QGIS &#038; FFmpeg\"}]},{\"@type\":\"WebSite\",\"@id\":\"http:\/\/www.meiotic.co.uk\/my\/#website\",\"url\":\"http:\/\/www.meiotic.co.uk\/my\/\",\"name\":\"*meiotic*\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"http:\/\/www.meiotic.co.uk\/my\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-GB\"},{\"@type\":\"Person\",\"@id\":\"http:\/\/www.meiotic.co.uk\/my\/#\/schema\/person\/1995e1cecd67d2ff1e6a638aa331d032\",\"name\":\"meiotic\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"http:\/\/www.meiotic.co.uk\/my\/#\/schema\/person\/image\/\",\"url\":\"http:\/\/0.gravatar.com\/avatar\/cacd48b532259fb621d7acf4cc462290?s=96&d=retro&r=r\",\"contentUrl\":\"http:\/\/0.gravatar.com\/avatar\/cacd48b532259fb621d7acf4cc462290?s=96&d=retro&r=r\",\"caption\":\"meiotic\"},\"sameAs\":[\"http:\/\/meiotic.co.uk\",\"https:\/\/twitter.com\/ScienceAndMaps\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Animating Time: QGIS & FFmpeg | *meiotic*","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"og_locale":"en_GB","og_type":"article","og_title":"Animating Time: QGIS & FFmpeg | *meiotic*","og_description":"I was recently asked if I could animate this summer&#8217;s records from the Bloomin&#8217; Algae App, to help show the spatial patterns as well as the impact of a recent media interest in the subject","og_url":"https:\/\/www.meiotic.co.uk\/my\/research\/animating-time-qgis-ffmpeg\/","og_site_name":"*meiotic*","article_published_time":"2019-09-06T07:33:54+00:00","article_modified_time":"2019-09-06T23:40:42+00:00","og_image":[{"width":973,"height":686,"url":"https:\/\/www.meiotic.co.uk\/my\/wp-content\/uploads\/2019\/09\/frame072.png","type":"image\/png"}],"author":"meiotic","twitter_card":"summary_large_image","twitter_creator":"@ScienceAndMaps","twitter_site":"@ScienceAndMaps","twitter_misc":{"Written by":"meiotic","Estimated reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.meiotic.co.uk\/my\/research\/animating-time-qgis-ffmpeg\/","url":"https:\/\/www.meiotic.co.uk\/my\/research\/animating-time-qgis-ffmpeg\/","name":"Animating Time: QGIS & FFmpeg | *meiotic*","isPartOf":{"@id":"http:\/\/www.meiotic.co.uk\/my\/#website"},"datePublished":"2019-09-06T07:33:54+00:00","dateModified":"2019-09-06T23:40:42+00:00","author":{"@id":"http:\/\/www.meiotic.co.uk\/my\/#\/schema\/person\/1995e1cecd67d2ff1e6a638aa331d032"},"breadcrumb":{"@id":"https:\/\/www.meiotic.co.uk\/my\/research\/animating-time-qgis-ffmpeg\/#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.meiotic.co.uk\/my\/research\/animating-time-qgis-ffmpeg\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.meiotic.co.uk\/my\/research\/animating-time-qgis-ffmpeg\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"http:\/\/www.meiotic.co.uk\/my\/"},{"@type":"ListItem","position":2,"name":"Animating Time: QGIS &#038; FFmpeg"}]},{"@type":"WebSite","@id":"http:\/\/www.meiotic.co.uk\/my\/#website","url":"http:\/\/www.meiotic.co.uk\/my\/","name":"*meiotic*","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"http:\/\/www.meiotic.co.uk\/my\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-GB"},{"@type":"Person","@id":"http:\/\/www.meiotic.co.uk\/my\/#\/schema\/person\/1995e1cecd67d2ff1e6a638aa331d032","name":"meiotic","image":{"@type":"ImageObject","inLanguage":"en-GB","@id":"http:\/\/www.meiotic.co.uk\/my\/#\/schema\/person\/image\/","url":"http:\/\/0.gravatar.com\/avatar\/cacd48b532259fb621d7acf4cc462290?s=96&d=retro&r=r","contentUrl":"http:\/\/0.gravatar.com\/avatar\/cacd48b532259fb621d7acf4cc462290?s=96&d=retro&r=r","caption":"meiotic"},"sameAs":["http:\/\/meiotic.co.uk","https:\/\/twitter.com\/ScienceAndMaps"]}]}},"_links":{"self":[{"href":"http:\/\/www.meiotic.co.uk\/my\/wp-json\/wp\/v2\/posts\/2132"}],"collection":[{"href":"http:\/\/www.meiotic.co.uk\/my\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.meiotic.co.uk\/my\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.meiotic.co.uk\/my\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.meiotic.co.uk\/my\/wp-json\/wp\/v2\/comments?post=2132"}],"version-history":[{"count":24,"href":"http:\/\/www.meiotic.co.uk\/my\/wp-json\/wp\/v2\/posts\/2132\/revisions"}],"predecessor-version":[{"id":2159,"href":"http:\/\/www.meiotic.co.uk\/my\/wp-json\/wp\/v2\/posts\/2132\/revisions\/2159"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/www.meiotic.co.uk\/my\/wp-json\/wp\/v2\/media\/2151"}],"wp:attachment":[{"href":"http:\/\/www.meiotic.co.uk\/my\/wp-json\/wp\/v2\/media?parent=2132"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.meiotic.co.uk\/my\/wp-json\/wp\/v2\/categories?post=2132"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.meiotic.co.uk\/my\/wp-json\/wp\/v2\/tags?post=2132"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}