Interactive Graphics in RMarkdown

Now you know the basics of setting up an RMarkdown page and it looks really pretty but you’re still not really getting anything more out of it than a Sweave document. Here I’ll cover how to use some of the R libraries for interactive graphics, which will give your page a little more of a kick.

Specifically, I’ll spend most of the time covering a few different uses of the Plotly library, and then briefly introduce the Leaflet library at the end.

Plotly

There are a lot of different options for creating interactive graphis in R but I have had a lot of success using the plotly library. Plotly is a javascript library that was integrated into Phython and more recently into R, so that support is not great but it is generally pretty easy to use.

There are a couple of different way to use the library.

Simple graphs

First we can make a simple scatter plot that is generated directly by plotly using the diamond data that ships with R. I borrowed this example from plotly’s website. We’re plotting the Carat of a diamond against its price, coloring and changing the size of the dots by the carat. This basic function can generate most basic plot types including scatter plots, line graphs, bar graphs, pie charts, and surfaces. Examples are provided at the bottom of this page.

One important note before we start, these plots will NOT compile if code chunk cacheing is turned on, you need to turn it off for the interactive plots.

library(plotly)  #interactive plotting

set.seed(100)
d <- diamonds[sample(nrow(diamonds), 1000, replace=TRUE), ]
plot_ly(type="scatter",
        x = d$carat, #choose the x axis variable
        y = d$price, #choose the y axis variable
        text = paste("Clarity: ", d$clarity), #add the clarity variable to the mouse over
        mode = "markers", color = d$carat, size = d$carat)  %>% #adjust both the size and the color of dots by the carat value, then pipe
  layout(xaxis = list(title = "Carat", fixedrange = TRUE), #x axis title and disable zooming
         yaxis = list(title = "Price", fixedrange = TRUE), #y axis title and disable zooming
         title="")
#%>%  #no plot title, then pipe it to the next command
 # config(displaylogo = FALSE, displayModeBar = FALSE) #no plotly logo and remove most buttons

After generating our data, we run the plot_ly command to create a graph but before displaying it we pipe it to the layout command to specify some additional chart options such as the axis titles, and then we pipe that to the config command to suppress some water marks.

We could also have either nested these three functions, or have saved the output of each one and and run each command sequentially but the magrittr package makes sending the output of a function to the another function very easy. If the piping is confusing the steps are exactly equivalent to the following:

set.seed(100)
d <- diamonds[sample(nrow(diamonds), 1000, replace=TRUE), ]

#create the plot and save it
p <- plot_ly(type="scatter",
        x = d$carat, #choose the x axis variable
        y = d$price, #choose the y axis variable
        text = paste("Clarity: ", d$clarity), #add the clarity variable to the mouse over
        mode = "markers", color = d$carat, size = d$carat)#adjust both the size and the color of dots by the carat value

#apply layout options to the plot
p <- layout(p=p, xaxis = list(title = "Carat", fixedrange = TRUE), #x axis title and disable zooming
         yaxis = list(title = "Price", fixedrange = TRUE), #y axis title and disable zooming
         title="")#no plot title

#apply config options to the plot
#p <- config(p=p, displaylogo = FALSE, modeBarButtonsToRemove= remove) #no plotly logo and remove most buttons

#display the plot
p

ggplot

So far so easy but what if we want to do something more complicated that is not covered by the plot_ly function? Well, we can transform any ggplot graph object into a plotly graph object and give it additional interactive features. This also means that our graphics will have that classic ggplot aesthetic, which can either be a pro or a con depending on where you stand.

Let’s generate another plot based on the same diamond data, this time with a loess smoother. This example is also from the Plotly website.

#create a ggplot object
p <- ggplot(data = d, aes(x = carat, y = price)) +
  geom_point(size = 4) +
  geom_smooth(aes(colour = cut, fill = cut)) + facet_wrap(~ cut)

#run the ggplotly function on it
gg <- ggplotly(p)

#display the plot
gg

Advanced commands

Many of the graph options are controlled through the layout and config commands which can be difficult to use but enable a lot of flexibility. The first example showed how to set the X axis title to “Carat” and the Y axis title to “Price” by inserting a list into the layout command but this is not a particuarly well organized way of accomplishing this goal, especially if you have many graphs.

layout()

The cleanest way to make these changes to the X and Y axes is to save these specifications as lists and then and then send these lists to the layout command. For example, let’s disable zooming on the X and Y axes (which should be your default) and give them both boring titles.

x.options <- list(
    'fixedrange'= TRUE,
    'title' = 'X Axis'
)

y.options <- list(
    'fixedrange'= TRUE,
    'title' = 'Y Axis'
)

layout(xaxis = x.options, yaxis = y.options, title="")#no plot title

The following code is exactly equivalent

#alternatively
y.options <- list()
y.options$title <- "Y Axis"
y.options$fixedrange = TRUE

config()

Finally there are some important options to specify for the graph itself. By default, plotly adds a watermark to the hover over legend and its just filled with buttoms that are basically useless. Just check out the ggplot above, a million buttons pop up when you hover over it.

So let’s remove those. I figured out the names of these buttons from the modebar documentation, which is here. Then I just add them all to a vector which I call remove and then use this in the config command, also specifying that I do not want a logo.

#documentation
#https://github.com/plotly/plotly.js/blob/master/src/components/modebar/buttons.js

remove <- c('sendDataToCloud',
            'hoverCompareCartesian',
            'hoverClosestCartesian',
            'select2d', 'lasso2d',
            'resetScale2d', 
            'autoScale2d',
            'zoomIn2d', 'zoomOut2d',
            'zoom2d', 'pan2d'
)

config(displaylogo = FALSE, modeBarButtonsToRemove= remove)

That’s a much cleaner hover-over. My settings leave the option to save a plot as a PNG. If you want to turn everything off there’s a much simplier config option displayModeBar = FALSE. There are some more options you can control in the modebar, here.

Other

If that’s not enough interactivity for you, you can also add drop down menus to change chart options on the fly, following these steps.

Leaflet

If you want to make an interactive map, the best way to go is to plot it in ggPlot and then apply the ggPlotly command. But, if you’re looking for a street map in particular, there’s a lot of extra functionality built into Leaflet.

The process is pretty straightforward:

  1. Create a new map instance using the leaflet() command

  2. Set the view of that map using setView() which takes the latitude and longitude of the center, and the zoom level

  3. Choose your map tiles. I have found this website useful for previewing the tiles.

  4. Add shapes, markers, and data to your map.

Here’s the code from my website to add a map to Encina Hall.

#https://rstudio.github.io/leaflet/

library(leaflet)

m <- leaflet() %>%
    setView(lat=37.427439, lng=-122.164757, zoom=14) %>% 
    addProviderTiles("Hydda.Full") %>% 
    addMarkers(lat=37.427439, lng=-122.164757, popup="Encina Hall")
m  # Print the map

You can also add shapes, shaded areas, and routes to the map.