R ggvis: How to Make Interactive Data Visualizations in R and R Shiny

By:
Dario Radečić
January 1, 1970

If you want to master the game of data visualization in R, <a href="https://appsilon.com/tag/ggplot2/" target="_blank" rel="noopener"><code>ggplot2</code></a> isn't your only option. R ggvis package is a viable alternative built on top of <code>ggplot2</code>, which also brings interactivity to the table. The cherry on top is that <code>ggvis</code> also has native R Shiny support, which could really make it a one-stop-shop when it comes to R data visualization packages. This article will teach you the basics of R ggvis data visualization. We'll go over a basic introduction and installation, to fundamental charts, their styling, interactive charts, and finally R Shiny with ggvis. It's gonna be a long one, but we promise to make it worth your time. <blockquote>Can you use Python's Matplotlib in R Shiny? <a href="https://appsilon.com/matplotlib-vs-ggplot/" target="_blank" rel="noopener">Learn how to use both Matplotlib and ggplot2 in your dashboards</a>.</blockquote> Table of contents: <ul><li><a href="#introduction">Introduction to R ggvis</a></li><li><a href="#basics">R ggvis Basics - How to Make Basic Data Visualizations</a></li><li><a href="#styling">How to Enrich and Optimize ggvis Charts</a></li><li><a href="#interactive">How to Make Interactive Data Visualizations with R ggvis</a></li><li><a href="#shiny">R ggvis in Shiny - How to Get Started</a></li><li><a href="#summary">Summing up R ggvis</a></li></ul> <hr /> <h2 id="introduction">Introduction to R ggvis</h2> The <a href="https://ggvis.rstudio.com/" target="_blank" rel="noopener">ggvis package</a> is built on top of another package everyone knows about - <code>ggplot2</code>. The idea behind <code>ggvis</code> is to add interactivity to already great-looking charts, and allow you to make your visualizations a bit more dynamic. The package is open-source and is available on <a href="https://cran.r-project.org/web/packages/ggvis/index.html" target="_blank" rel="noopener">CRAN</a>, which means you can install it by running the following command from the R console: <pre><code class="language-r">install.packages("ggvis")</code></pre> If you're interested in features that R ggvis offers, look no further. These ones separate it from the pack: <ul><li><b>Reactive programming: </b>The <code>ggvis</code> package relies on reactive programming to create interactive charts. This means you can create charts that respond to user input in real-time, all by changing the dropdown value or dragging a slider</li><li><b>Layering system: </b>Graphs are created by using the layering system, which means you overlay graphics on top of each other. Think of this as layer ordering in Photoshop.</li><li><b>Built-in interactivity: </b>There are many built-in interactive elements you can add to your charts, such as tooltips, legends, axis labels, and so on.</li><li><b>R Shiny integration: </b>The package works seamlessly with R Shiny, which means it makes it easy to create interactive web applications or dashboards.</li></ul> Now, we can't cover everything mentioned above in the scope of a single article, but we hope to give you a brief overview of basic plots, interactivity, and R Shiny. Let's start with a couple of basic plots you must know. <h2 id="basics">R ggvis Basics - How to Make Basic Data Visualizations</h2> In this section, you'll learn how to make some basic data visualizations with R ggvis on a real dataset. We'll use <a href="https://appsilon.com/r-dplyr-gapminder/" target="_blank" rel="noopener">Gapminder</a> for all of the visualizations, which is available under the <code>gapminder</code> R package. Install it if you don't have it already: <pre><code class="language-r">install.packages("gapminder")</code></pre> Let's first import this dataset and filter it down a bit. <h3>Loading the Gapminder Dataset</h3> The following code snippet imports all R packages you'll need to follow along. If you don't have some of them installed, run the <code>install.packages("package-name")</code> from the R console. The code snippet also prints the first 6 rows from the Gapminder dataset: <pre><code class="language-r">library(dplyr) library(ggvis) library(gapminder) <br>head(gapminder)</code></pre> Here's what they look like: <img class="size-full wp-image-18839" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b7d769765eef446fc72e54_92d50322_1-1.webp" alt="Image 1 - Head of the Gapminder dataset" width="1236" height="520" /> Image 1 - Head of the Gapminder dataset The dataset contains information on all countries across all continents, which is too much to display visually at once. For that reason, we'll filter the data down only to show the average life expectancy for each year (mean of all countries) in Europe. Here's the code snippet that uses <code>dplyr</code> to summarize the data: <pre><code class="language-r">life_exp_eu &lt;- gapminder %&gt;%  filter(continent == "Europe") %&gt;%  group_by(year) %&gt;%  summarise(avgLifeExp = mean(lifeExp)) <br>life_exp_eu</code></pre> We now have only two features that should be easy to represent graphically: <img class="size-full wp-image-18841" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b7d76a36826c9084361041_303396f6_2-1.webp" alt="Image 2 - Average life expectancy in Europe over time" width="994" height="824" /> Image 2 - Average life expectancy in Europe over time Let's start with basic scatter plots in R ggvis next. <h3>Basic Scatter Plot with ggvis</h3> A 2-dimensional scatter plot displays the relationship between two variables by a marker in an X-Y coordinate space. We'll use it to display the year on the X-axis and the average life expectancy on the Y-axis. <blockquote>Want to learn more about scatter plots in R? <a href="https://appsilon.com/ggplot-scatter-plots/" target="_blank" rel="noopener">Our hands-on guide with ggplot2 will get you started</a>.</blockquote> R ggvis uses dplyr-like syntax, which means you can change code lines by using the <code>%&gt;%</code> operator. The following code snippet plots a basic scatter chart: <pre><code class="language-r">life_exp_eu %&gt;%  ggvis(x = ~year, y = ~avgLifeExp)</code></pre> <img class="size-full wp-image-18843" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b7d76b2cd28b714e23c6c2_437393d4_3-1.webp" alt="Image 3 - Scatter plot with ggvis" width="1934" height="1696" /> Image 3 - Scatter plot with ggvis If you want to somewhat customize it, you can add values to <code>fill</code> and <code>size</code> parameters, and these will change the fill color and overall marker size: <pre><code class="language-r">life_exp_eu %&gt;%  ggvis(x = ~year, y = ~avgLifeExp, fill := "#0198f9", size := 150) %&gt;%  layer_points()</code></pre> <img class="size-full wp-image-18845" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b7d76b0750e0f883991cde_5c583734_4-1.webp" alt="Image 4 - Customised scatter plot with ggvis" width="1934" height="1696" /> Image 4 - Customised scatter plot with ggvis Instead of scatter plots, we can also represent this relationship with bar charts. Let's learn how next. <h3>Bar Plot with ggvis</h3> Bar charts, either horizontal or vertical, represent quantities of some variable with a rectangular shape. In general, the larger the rectangle, the higher the value of the variable at a given category. <blockquote>New to bar charts? <a href="https://appsilon.com/ggplot2-bar-charts/" target="_blank" rel="noopener">Learn the basics with R and ggplot2</a>.</blockquote> You can add the <code>layer_bars()</code> layer in R ggvis to instruct the package to display the data as a bar chart. The optional <code>fill</code> and <code>width</code> arguments determine the rectangle color and width, as the name suggests: <pre><code class="language-r">life_exp_eu %&gt;%  ggvis(x = ~year, y = ~avgLifeExp) %&gt;%  layer_bars(fill := "#0198f9", width = 4)</code></pre> <img class="size-full wp-image-18847" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b7d76c9006b587a562ca2b_c34a2890_5-1.webp" alt="Image 5 - Bar chart with ggvis" width="1934" height="1696" /> Image 5 - Bar chart with ggvis In short, bar charts <i>fill the area</i> much more than scatter plots. It's a matter of personal preference and whether a certain chart type works for your problem. In this case, it definitely does. But what about line charts? Let's find out. <h3>Line Plot with ggvis</h3> With R ggvis, you can use either <code>layer_lines()</code> or <code>layer_smooths()</code> to make a line chart. The latter will somewhat smoothen the line, which is a preferred look in most cases. <blockquote>You can do so much with line charts - <a href="https://appsilon.com/ggplot2-line-charts/" target="_blank" rel="noopener">And it's easier than ever with R and ggplot2</a>.</blockquote> The following code snippet represents life expectancy in Europe over time with a line chart: <pre><code class="language-r">life_exp_eu %&gt;%  ggvis(x = ~year, y = ~avgLifeExp) %&gt;%  layer_smooths(stroke := "#0198f9")</code></pre> <img class="size-full wp-image-18849" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b7d76c6d54b9a126eedc3e_b6585b1f_6-1.webp" alt="Image 6 - Line chart with ggvis" width="1934" height="1696" /> Image 6 - Line chart with ggvis And that's a line chart for you. The question you might have now is - <b>Can you combine multiple chart types into a single one?</b> Let's answer that next. <h3>Combining Multiple Layers in ggvis</h3> Combining multiple plot types in R ggvis is as simple as stacking two (or more) ggvis layers. for example, you can plot the line first, and then add the circular markers. Here's an example of how to make a line chart with markers in ggvis: <pre><code class="language-r">life_exp_eu %&gt;%  ggvis(x = ~year, y = ~avgLifeExp) %&gt;%  layer_smooths(stroke := "#0198f9") %&gt;%  layer_points(fill := "#0198f9", size := 150)</code></pre> <img class="size-full wp-image-18851" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b7d76d2cd28b714e23c785_99f2dc4a_7-1.webp" alt="Image 7 - Combining line and scatter plot with ggvis" width="1934" height="1696" /> Image 7 - Combining line and scatter plot with ggvis And that does it for the basics of R ggvis. You might have noticed that our charts are missing a couple of things, such as title and proper axis labels, and that some things aren't formatted optimally. That's what we'll address next. <h2 id="styling">How to Enrich and Optimize ggvis Charts</h2> Our ggvis charts are missing a couple of things right now, and these are preventing them from being sharable, either in static reports or dynamic dashboards. We'll address all the shortcomings in this section, starting with axis labels. <h3>How to Add Axis Labels</h3> Technically, our charts do have axis labels, but they aren't formatted optimally. Just take a look at the Y-axis label - <code>avgLifeExp</code> isn't something all users will catch. It's easy to change axis labels in R ggvis, as you only need to append the <code>add_axis()</code> function twice, one for each axis, and specify the title. The following code snippet addresses the axis labels on the bar chart created in the previous section: <pre><code class="language-r">life_exp_eu %&gt;%  ggvis(x = ~year, y = ~avgLifeExp) %&gt;%  layer_bars(fill := "#0198f9", width = 4) %&gt;%  add_axis("x", title = "Year") %&gt;%  add_axis("y", title = "Average life expectancy")</code></pre> <img class="size-full wp-image-18853" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b7d76ec774367445231dfa_d1f9bb74_8-1.webp" alt="Image 8 - Adding axis labels with ggvis" width="1934" height="1696" /> Image 8 - Adding axis labels with ggvis That was easy, but we're still missing a title. Let's add it next. <h3>How to Add Title</h3> Adding a title to an R ggvis chart isn't as straightforward as you might think. The official resources state you need to call <code>add_axis()</code> once again for the X-axis, and specify the <code>title</code> for the top <code>orient</code>. Here's what it should look like in the code: <pre><code class="language-r">life_exp_eu %&gt;%  ggvis(x = ~year, y = ~avgLifeExp) %&gt;%  layer_bars(fill := "#0198f9", width = 4) %&gt;%  add_axis("x", title = "Year") %&gt;%  add_axis("y", title = "Average life expectancy") %&gt;%  add_axis("x", orient = "top", title = "Average life expectancy in Europe over time")</code></pre> This alone adds the title, but it moves axis ticks to the top of the chart: <img class="size-full wp-image-18855" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b7d76ec774367445231e10_c4876ec3_9-1.webp" alt="Image 9 - Adding title with ggvis" width="1934" height="1696" /> Image 9 - Adding title with ggvis We're just going to say that this isn't what you want most of the time, and addressing this issue will take some work. You'll need to specify the additional <code>properties</code> argument to handle this issue, and it will put the ticks back to the bottom of the X-axis. While we're here, let's also increase the title font size: <pre><code class="language-r">life_exp_eu %&gt;%  ggvis(x = ~year, y = ~avgLifeExp) %&gt;%  layer_bars(fill := "#0198f9", width = 4) %&gt;%  add_axis("x", title = "Year") %&gt;%  add_axis("y", title = "Average life expectancy") %&gt;%  add_axis("x",    orient = "top", ticks = 0, title = "Average life expectancy in Europe over time",    properties = axis_props(      axis = list(stroke = "white"),      title = list(fontSize = 14),      labels = list(fontSize = 0)    )  )</code></pre> The resulting chart looks more natural now: <img class="size-full wp-image-18857" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b7d76f0ca3d363ce97f642_6acfdfeb_10-1.webp" alt="Image 10 - Modifying title with ggvis" width="1934" height="1696" /> Image 10 - Modifying title with ggvis That took care of the title, and the only issue remaining is the X-axis ticks. These represent years, so there's no need to format them as decimal numbers. <h3>How to Format Axis Ticks</h3> There's an additional <code>format</code> attribute you can specify when modifying an axis of the chart. Currently, our X-axis represents years but is formatted as decimal numbers, which isn't ideal. You can specify <code>format = "."</code> to mitigate this issue, and do so in the first call to <code>add_axis()</code> for the X-axis: <pre><code class="language-r">life_exp_eu %&gt;%  ggvis(x = ~year, y = ~avgLifeExp) %&gt;%  layer_bars(fill := "#0198f9", width = 4) %&gt;%  add_axis("x", title = "Year", format = ".") %&gt;%  add_axis("y", title = "Average life expectancy") %&gt;%  add_axis("x",    orient = "top", ticks = 0, title = "Average life expectancy in Europe over time",    properties = axis_props(      axis = list(stroke = "white"),      title = list(fontSize = 14),      labels = list(fontSize = 0)    )  )</code></pre> Now it's clear the X-axis actually represents years: <img class="size-full wp-image-18859" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b7d7719b186acba34f990c_e310d486_11-1.webp" alt="Image 11 - Formatting year axis ticks with ggvis" width="1934" height="1696" /> Image 11 - Formatting year axis ticks with ggvis We now have somewhat of a production-ready chart, but we still haven't taken full advantage of R ggvis, which lies in interactivity. Let's go over that next. <h2 id="interactive">How to Make Interactive Data Visualizations with R ggvis</h2> An interactive chart is a chart the end-user can modify on the fly, without making any changes to the code. R ggvis provides that functionality through a couple of built-in methods, and you'll learn the basics of them in this section. For example, you can control the bar fill color and width by replacing the static values with one of the following: <ul><li><code>input_select()</code> - Provides a dropdown menu for the user to choose from. The first value in a vector is the one chosen by default</li><li><code>input_slider()</code> - Provides a slider that the user can drag to customize the looks and behavior of the chart</li></ul> This will be much easier to understand through code. The following code snippet allows the user to change the bar color from 3 different ones, and also to change the individual bar width through a slider: <pre><code class="language-r">life_exp_eu %&gt;%  ggvis(x = ~year, y = ~avgLifeExp) %&gt;%  layer_bars(    fill := input_select(      c(        "Blue" = "#0198f9",        "Red" = "#C41E3A",        "Green" = "#52BE80"      )    ),    width = input_slider(      min = 1,      max = 5,      value = 4    )  ) %&gt;%  add_axis("x", title = "Year", format = ".") %&gt;%  add_axis("y", title = "Average life expectancy") %&gt;%  add_axis("x",    orient = "top", ticks = 0, title = "Average life expectancy in Europe over time",    properties = axis_props(      axis = list(stroke = "white"),      title = list(fontSize = 14),      labels = list(fontSize = 0)    )  )</code></pre> Here's what the resulting chart looks like: <img class="size-full wp-image-18861" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b7d771215de09d850f599e_88eb8e92_12.gif" alt="Image 12 - Interactive ggvis chart with custom controls" width="912" height="844" /> Image 12 - Interactive ggvis chart with custom controls You now have controls that you can use to modify how the chart looks and feels. That's valuable for the end-user who might not be as tech-savvy as you are. Finally, let's take a look at R ggvis integration with R Shiny. <h2 id="shiny">R ggvis in Shiny - How to Get Started</h2> It's now time to connect everything covered so far into a single R Shiny app. The idea is to have a simple app that allows you to change the content in the left sidebar menu, and an R ggvis chart displaying average life expectancy on that continent in the main app section. We'll start with the UI. <h3>Shiny App UI</h3> We'll keep the UI simple - a sidebar layout with a dropdown menu in the sidebar and a chart in the main section. The dropdown menu or the <code>selectInput()</code> allows you to change the continent, and it has unique values from the Gapminder's <code>continent</code> column as possible values. The main panel contains a <code>ggvisOutput</code> element that will be responsible for the chart. Here's the entire code snippet: <pre><code class="language-r">library(dplyr) library(ggvis) library(gapminder) library(shiny) <br> ui &lt;- fluidPage(  sidebarLayout(    sidebarPanel(      tags$h3("Gapminder Exploration"),      selectInput(        inputId = "in_continent",        label = "Select continent:",        choices = unique(gapminder$continent),        selected = "Europe"      )    ),    mainPanel(      ggvisOutput(plot_id = "life_exp_chart")    )  ) )</code></pre> We also need the server function before we can wrap this into a Shiny app, so let's go over that next. <h3>Shiny App Server</h3> The server logic is utterly simple - we need a reactive dataset that filters down the data and calculates average life expectancy, all based on the currently selected dropdown item. Then, we make a bar chart on top of that data. It's essential to call <code>bind_shiny("plot_id")</code> at the end of the chart logic, so Shiny can recognize where to place the chart. Here's the code for the entire server logic: <pre><code class="language-r">server &lt;- function(input, output) {  data &lt;- reactive({    gapminder %&gt;%      filter(continent == input$in_continent) %&gt;%      group_by(year) %&gt;%      summarise(avgLifeExp = mean(lifeExp))  }) <br>  data %&gt;%    ggvis(x = ~year, y = ~avgLifeExp) %&gt;%    layer_bars(fill := "#0198f9", width = 4) %&gt;%    add_axis("x", title = "Year", format = ".") %&gt;%    add_axis("y", title = "Average life expectancy") %&gt;%    add_axis("x",      orient = "top", ticks = 0, title = paste("Average life expectancy over time"),      properties = axis_props(        axis = list(stroke = "white"),        title = list(fontSize = 14),        labels = list(fontSize = 0)      )    ) %&gt;%    bind_shiny("life_exp_chart") }</code></pre> And finally, let's tie everything together with a call to <code>shinyApp()</code>: <pre><code class="language-r">shinyApp(ui = ui, server = server)</code></pre> You can run the R Shiny app now, as everything is ready. Here's what you should see: <img class="size-full wp-image-18863" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b0241312a2079be56c5b53_13.gif" alt="Image 13 - Finished R Shiny application with ggvis" width="864" height="844" /> Image 13 - Finished R Shiny application with ggvis <b>To summarize:</b> Use <code>ggvisOutput("plot_id")</code> in the UI to ensure placeholders for R ggvis charts. Then in the server function, attach the <code>bind_shiny("plot_id")</code> to the end of your chart logic to connect the chart to the placeholder. That's all for today, so let's make a short recap next. <hr /> <h2 id="summary">Summing up R ggvis</h2> Today you've learned yet another R package capable of producing some respective data visualizations. The <code>ggvis</code> package is one of the few that brings interactivity to the table and doesn't require you to use Shiny to tweak the data on the go. It also packs beautiful animations and transitions when updating data on the charts, which is one less thing you have to implement manually. <i>Do you want to see a more advanced guide on R ggvis?</i> Please let us know in the comment section below, and we'll be happy to write one. <i>What are your thoughts on R ggvis? Do you see it as an <code>ggplot2</code> alternative or not? And why?</i> Share your thoughts with us on Twitter - <a href="https://twitter.com/appsilon" target="_blank" rel="noopener">@appsilon</a>. <blockquote>Considering a career as an R Shiny professional? <a href="https://appsilon.com/how-to-start-a-career-as-an-r-shiny-developer/" target="_blank" rel="noopener">Our detailed guide covers everything you need to learn to get hired</a>.</blockquote>

Have questions or insights?

Engage with experts, share ideas and take your data journey to the next level!
Explore Possibilities

Share Your Data Goals with Us

From advanced analytics to platform development and pharma consulting, we craft solutions tailored to your needs.

Talk to our Experts
r
shiny
data visualization
tutorials