How to: Weather Radials

[This article was first published on Jkunst - R category, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

TLDR: Creating weather radials with highcharter and
ggplot2.

I was surfing by the deep seas of the web and I found the Brice Pierre de la Briere’s
blocks and I saw the weather radials which originally are a
poster collection. Brice uses D3 and he used D3 very well
and I love D3 but I’m in a rookie level to do something like him. D3 is not for everybody
and surely not for me, I would love to lear more but family, work and R has priority over D3 so
how can I do something like that. Well… We have R & highcarter. So let’s try.

We’ll use the same data as Brice [https://www.wunderground.com/].

<span class="n">df</span> <span class="o"><-</span> <span class="n">read_csv</span><span class="p">(</span><span class="s2">"http://bl.ocks.org/bricedev/raw/458a01917183d98dff3c/sf.csv"</span><span class="p">)</span>

<span class="n">df</span><span class="p">[</span><span class="m">1</span><span class="o">:</span><span class="m">4</span><span class="p">,</span> <span class="m">1</span><span class="o">:</span><span class="m">4</span><span class="p">]</span>
date Max TemperatureC Mean TemperatureC Min TemperatureC
2014-01-01 13 9 5
2014-01-02 17 12 6
2014-01-03 18 12 7
2014-01-04 19 13 6
<span class="n">names</span><span class="p">(</span><span class="n">df</span><span class="p">)</span> <span class="o"><-</span> <span class="n">names</span><span class="p">(</span><span class="n">df</span><span class="p">)</span> <span class="o">%>%</span> 
  <span class="n">str_to_lower</span><span class="p">()</span> <span class="o">%>%</span> 
  <span class="n">str_replace</span><span class="p">(</span><span class="s2">"\s+"</span><span class="p">,</span> <span class="s2">"_"</span><span class="p">)</span>

<span class="n">df</span> <span class="o"><-</span> <span class="n">df</span> <span class="o">%>%</span> 
  <span class="n">mutate</span><span class="p">(</span><span class="n">id</span> <span class="o">=</span> <span class="n">seq</span><span class="p">(</span><span class="n">nrow</span><span class="p">(</span><span class="n">df</span><span class="p">)),</span>
         <span class="n">date2</span> <span class="o">=</span> <span class="n">as.Date</span><span class="p">(</span><span class="n">ymd</span><span class="p">(</span><span class="n">date</span><span class="p">)),</span>
         <span class="n">tmstmp</span> <span class="o">=</span> <span class="n">datetime_to_timestamp</span><span class="p">(</span><span class="n">date2</span><span class="p">),</span>
         <span class="n">month</span> <span class="o">=</span> <span class="n">month</span><span class="p">(</span><span class="n">ymd</span><span class="p">(</span><span class="n">date</span><span class="p">)))</span>

<span class="n">dsmax</span> <span class="o"><-</span> <span class="n">df</span> <span class="o">%>%</span>
  <span class="n">select</span><span class="p">(</span><span class="n">x</span> <span class="o">=</span> <span class="n">tmstmp</span><span class="p">,</span>
         <span class="n">y</span> <span class="o">=</span> <span class="n">max_temperaturec</span><span class="p">)</span> <span class="o">%>%</span> 
  <span class="n">list.parse3</span><span class="p">()</span>
 
<span class="n">dsmin</span> <span class="o"><-</span> <span class="n">df</span> <span class="o">%>%</span> 
  <span class="n">select</span><span class="p">(</span><span class="n">x</span> <span class="o">=</span> <span class="n">tmstmp</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="n">min_temperaturec</span><span class="p">)</span> <span class="o">%>%</span> 
  <span class="n">list.parse3</span><span class="p">()</span>

First try

Here we test and chart the data in the most simple way. A line time.

<span class="n">hc</span> <span class="o"><-</span> <span class="n">highchart</span><span class="p">()</span> <span class="o">%>%</span> 
  <span class="n">hc_chart</span><span class="p">(</span>
    <span class="n">type</span> <span class="o">=</span> <span class="s2">"line"</span>
    <span class="p">)</span> <span class="o">%>%</span>
  <span class="n">hc_xAxis</span><span class="p">(</span>
    <span class="n">type</span> <span class="o">=</span> <span class="s2">"datetime"</span><span class="p">,</span>
    <span class="n">tickInterval</span> <span class="o">=</span> <span class="m">30</span> <span class="o">*</span> <span class="m">24</span> <span class="o">*</span> <span class="m">3600</span> <span class="o">*</span> <span class="m">1000</span><span class="p">,</span>
    <span class="n">labels</span> <span class="o">=</span> <span class="n">list</span><span class="p">(</span><span class="n">format</span> <span class="o">=</span> <span class="s2">"{value: %b}"</span><span class="p">)</span>
  <span class="p">)</span> <span class="o">%>%</span> 
  <span class="n">hc_yAxis</span><span class="p">(</span>
    <span class="n">min</span> <span class="o">=</span> <span class="m">0</span><span class="p">,</span>
    <span class="n">labels</span> <span class="o">=</span> <span class="n">list</span><span class="p">(</span><span class="n">format</span> <span class="o">=</span> <span class="s2">"{value} C"</span><span class="p">)</span>
  <span class="p">)</span> <span class="o">%>%</span> 
  <span class="n">hc_add_series</span><span class="p">(</span>
    <span class="n">data</span> <span class="o">=</span> <span class="n">dsmax</span><span class="p">,</span> <span class="n">name</span> <span class="o">=</span> <span class="s2">"max"</span>
  <span class="p">)</span> <span class="o">%>%</span> 
  <span class="n">hc_add_series</span><span class="p">(</span>
    <span class="n">data</span> <span class="o">=</span> <span class="n">dsmin</span><span class="p">,</span> <span class="n">name</span> <span class="o">=</span> <span class="s2">"min"</span>
    <span class="p">)</span> <span class="o">%>%</span> 
  <span class="n">hc_add_theme</span><span class="p">(</span>
    <span class="n">hc_theme_smpl</span><span class="p">()</span>
    <span class="p">)</span>

<span class="n">hc</span>

open

Everything seems fine.

Second Step

We’ change the type to column, stack and see what is the result

<span class="n">hc</span> <span class="o"><-</span> <span class="n">hc</span> <span class="o">%>%</span> 
  <span class="n">hc_chart</span><span class="p">(</span>
    <span class="n">type</span> <span class="o">=</span> <span class="s2">"column"</span>
    <span class="p">)</span> <span class="o">%>%</span> 
  <span class="n">hc_plotOptions</span><span class="p">(</span>
    <span class="n">series</span> <span class="o">=</span> <span class="n">list</span><span class="p">(</span>
      <span class="n">stacking</span> <span class="o">=</span> <span class="s2">"normal"</span>
    <span class="p">)</span>
  <span class="p">)</span>

<span class="n">hc</span>

open

Not so close.

Final Step

If you see the previous chart we stacked so we sum the min and max
and the data don’t reflect the value (min,max) what we want.
So we need to create the difference between the max and min,
and plot them with the min value and hiding using a transparent color.

And set polar = TRUE obviously.

<span class="n">dsmax</span> <span class="o"><-</span> <span class="n">df</span> <span class="o">%>%</span> 
  <span class="n">mutate</span><span class="p">(</span><span class="n">color</span> <span class="o">=</span> <span class="n">colorize_vector</span><span class="p">(</span><span class="n">mean_temperaturec</span><span class="p">,</span> <span class="s2">"A"</span><span class="p">),</span>
         <span class="n">y</span> <span class="o">=</span> <span class="n">max_temperaturec</span> <span class="o">-</span> <span class="n">min_temperaturec</span><span class="p">)</span> <span class="o">%>%</span> 
  <span class="n">select</span><span class="p">(</span><span class="n">x</span> <span class="o">=</span> <span class="n">tmstmp</span><span class="p">,</span>
         <span class="n">y</span><span class="p">,</span>
         <span class="n">name</span> <span class="o">=</span> <span class="n">date</span><span class="p">,</span>
         <span class="n">color</span><span class="p">,</span>
         <span class="n">mean</span> <span class="o">=</span> <span class="n">mean_temperaturec</span><span class="p">,</span>
         <span class="n">max</span> <span class="o">=</span> <span class="n">max_temperaturec</span><span class="p">,</span>
         <span class="n">min</span> <span class="o">=</span> <span class="n">min_temperaturec</span><span class="p">)</span> <span class="o">%>%</span> 
  <span class="n">list.parse3</span><span class="p">()</span>


<span class="c1"># Some tooltips to make it a little *intercative*
</span><span class="n">x</span> <span class="o"><-</span> <span class="n">c</span><span class="p">(</span><span class="s2">"Min"</span><span class="p">,</span> <span class="s2">"Mean"</span><span class="p">,</span> <span class="s2">"Max"</span><span class="p">)</span>
<span class="n">y</span> <span class="o"><-</span> <span class="n">sprintf</span><span class="p">(</span><span class="s2">"{point.%s}"</span><span class="p">,</span> <span class="n">tolower</span><span class="p">(</span><span class="n">x</span><span class="p">))</span>
<span class="n">tltip</span> <span class="o"><-</span> <span class="n">tooltip_table</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span>

<span class="n">hc</span> <span class="o"><-</span> <span class="n">highchart</span><span class="p">()</span> <span class="o">%>%</span> 
  <span class="n">hc_chart</span><span class="p">(</span>
    <span class="n">type</span> <span class="o">=</span> <span class="s2">"column"</span><span class="p">,</span>
    <span class="n">polar</span> <span class="o">=</span> <span class="n">TRUE</span>
  <span class="p">)</span> <span class="o">%>%</span>
  <span class="n">hc_plotOptions</span><span class="p">(</span>
    <span class="n">series</span> <span class="o">=</span> <span class="n">list</span><span class="p">(</span>
      <span class="n">stacking</span> <span class="o">=</span> <span class="s2">"normal"</span><span class="p">,</span>
      <span class="n">showInLegend</span> <span class="o">=</span> <span class="n">FALSE</span>
    <span class="p">)</span>
  <span class="p">)</span> <span class="o">%>%</span> 
  <span class="n">hc_xAxis</span><span class="p">(</span>
    <span class="n">gridLineWidth</span> <span class="o">=</span> <span class="m">0.5</span><span class="p">,</span>
    <span class="n">type</span> <span class="o">=</span> <span class="s2">"datetime"</span><span class="p">,</span>
    <span class="n">tickInterval</span> <span class="o">=</span> <span class="m">30</span> <span class="o">*</span> <span class="m">24</span> <span class="o">*</span> <span class="m">3600</span> <span class="o">*</span> <span class="m">1000</span><span class="p">,</span>
    <span class="n">labels</span> <span class="o">=</span> <span class="n">list</span><span class="p">(</span><span class="n">format</span> <span class="o">=</span> <span class="s2">"{value: %b}"</span><span class="p">)</span>
  <span class="p">)</span> <span class="o">%>%</span> 
  <span class="n">hc_yAxis</span><span class="p">(</span>
    <span class="n">max</span> <span class="o">=</span> <span class="m">30</span><span class="p">,</span>
    <span class="n">min</span> <span class="o">=</span> <span class="m">-10</span><span class="p">,</span>
    <span class="n">labels</span> <span class="o">=</span> <span class="n">list</span><span class="p">(</span><span class="n">format</span> <span class="o">=</span> <span class="s2">"{value} C"</span><span class="p">),</span>
    <span class="n">showFirstLabel</span> <span class="o">=</span> <span class="n">FALSE</span>
    <span class="p">)</span> <span class="o">%>%</span> 
  <span class="n">hc_add_series</span><span class="p">(</span>
    <span class="n">data</span> <span class="o">=</span> <span class="n">dsmax</span>
  <span class="p">)</span> <span class="o">%>%</span> 
  <span class="n">hc_add_series</span><span class="p">(</span>
    <span class="n">data</span> <span class="o">=</span> <span class="n">dsmin</span><span class="p">,</span>
    <span class="n">color</span> <span class="o">=</span> <span class="s2">"transparent"</span><span class="p">,</span>
    <span class="n">enableMouseTracking</span> <span class="o">=</span> <span class="n">FALSE</span>
  <span class="p">)</span> <span class="o">%>%</span> 
  <span class="n">hc_add_theme</span><span class="p">(</span>
    <span class="n">hc_theme_smpl</span><span class="p">()</span>
  <span class="p">)</span> <span class="o">%>%</span> 
  <span class="n">hc_tooltip</span><span class="p">(</span>
    <span class="n">useHTML</span> <span class="o">=</span> <span class="n">TRUE</span><span class="p">,</span>
    <span class="n">headerFormat</span> <span class="o">=</span> <span class="n">as.character</span><span class="p">(</span><span class="n">tags</span><span class="o">$</span><span class="n">small</span><span class="p">(</span><span class="s2">"{point.x:%d %B, %Y}"</span><span class="p">)),</span>
    <span class="n">pointFormat</span> <span class="o">=</span> <span class="n">tltip</span>
  <span class="p">)</span>

<span class="n">hc</span>

open

Yay :D! A beautiful chart same as the d3 version and only using R. So sweet!

I’m happy with the result. This is not a standar chart but is
a king of artistic. What do you think? Any other examples to test
this type of chart?

Bonus Track: ggplot2 version

It’s really really easy to do this type of chart in ggplot2 using
geom_linerange and geom_polar:

<span class="n">library</span><span class="p">(</span><span class="s2">"ggplot2"</span><span class="p">)</span>
<span class="n">library</span><span class="p">(</span><span class="s2">"viridis"</span><span class="p">)</span>
<span class="n">library</span><span class="p">(</span><span class="s2">"scales"</span><span class="p">)</span>

<span class="n">ggplot</span><span class="p">(</span><span class="n">df</span><span class="p">,</span> <span class="n">aes</span><span class="p">(</span><span class="n">date2</span><span class="p">,</span>
               <span class="n">ymin</span> <span class="o">=</span> <span class="n">min_temperaturec</span><span class="p">,</span>
               <span class="n">ymax</span> <span class="o">=</span> <span class="n">max_temperaturec</span><span class="p">,</span>
               <span class="n">color</span> <span class="o">=</span> <span class="n">mean_temperaturec</span><span class="p">))</span> <span class="o">+</span> 
  <span class="n">geom_linerange</span><span class="p">(</span><span class="n">size</span> <span class="o">=</span> <span class="m">1.3</span><span class="p">,</span> <span class="n">alpha</span> <span class="o">=</span> <span class="m">0.75</span><span class="p">)</span> <span class="o">+</span>
  <span class="n">scale_color_viridis</span><span class="p">(</span><span class="n">NULL</span><span class="p">,</span> <span class="n">option</span> <span class="o">=</span> <span class="s2">"A"</span><span class="p">)</span> <span class="o">+</span>
  <span class="n">scale_x_date</span><span class="p">(</span><span class="n">labels</span> <span class="o">=</span> <span class="n">date_format</span><span class="p">(</span><span class="s2">"%b"</span><span class="p">),</span> <span class="n">breaks</span> <span class="o">=</span> <span class="n">date_breaks</span><span class="p">(</span><span class="s2">"month"</span><span class="p">))</span> <span class="o">+</span> 
  <span class="n">ylim</span><span class="p">(</span><span class="m">-10</span><span class="p">,</span> <span class="m">35</span><span class="p">)</span> <span class="o">+</span> 
  <span class="n">labs</span><span class="p">(</span><span class="n">title</span> <span class="o">=</span> <span class="s2">"San Francisco Wather Radial"</span><span class="p">,</span>
       <span class="n">subtitle</span> <span class="o">=</span> <span class="s2">"It would be nice if someone do this with the animation package"</span><span class="p">,</span>
       <span class="n">caption</span> <span class="o">=</span> <span class="s2">"Other example for ggplot2 vs base #boring but #fun"</span><span class="p">,</span>
       <span class="n">x</span> <span class="o">=</span> <span class="n">NULL</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="n">NULL</span><span class="p">)</span> <span class="o">+</span>
  <span class="n">coord_polar</span><span class="p">()</span> <span class="o">+</span> 
  <span class="n">theme_jbk</span><span class="p">()</span> <span class="o">+</span>
  <span class="n">theme</span><span class="p">(</span><span class="n">legend.position</span> <span class="o">=</span> <span class="s2">"bottom"</span><span class="p">)</span>

plot of chunk unnamed-chunk-6

Nice!

Searching I found someone do
this:

Always exist someone who did what you did before you.

At least I share the code! :D.

giphy gif source

To leave a comment for the author, please follow the link and comment on their blog: Jkunst - R category.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)