<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/comparing-plotly-ggplotly-plot-generation-times/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="http://blog.jumpingrivers.com/posts/2017/plotly_vs_ggplotly/"> R on The Jumping Rivers Blog</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p><br>
<br>
<br>




</p>
<div>
<ul>
<li><a rel="nofollow" href="http://blog.jumpingrivers.com/posts/2017/plotly_vs_ggplotly/#prerequisites" target="_blank">Prerequisites</a></li>
<li><a rel="nofollow" href="http://blog.jumpingrivers.com/posts/2017/plotly_vs_ggplotly/#analysis" target="_blank">Analysis</a></li>
<li><a rel="nofollow" href="http://blog.jumpingrivers.com/posts/2017/plotly_vs_ggplotly/#summary" target="_blank">Summary</a></li>
</ul>
</div>
<p>The <strong>plotly</strong> package. A godsend for interactive documents, dashboard and presentations. For such documents there is no doubt that anyone would prefer a plot created in <strong>plotly</strong> rather than <strong>ggplot2</strong>. Why? Using <strong>plotly</strong> gives you neat and crucially <em>interactive</em> options at the top, where as <strong>ggplot2</strong> objects are static. In an app we have been developing here at <a rel="nofollow" href="https://www.jumpingrivers.com/" target="_blank">Jumping Rivers</a>, we found ourselves asking the question would it be quicker to use <code>plot_ly()</code> or wrapping a <strong>ggplot2</strong> object in <code>ggplotly()</code>? I found the results staggering.</p>
<hr>
<div>
<h3>Prerequisites</h3>
<p>Throughout we will be using the packages: <strong>dplyr</strong>, <strong>tidyr</strong>, <strong>ggplot2</strong>, <strong>plotly</strong> and <strong>microbenchmark</strong>. The data in use is the <code>birthdays</code> dataset in the <strong>mosaicData</strong> package. This data sets contains the daily birth count in each state of the USA from 1969 – 1988. The packages can be installed in the usual way (remember you can install packages in <a rel="nofollow" href="http://blog.jumpingrivers.com/posts/2017/speed_package_installation/" target="_blank">parallel</a>)</p>
<pre><code>install.packages(c(&quot;mosaicData&quot;, &quot;dplyr&quot;, 
                   &quot;tidyr&quot;, &quot;ggplot2&quot;, 
                   &quot;plotly&quot;, &quot;microbenchmark&quot;))</code></pre>
<pre><code>library(&quot;mosaicData&quot;)
library(&quot;dplyr&quot;)
library(&quot;tidyr&quot;)
library(&quot;ggplot2&quot;)
library(&quot;plotly&quot;)
library(&quot;microbenchmark&quot;)</code></pre>
<hr>
</div>
<div>
<h3>Analysis</h3>
<p>Let’s load and take a look at the data.</p>
<pre><code>data(&quot;Birthdays&quot;, package = &quot;mosaicData&quot;)
head(Birthdays)
##   state year month day       date wday births
## 1    AK 1969     1   1 1969-01-01  Wed     14
## 2    AL 1969     1   1 1969-01-01  Wed    174
## 3    AR 1969     1   1 1969-01-01  Wed     78
## 4    AZ 1969     1   1 1969-01-01  Wed     84
## 5    CA 1969     1   1 1969-01-01  Wed    824
## 6    CO 1969     1   1 1969-01-01  Wed    100</code></pre>
<p>First, we’ll create a very simple scatter graph of the mean births in every year.</p>
<pre><code>meanb = Birthdays %>% 
    group_by(year) %>% 
    summarise(mean = mean(births))</code></pre>
<p>Wrapping this as a <strong>ggplot</strong> object inside <code>ggplotly()</code> we obtain this…</p>
<pre><code>ggplotly(ggplot(meanb) + 
  geom_point(aes(y = mean, x = year, colour = year)))</code></pre>
<p><div></div>
<p> Whilst using <code>plot_ly()</code> give us this…</p>
<pre><code>plot_ly(data = meanb, 
        y = ~mean, x = ~year, color = ~year, 
        type = &quot;scatter&quot;)</code></pre>
<div></div>
<p></p>
<p>Both graphs are, identical, bar styling, yes?</p>
<p>Now let’s use <code>microbenchmark</code> to see how their timings compare (for an overview on timing R functions, see our <a rel="nofollow" href="http://blog.jumpingrivers.com/posts/2017/timing-in-r/" target="_blank">previous blog post</a>).</p>
<pre><code>time = microbenchmark::microbenchmark(
        ggplotly = ggplotly(ggplot(meanb) + 
                            geom_point(aes(y = mean, x = year, colour = year))),
        plotly = plot_ly(data = meanb, 
                         y = ~mean, x = ~year, 
                         color = ~year, type = &quot;scatter&quot;),
        times = 100, unit = &quot;s&quot;)
