<p><div><div><div><div data-width="100" data-show-faces="false" data-send="true" data-layout="button_count" data-height="21" data-href="https://www.r-bloggers.com/thematic-interactive-map/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="http://jkunst.com/r/thematic-interactive-map/"> Jkunst - R category</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>Last week all the <em>rstatsosphere</em> see the beautiful<br>
<a target="_blank" rel="nofollow" href="http://jkunst.com/r/thematic-interactive-map/timogrossenbacher.ch">Timo Grossenbacher</a><br>
<a target="_blank" rel="nofollow" href="http://jkunst.com/r/thematic-interactive-map/timogrossenbacher.ch/2016/12/beautiful-thematic-maps-with-ggplot2-only/">work</a>.</p>
<p>The last month, yep, the past year I’ve working on create maps<br>
easily with <a target="_blank" rel="nofollow" href="http://jkunst.com/highcharter/">highcharter</a>.<br>
When I saw this chart I took as challege to replicate this nice<br>
map in using highcharter:</p>
<p><img title="Thematic intercative map" alt="" src="https://i0.wp.com/jkunst.com/images/featured-image/thematic-interactive-map.gif?w=456" data-recalc-dims="1"></p>
<p>So…</p>
<p><img alt="giphy gif" src="https://i0.wp.com/media.giphy.com/media/eNweOH3UEi33a/giphy.gif?w=456&ssl=1" data-recalc-dims="1"> <a target="_blank" rel="nofollow" href="http://wifflegif.com/">source</a></p>
<blockquote>
<p>Challenge accepted. it’s gonna be legen…<br>
– <cite>Me.</cite></p>
</blockquote>
<div>
<pre><code><span># packages ----------------------------------------------------------------
</span><span>library</span><span>(</span><span>dplyr</span><span>)</span><span>
</span><span>library</span><span>(</span><span>rmapshaper</span><span>)</span><span>
</span><span>library</span><span>(</span><span>maptools</span><span>)</span><span>
</span><span>library</span><span>(</span><span>highcharter</span><span>)</span><span>
</span><span>library</span><span>(</span><span>geojsonio</span><span>)</span><span>
</span><span>library</span><span>(</span><span>readr</span><span>)</span><span>
</span><span>library</span><span>(</span><span>viridis</span><span>)</span><span>
</span><span>library</span><span>(</span><span>purrr</span><span>)</span><span>
</span></code></pre>
</div>
<h2>Data</h2>
<p>The data used fhor this chart is the same using by Timo. But the workflow<br>
was slightly modified:</p>
<ol>
<li>Read the shapefile with <code>maptools::readShapeSpatial</code>.</li>
<li>Simplify the shapefile (optional step) using <code>rmapshaper::ms_simplify</code>.</li>
<li>Then transform the map data to geojson using <code>geojsonio::geojson_list</code>.</li>
</ol>
<div>
<pre><code><span># data --------------------------------------------------------------------
</span><span>folder</span><span> </span><span>&lt;-</span><span> </span><span>&quot;data/thematicmap/&quot;</span><span>
</span><span>map</span><span> </span><span>&lt;-</span><span> </span><span>readShapeSpatial</span><span>(</span><span>file.path</span><span>(</span><span>folder</span><span>,</span><span> </span><span>&quot;gde-1-1-15.shp&quot;</span><span>))</span><span>
</span><span>map</span><span> </span><span>&lt;-</span><span> </span><span>ms_simplify</span><span>(</span><span>map</span><span>,</span><span> </span><span>keep</span><span> </span><span>=</span><span> </span><span>1</span><span>)</span><span> </span><span># because ms_simplify fix the Ã¼'s
</span><span>map</span><span> </span><span>&lt;-</span><span> </span><span>geojson_list</span><span>(</span><span>map</span><span>)</span><span>
</span><span>str</span><span>(</span><span>map</span><span>,</span><span> </span><span>max.level</span><span> </span><span>=</span><span> </span><span>1</span><span>)</span><span>
</span></code></pre>
</div>
<div>
<pre><code>## List of 2
##  $ type    : chr &quot;FeatureCollection&quot;
##  $ features:List of 2324
##   .. [list output truncated]
##  - attr(*, &quot;class&quot;)= chr &quot;geo_list&quot;
##  - attr(*, &quot;from&quot;)= chr &quot;SpatialPolygonsDataFrame&quot;
</code></pre>
</div>
<div>
<pre><code><span>str</span><span>(</span><span>map</span><span>$</span><span>features</span><span>[[</span><span>7</span><span>]],</span><span> </span><span>max.level</span><span> </span><span>=</span><span> </span><span>5</span><span>)</span><span>
</span></code></pre>
</div>
<div>
<pre><code>## List of 4
##  $ type      : chr &quot;Feature&quot;
##  $ id        : int 6
##  $ properties:List of 3
##   ..$ Secondary_  : chr &quot;Knonau&quot;
##   ..$ BFS_ID      : int 7
##   ..$ rmapshaperid: int 6
##  $ geometry  :List of 2
##   ..$ type       : chr &quot;MultiPolygon&quot;
##   ..$ coordinates:List of 1
##   .. ..$ :List of 1
##   .. .. ..$ :List of 7
##   .. .. .. ..$ : num [1:2] 676327 230767
##   .. .. .. ..$ : num [1:2] 675655 233007
##   .. .. .. ..$ : num [1:2] 676458 233252
##   .. .. .. ..$ : num [1:2] 679285 230257
##   .. .. .. ..$ : num [1:2] 679590 229402
##   .. .. .. ..$ : num [1:2] 678887 229152
##   .. .. .. ..$ : num [1:2] 676327 230767
</code></pre>
</div>
<div>
<pre><code><span># this was to put the name on the tooltip
</span><span>map</span><span>$</span><span>features</span><span> </span><span>&lt;-</span><span> </span><span>map</span><span>(</span><span>map</span><span>$</span><span>features</span><span>,</span><span> </span><span>function</span><span>(</span><span>x</span><span>)</span><span> </span><span>{</span><span>
</span><span>x</span><span>$</span><span>properties</span><span>$</span><span>name</span><span> </span><span>&lt;-</span><span> </span><span>x</span><span>$</span><span>properties</span><span>[[</span><span>&quot;Secondary_&quot;</span><span>]]</span><span> </span><span>x</span><span>
</span><span>})</span><span>
</span><span>data</span><span> </span><span>&lt;-</span><span> </span><span>read_csv</span><span>(</span><span>file.path</span><span>(</span><span>folder</span><span>,</span><span> </span><span>&quot;avg_age_15.csv&quot;</span><span>))</span><span>
</span><span>data</span><span> </span><span>&lt;-</span><span> </span><span>select</span><span>(</span><span>data</span><span>,</span><span> </span><span>-</span><span>X</span><span>1</span><span>)</span><span>
</span><span>data</span><span> </span><span>&lt;-</span><span> </span><span>rename</span><span>(</span><span>data</span><span>,</span><span> </span><span>value</span><span> </span><span>=</span><span> </span><span>avg_age_15</span><span>)</span><span>
</span><span># colors
</span><span>no_classes</span><span> </span><span>&lt;-</span><span> </span><span>6</span><span>
</span><span>colors</span><span> </span><span>&lt;-</span><span> </span><span>magma</span><span>(</span><span>no_classes</span><span> </span><span>+</span><span> </span><span>2</span><span>)</span><span> </span><span>%>%</span><span> </span><span>rev</span><span>()</span><span> </span><span>%>%</span><span> </span><span>head</span><span>(</span><span>-1</span><span>)</span><span> </span><span>%>%</span><span> </span><span>tail</span><span>(</span><span>-1</span><span>)</span><span> </span><span>%>%</span><span> </span><span>gsub</span><span>(</span><span>&quot;FF$&quot;</span><span>,</span><span> </span><span>&quot;&quot;</span><span>,</span><span> </span><span>.</span><span>)</span><span>
</span><span># brks &lt;- quantile(data$value, probs = seq(0, 1, length.out = no_classes + 1))
</span><span>brks</span><span> </span><span>&lt;-</span><span> </span><span>c</span><span>(</span><span>min</span><span>(</span><span>data</span><span>$</span><span>value</span><span>),</span><span> </span><span>c</span><span>(</span><span>40</span><span>,</span><span>42</span><span>,</span><span>44</span><span>,</span><span>46</span><span>,</span><span>48</span><span>),</span><span> </span><span>max</span><span>(</span><span>data</span><span>$</span><span>value</span><span>))</span><span>
</span><span>brks</span><span> </span><span>&lt;-</span><span> </span><span>ifelse</span><span>(</span><span>1</span><span>:</span><span>(</span><span>no_classes</span><span> </span><span>+</span><span> </span><span>1</span><span>)</span><span> </span><span>&lt;</span><span> </span><span>no_classes</span><span>,</span><span> </span><span>floor</span><span>(</span><span>brks</span><span>),</span><span> </span><span>ceiling</span><span>(</span><span>brks</span><span>))</span><span>
</span></code></pre>
</div>
<h2>Map</h2>
<p>Create the raw map is straightforward. The <em>main</em> challege was replicate the<br>
relief feature of the orignal map. This took <em>some days</em> to figure<br>
how add the backgound image. I almost loose the hope but you know, new year,<br>
so I tried a little more and it was possible :):</p>
<ol>
<li>First I searched a way to transform the tif image to geojson. I wrote<br>
a mail <a target="_blank" rel="nofollow" href="https://twitter.com/frzambra">@frzambra</a> a geoRexpert :D. and<br>
he kindly said me that I was wrong. And he was right. NEXT!</li>
<li>I tried with use <code>divBackgroundImage</code> but with this the image use all the<br>
container… so… NEXT.</li>
<li>Finally surfing in the web I met <code>plotBackgroundImage</code> argument in highcharts<br>
which is uesd to put and image only in plot container (inside de axis) and<br>
it works nicely. It was necessary hack the image using the <code>preserveAspectRatio</code><br>
(html world) to center the image but nothing magical.</li>
</ol>
<div>
<pre><code><span>urlimage</span><span> </span><span>&lt;-</span><span> </span><span>&quot;https://raw.githubusercontent.com/jbkunst/r-posts/master/061-beautiful-thematic-maps-with-ggplot2-highcharter-version/02-relief-georef-clipped-resampled.jpg&quot;</span><span>
</span><span>highchart</span><span>(</span><span>type</span><span> </span><span>=</span><span> </span><span>&quot;map&quot;</span><span>)</span><span> </span><span>%>%</span><span> </span><span># data part
</span><span> </span><span>hc_add_series</span><span>(</span><span>mapData</span><span> </span><span>=</span><span> </span><span>map</span><span>,</span><span> </span><span>data</span><span> </span><span>=</span><span> </span><span>data</span><span>,</span><span> </span><span>type</span><span> </span><span>=</span><span> </span><span>&quot;map&quot;</span><span>,</span><span>
</span><span>joinBy</span><span> </span><span>=</span><span> </span><span>c</span><span>(</span><span>&quot;BFS_ID&quot;</span><span>,</span><span> </span><span>&quot;bfs_id&quot;</span><span>),</span><span> </span><span>value</span><span> </span><span>=</span><span> </span><span>&quot;value&quot;</span><span>,</span><span>
</span><span>borderWidth</span><span> </span><span>=</span><span> </span><span>0</span><span>)</span><span> </span><span>%>%</span><span> </span><span>hc_colorAxis</span><span>(</span><span>dataClasses</span><span> </span><span>=</span><span> </span><span>color_classes</span><span>(</span><span>brks</span><span>,</span><span> </span><span>colors</span><span>))</span><span> </span><span>%>%</span><span> </span><span># functionality
</span><span> </span><span>hc_tooltip</span><span>(</span><span>headerFormat</span><span> </span><span>=</span><span> </span><span>&quot;&quot;</span><span>,</span><span>
</span><span>pointFormat</span><span> </span><span>=</span><span> </span><span>&quot;{point.name}: {point.value}&quot;</span><span>,</span><span>
</span><span>valueDecimals</span><span> </span><span>=</span><span> </span><span>2</span><span>)</span><span> </span><span>%>%</span><span> </span><span>hc_legend</span><span>(</span><span>align</span><span> </span><span>=</span><span> </span><span>&quot;right&quot;</span><span>,</span><span> </span><span>verticalAlign</span><span> </span><span>=</span><span> </span><span>&quot;bottom&quot;</span><span>,</span><span> </span><span>layout</span><span> </span><span>=</span><span> </span><span>&quot;vertical&quot;</span><span>,</span><span>
</span><span>floating</span><span> </span><span>=</span><span> </span><span>TRUE</span><span>)</span><span> </span><span>%>%</span><span>
</span><span>hc_mapNavigation</span><span>(</span><span>enabled</span><span> </span><span>=</span><span> </span><span>FALSE</span><span>)</span><span> </span><span>%>%</span><span> </span><span># if TRUE to zoom the relief image dont zoom.
</span><span> </span><span># info
</span><span> </span><span>hc_title</span><span>(</span><span>text</span><span> </span><span>=</span><span> </span><span>&quot;Switzerland's regional demographics&quot;</span><span>)</span><span> </span><span>%>%</span><span> </span><span>hc_subtitle</span><span>(</span><span>text</span><span> </span><span>=</span><span> </span><span>&quot;Average age in Swiss municipalities, 2015&quot;</span><span>)</span><span> </span><span>%>%</span><span> </span><span>hc_credits</span><span>(</span><span>enabled</span><span> </span><span>=</span><span> </span><span>TRUE</span><span>,</span><span>
</span><span>text</span><span> </span><span>=</span><span> </span><span>&quot;Map CC-BY-SA; Author: Joshua Kunst (@jbkunst) based mostly on Timo Grossenbacher (@grssnbchr) work, Geometries: ThemaKart, BFS; Data: BFS, 2016; Relief: swisstopo, 2016&quot;</span><span>)</span><span> </span><span>%>%</span><span> </span><span># style
</span><span> </span><span>hc_chart</span><span>(</span><span>plotBackgroundImage</span><span> </span><span>=</span><span> </span><span>urlimage</span><span>,</span><span>
</span><span>backgroundColor</span><span> </span><span>=</span><span> </span><span>&quot;transparent&quot;</span><span>,</span><span>
</span><span>events</span><span> </span><span>=</span><span> </span><span>list</span><span>(</span><span>
</span><span>load</span><span> </span><span>=</span><span> </span><span>JS</span><span>(</span><span>&quot;function(){ $(\&quot;image\&quot;)[0].setAttribute('preserveAspectRatio', 'xMidYMid') }&quot;</span><span>)</span><span>
</span><span>))</span><span>
</span></code></pre>
</div>
<p><iframe src="http://jkunst.com/htmlwidgets/thematic-interactive-map/highchart_ufzvsmh.html"></iframe></p>
<p><a target="_blank" rel="nofollow" href="http://jkunst.com/htmlwidgets/thematic-interactive-map/highchart_ufzvsmh.html">open</a></p>
<blockquote>
<p>DARY! Legendary.<br>
– <cite>Me.</cite></p>
</blockquote>
<p>Same as the original/ggplot2 version. I’m very happy with the result.<br>
But anyway, there are some details:</p>
<ol>
<li>The image/relief need to be accesible in web. I don’t know how<br>
to add images as dependencies yet. I tried econding the image but didn’t work.</li>
<li>I could not do the legend same as the original. So I used <code>dataClasses</code><br>
instead of <code>stops</code> in <code>hc_colorAxis</code>.</li>
</ol>
<p>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="http://jkunst.com/r/thematic-interactive-map/"> Jkunst - R category</a></strong>.</div>
<hr>
<a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" rel="nofollow" href="https://www.r-project.org/">R</a> news and <a title="R tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/tutorial">tutorials</a> on topics such as: <a title="Data science" rel="nofollow" href="https://www.r-bloggers.com/search/data%20science">Data science</a>, <a title="Big Data" rel="nofollow" href="https://www.r-bloggers.com/search/Big%20Data">Big Data, <a title="R jobs" rel="nofollow" href="https://www.r-users.com/">R jobs</a>, visualization (<a title="ggplot and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/ggplot2">ggplot2</a>, <a title="Boxplots using lattice and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/boxplot">Boxplots</a>, <a title="Maps and gis" rel="nofollow" href="https://www.r-bloggers.com/search/map">maps</a>, <a title="Animation in R" rel="nofollow" href="https://www.r-bloggers.com/search/animation">animation</a>), programming (<a title="RStudio IDE for R" rel="nofollow" href="https://www.r-bloggers.com/search/RStudio">RStudio</a>, <a title="Sweave and literate programming" rel="nofollow" href="https://www.r-bloggers.com/search/sweave">Sweave</a>, <a title="LaTeX in R" rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX">LaTeX</a>, <a title="SQL and databases" rel="nofollow" href="https://www.r-bloggers.com/search/SQL">SQL</a>, <a title="Eclipse IDE for R" rel="nofollow" href="https://www.r-bloggers.com/search/eclipse">Eclipse</a>, <a title="git and github, Version Control System" rel="nofollow" href="https://www.r-bloggers.com/search/git">git</a>, <a title="Large data in R using Hadoop" rel="nofollow" href="https://www.r-bloggers.com/search/hadoop">hadoop</a>, <a title="Web Scraping of google, facebook, yahoo, twitter and more using R" rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping">Web Scraping</a>) statistics (<a title="Regressions and ANOVA analysis tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/regression">regression</a>, <a title="principal component analysis tutorial" rel="nofollow" href="https://www.r-bloggers.com/search/PCA">PCA</a>, <a title="Time series" rel="nofollow" href="https://www.r-bloggers.com/search/time+series">time series</a>, <a title="finance trading" rel="nofollow" href="https://www.r-bloggers.com/search/trading">trading</a>) and more...
<img height="1" alt="" width="1" src="http://feeds.feedburner.com/~r/RBloggers/~4/I_--KllqhE8"></a></div>