<p><div><div><div><div data-show-faces="false" data-height="21" data-width="100" data-layout="button_count" data-send="true" data-href="https://www.r-bloggers.com/2017-ropensci-ozunconf-reflections-and-the-realtime-package/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="https://ropensci.org/blog/2017/11/14/realtime/"> rOpenSci - open tools for open science</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p> </p>
<p>This year’s <a rel="nofollow" href="https://ozunconf17.ropensci.org/" target="_blank">rOpenSci ozunconf</a> was held in Melbourne, bringing together over 45 R enthusiasts from around the country and beyond. As is customary, ideas for projects were discussed in <a rel="nofollow" href="https://github.com/ropensci/ozunconf17/issues" target="_blank">GitHub Issues</a> (41 of them by the time the unconf rolled around!) and there was no shortage of enthusiasm, interesting concepts, and varied experience.</p>
<p>I’ve been to a few unconfs now and I treasure the time I get to spend with new people, new ideas, new backgrounds, new approaches, and new insights. That’s not to take away from the time I get to spend with people I met at previous unconfs; I’ve gained great friendships and started collaborations on side projects with these wonderful people.</p>
<p>When the call for nominations came around this year it was an easy decision. I don’t have employer support to attend these things so I take time off work and pay my own way. This is my networking time, my development time, and my skill-building time. I wasn’t sure what sort of project I’d be interested in but I had no doubts something would come up that sounded interesting.</p>
<p>As it happened, I had been playing around with a bit of code, purely out of interest and hoping to learn how <a rel="nofollow" href="https://www.htmlwidgets.org/" target="_blank"><code>htmlwidgets</code></a> work. The idea I had was to make a classic graphic equaliser visualisation like this</p>
<p><img alt="" src="https://i1.wp.com/ropensci.org/img/blog-images/2017-11-14-realtime/graphiceq.gif?w=456&ssl=1" data-recalc-dims="1"></p>
<p>using R.</p>
<p>This presents several challenges; how can I get live audio into R, and how fast can I plot the signal? I had doubts about both parts, partly because of the way that R calls tie up the session (<a rel="nofollow" href="https://appsilondatascience.com/blog/rstats/2017/11/01/r-promises-hands-on.html" target="_blank">for now…</a>) and partly because constructing a <code>ggplot2</code> object is somewhat slow (in terms of raw audio speeds). I’d heard about <code>htmlwidgets</code> and thought there must be a way to leverage that towards my goal.</p>
<p>I searched for a graphic equaliser javascript library to work with and didn’t find much that aligned with what I had in my head. Eventually I stumbled on <a rel="nofollow" href="https://p5js.org/" target="_blank"><code>p5.js</code></a> and its examples page which has an <a rel="nofollow" href="https://p5js.org/examples/sound-frequency-spectrum.html" target="_blank">audio-input plot with a live demo</a>. It’s a frequency spectrum, but I figured that’s just a bit of binning away from what I need. Running the example there looks like</p>
<p><img alt="" src="https://i0.wp.com/ropensci.org/img/blog-images/2017-11-14-realtime/p5sound_optimised.gif?w=456&ssl=1" data-recalc-dims="1"></p>
<p>This seemed to be worth a go. I managed to follow enough of <a rel="nofollow" href="https://www.htmlwidgets.org/develop_intro.html" target="_blank">this tutorial</a> to have the library called from R. I modified the javascript canvas code to look a little more familiar, and the first iteration of <code>geom_realtime()</code> was born</p>
<p><iframe width="450" allowfullscreen src="https://www.youtube.com/embed/3mdiCUbgxi0"></iframe></p>
<p>This seemed like enough of an idea that I proposed it in the GitHub Issues for the unconf. It got a bit of attention, which was worrying, because I had no idea what to do with this next. <a rel="nofollow" href="https://github.com/petehaitch" target="_blank">Peter Hickey</a> pointed out that <a rel="nofollow" href="https://github.com/seankross" target="_blank">Sean Kross</a> had <a rel="nofollow" href="https://seankross.com/2017/08/11/Beyond-Axes-Simulating-Systems-with-Interactive-Graphics.html" target="_blank">already wrapped some of the <code>p5.js</code> calls into R calls</a> with his <code>p5</code> package, so this seemed like a great place to start. It’s quite a clever way of doing it too; it involves re-writing the <code>javascript</code> which <code>htmlwidgets</code> calls on each time you want to do something.</p>
<p>Fast forward to the unconf and a decent number of people gathered around a little slip of paper with <code>geom_realtime()</code> written on it. I had to admit to everyone that the <code>ggplot2</code> aspect of my demo was a sham (it’s surprisingly easy to draw a canvas in just the right shade of grey with white gridlines), but people stayed, and we got to work seeing what else we could do with the idea. We came up with some suggestions for input sources, some different plot types we might like to support, and set about trying to understand what Sean’s package actually did.</p>
<p>As it tends to work out, we had a great mix of people with different experience levels in different aspects of the project; some who knew how to make a package, some who knew how to work with <code>javascript</code>, some who knew how to work with <code>websockets</code>, some who knew about realtime data sources, and some who knew about nearly none of these things (✋ that would be me). If everyone knew every aspect about how to go about an unconf project I suspect the endeavor would be a bit boring. I love these events because I get to learn so much about so many different topics.</p>
<p>I shared my demo script and we deconstructed the pieces. We dug into the inner workings of the <code>p5</code> package and started determining which parts we could siphon off to meet our own needs. One of the aspects that we wanted to figure out was how to simulate realtime data. This could be useful both for testing, and also in the situation where one might want to ’re-cast’ some time-coded data. We were thankful that <a rel="nofollow" href="https://github.com/kcf-jackson" target="_blank">Jackson Kwok</a> had gone deep-dive into <code>websockets</code> and pretty soon (surprisingly soon, perhaps; within the first day) we had examples of (albeit, constructed) real-time (every 100ms) data streaming from a server and being plotted at-speed</p>
<p><img alt="" src="https://i1.wp.com/ropensci.org/img/blog-images/2017-11-14-realtime/realtime_runif_optimised.gif?w=456&ssl=1" data-recalc-dims="1"></p>
<p>Best of all, running the plot code didn’t tie up the session; it uses a listener written into the <code>javascript</code> so it just waits for input on a particular port.</p>
<p>With the core goal well underway, people started branching out into aspects they found most interesting. We had some people work on finding and connecting actual data sources, such as the bitcoin exchange rate</p>
<p><img alt="" src="https://i1.wp.com/ropensci.org/img/blog-images/2017-11-14-realtime/realtime_btc_optimised.gif?w=456&ssl=1" data-recalc-dims="1"></p>
<p>and a live-stream of binary-encoded data from the <a rel="nofollow" href="http://qrng.anu.edu.au/index.php" target="_blank">Australian National University (ANU) Quantum Random Numbers Server</a></p>
<p><img alt="" src="https://i1.wp.com/ropensci.org/img/blog-images/2017-11-14-realtime/realtime_bin_optimised.gif?w=456&ssl=1" data-recalc-dims="1"></p>
<p>Others formalised the code so that it can be piped into different ‘themes’, and retain the <code>p5</code> structure for adding more components</p>
<p><img alt="" src="https://i0.wp.com/ropensci.org/img/blog-images/2017-11-14-realtime/realtime_bw.png?w=456&ssl=1" data-recalc-dims="1"></p>
<p>These were still toy examples of course, but they highlight what’s possible. They were each constructed using an offshoot of the <code>p5</code> package whereby the <code>javascript</code> is re-written to include various features each time the plot is generated.</p>
<p>Another route we took is to use the direct <code>javascript</code> binding API with factory functions. This had less flexibility in terms of adding modular components, but meant that the <code>javascript</code> could be modified without worrying about how it needed to interact with <code>p5</code> so much. This resulted in some outstanding features such as side-scrolling and date-time stamps. We also managed to pipe the data off to another thread for additional processing (in R) before being sent to the plot.</p>
<p>The example we ended up with reads the live-feed of Twitter posts under a given hashtag, computes a sentiment analysis on the words with R, and live-plots the result:</p>
<p><img alt="" src="https://i1.wp.com/ropensci.org/img/blog-images/2017-11-14-realtime/auspol.gif?w=456&ssl=1" data-recalc-dims="1"></p>
<p>Overall I was amazed at the progress we made over just two days. Starting from a silly idea/demo, we built a package which can plot realtime data, and can even serve up some data to be plotted. I have no expectations that this will be the way of the future, but it’s been a fantastic learning experience for me (and hopefully others too). It’s highlighted that there’s ways to achieve realtime plots, even if we’ve used a library built for drawing rather than one built for plotting per se.</p>
<p>It’s even inspired offshoots in the form of some R packages; <a rel="nofollow" href="https://github.com/ropenscilabs/tRainspotting" target="_blank"><code>tRainspotting</code></a> which shows realtime data on New South Wales public transport using <code>leaflet</code> as the canvas</p>
<p><img alt="" src="https://i2.wp.com/ropensci.org/img/blog-images/2017-11-14-realtime/tRainspotting.png?w=456&ssl=1" data-recalc-dims="1"></p>
<p>and <a rel="nofollow" href="https://github.com/kcf-jackson/jsReact/" target="_blank"><code>jsReact</code></a> which explores the interaction between R and Javascript</p>
<p><img alt="" src="https://i2.wp.com/github.com/kcf-jackson/jsReact/raw/master/inst/example_5.gif?w=456&ssl=1" data-recalc-dims="1"></p>
<p><img alt="" src="https://i1.wp.com/github.com/kcf-jackson/jsReact/raw/master/inst/example_6.gif?w=456&ssl=1" data-recalc-dims="1"></p>
<p>The possibilities are truly astounding. My list of ‘things to learn’ has grown significantly since the unconf, and projects are still starting up/continuing to develop. The <a rel="nofollow" href="https://github.com/jonocarroll/ggeasy" target="_blank"><code>ggeasy</code></a> package isn’t related, but it was spawned from another unconf Github Issue idea. Again; ideas and collaborations starting and developing.</p>
<p>I had a great time at the unconf, and I can’t wait until the next one. My hand will be going up to help out, attend, and help start something new.</p>
<p>My thanks and congratulations go out to each of the <a rel="nofollow" href="https://github.com/ropenscilabs/realtime" target="_blank"><code>realtime</code></a> developers: <a rel="nofollow" href="https://github.com/richardbeare" target="_blank">Richard Beare</a>, <a rel="nofollow" href="https://github.com/jonocarroll" target="_blank">Jonathan Carroll</a>, <a rel="nofollow" href="https://github.com/kimnewzealand" target="_blank">Kim Fitter</a>, <a rel="nofollow" href="https://github.com/softloud" target="_blank">Charles Gray</a>, <a rel="nofollow" href="https://github.com/jeffreyhanson" target="_blank">Jeffrey O Hanson</a>, <a rel="nofollow" href="https://github.com/holtzy" target="_blank">Yan Holtz</a>, <a rel="nofollow" href="https://github.com/kcf-jackson" target="_blank">Jackson Kwok</a>, <a rel="nofollow" href="https://github.com/MilesMcBain" target="_blank">Miles McBain</a> and the entire cohort of <a rel="nofollow" href="https://ozunconf17.ropensci.org/" target="_blank">2017 rOpenSci ozunconf attendees</a>. In particular, my thanks go to the organisers of such a wonderful event; <a rel="nofollow" href="https://github.com/njtierney" target="_blank">Nick Tierney</a>, <a rel="nofollow" href="https://github.com/robjhyndman" target="_blank">Rob Hyndman</a>, <a rel="nofollow" href="https://github.com/dicook" target="_blank">Di Cook</a>, and <a rel="nofollow" href="https://github.com/MilesMcBain" target="_blank">Miles McBain</a>.</p>
	<p>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://ropensci.org/blog/2017/11/14/realtime/"> rOpenSci - open tools for open science</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 rel="nofollow" href="https://www.r-project.org/" title="The R Project for Statistical Computing">R</a> news and <a rel="nofollow" href="https://www.r-bloggers.com/search/tutorial" title="R tutorials">tutorials</a> on topics such as: <a rel="nofollow" href="https://www.r-bloggers.com/search/data%20science" title="Data science">Data science</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Big%20Data" title="Big Data">Big Data, <a rel="nofollow" href="https://www.r-users.com/" title="R jobs">R jobs</a>, visualization (<a rel="nofollow" href="https://www.r-bloggers.com/search/ggplot2" title="ggplot and ggplot2 tutorials">ggplot2</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/boxplot" title="Boxplots using lattice and ggplot2 tutorials">Boxplots</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/map" title="Maps and gis">maps</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/animation" title="Animation in R">animation</a>), programming (<a rel="nofollow" href="https://www.r-bloggers.com/search/RStudio" title="RStudio IDE for R">RStudio</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/sweave" title="Sweave and literate programming">Sweave</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX" title="LaTeX in R">LaTeX</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/SQL" title="SQL and databases">SQL</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/eclipse" title="Eclipse IDE for R">Eclipse</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/git" title="git and github, Version Control System">git</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/hadoop" title="Large data in R using Hadoop">hadoop</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping" title="Web Scraping of google, facebook, yahoo, twitter and more using R">Web Scraping</a>) statistics (<a rel="nofollow" href="https://www.r-bloggers.com/search/regression" title="Regressions and ANOVA analysis tutorials">regression</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/PCA" title="principal component analysis tutorial">PCA</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/time+series" title="Time series">time series</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/trading" title="finance trading">trading</a>) and more...
<img width="1" alt="" src="http://feeds.feedburner.com/~r/RBloggers/~4/4YVAPwd3rHQ" height="1"></a></div>