time
## Unit: seconds
##      expr      min       lq     mean   median       uq     max neval cld
##  ggplotly 0.050139 0.052229 0.070750 0.054760 0.056785 1.56652   100   b
##    plotly 0.002475 0.002527 0.003017 0.002571 0.002674 0.03061   100  a</code></pre>
<pre><code>autoplot(time)</code></pre>
<p><img width="450" src="http://blog.jumpingrivers.com/posts/2017/2017-11-27-plotly_vs_ggplotly_files/figure-html/unnamed-chunk-8-1.svg"></p>
<p>Now I thought nesting a <strong>ggplot</strong> object within <code>ggplotly()</code> would be slower than using <code>plot_ly()</code>, but I didn’t think it would be this slow. On average <code>ggplotly()</code> is approximately 23 times slower than <code>plot_ly()</code>. <strong><em>23!</em></strong></p>
<p>Let’s take it up a notch. There we were plotting only 20 points, what about if we plot over 20,000? Here we will plot the min, mean and max births on each day.</p>
<pre><code>date = Birthdays %>% 
  group_by(date) %>% 
  summarise(mean = mean(births), min = min(births), max = max(births)) %>% 
  gather(birth_stat, value, -date)</code></pre>
<p>Wrapping this a <strong>ggplot2</strong> object inside <code>ggplotly()</code> we obtain this graph…</p>
<pre><code>ggplotly(ggplot(date) +
    geom_point(aes(y = value, x = date, colour = birth_stat)))</code></pre>
<p><div></div>
<p> Whilst using <code>plot_ly()</code> we obtain…</p>
<pre><code>plot_ly(date, 
        x = ~date, y = ~value, color = ~birth_stat, 
        type = &quot;scatter&quot;)</code></pre>
<p><div></div>
<p> Again, both plots are identical, bar styling.</p>
<pre><code>time2 = microbenchmark(
  ggplotly = ggplotly(
    ggplot(date) +
      geom_point(aes(y = value, x = date, colour = birth_stat))
    ),
    plotly = plot_ly(date, x = ~date, y = ~value, 
                      color = ~birth_stat, 
                      type = &quot;scatter&quot;),
  times = 100, unit = &quot;s&quot;)
time2
## Unit: seconds
##      expr      min       lq     mean   median       uq     max neval cld
##  ggplotly 0.335823 0.355301 0.389759 0.365353 0.378502 0.54746   100   b
##    plotly 0.002472 0.002534 0.002719 0.002585 0.002675 0.01179   100  a</code></pre>
<pre><code>autoplot(time2)</code></pre>
<p><img width="450" src="http://blog.jumpingrivers.com/posts/2017/2017-11-27-plotly_vs_ggplotly_files/figure-html/unnamed-chunk-15-1.svg"></p>
<p>On average <code>ggplotly()</code> is 143 times slower than <code>plot_ly()</code>, with the max run time being 0.547 seconds!</p>
<hr>
</div>
<div>
<h3>Summary</h3>
<p>I’m going to level with you. Using <code>ggplotly()</code> in interactive mode isn’t a problem. Well, it’s not a problem until your shiny dashboard or your markdown document has to generate a few plots at the same time. With only one plot, you’ll probably go with the method that gives you your style in the easiest way possible and you’ll do this with no repercussions. However, let’s say you’re making a shiny dashboard and it now has over 5 interactive graphs within it. Suddenly, if you’re using <code>ggplotly()</code>, the lag we noticed in the analysis above starts to build up unnecessarily. That’s why I’d use <code>plot_ly()</code>.</p>
<p>Thanks for chatting!</p>
<hr>
<pre><code>R.version.string
## [1] &quot;R version 3.4.2 (2017-09-28)&quot;
packageVersion(&quot;ggplot2&quot;)
## [1] '2.2.1'
packageVersion(&quot;plotly&quot;)
## [1] '4.7.1'</code></pre>
<hr>
<p><a rel="nofollow" href="https://www.jumpingrivers.com/?utm_source=blog&utm_medium=image&utm_campaign=plotly_vs_ggplotly" target="_blank"><img src="https://i1.wp.com/blog.jumpingrivers.com/img/logos/300_125.jpg?w=456" data-recalc-dims="1"></a></p>
</div>
	<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://blog.jumpingrivers.com/posts/2017/plotly_vs_ggplotly/"> R on The Jumping Rivers Blog</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/IVp5Yuu8sxU" height="1"></a></div>