rCharts¶
rCharts is an R package to create, customize and publish interactive javascript visualizations from R using a familiar lattice style plotting interface.
Quick Start¶
You can install rCharts from github using the devtools package
require(devtools)
install_github('rCharts', 'ramnathv')
The design philosophy behind rCharts is to make the process of creating, customizing and sharing interactive visualizations easy.
Create
rCharts uses a formula interface to specify plots, just like the lattice package. Here are a few examples you can try out in your R console.
require(rCharts)
## Example 1 Facetted Scatterplot
names(iris) = gsub("\\.", "", names(iris))
rPlot(SepalLength ~ SepalWidth | Species, data = iris, color = 'Species', type = 'point')
## Example 2 Facetted Barplot
hair_eye = as.data.frame(HairEyeColor)
rPlot(Freq ~ Hair | Eye, color = 'Eye', data = hair_eye, type = 'bar')
Customize
rCharts supports multiple javascript charting libraries, each with its own strengths. Each of these libraries has multiple customization options, most of which are supported within rCharts.
Share
rCharts allows you to share your visualization in multiple ways, as a standalone page, embedded in a shiny application, or embedded in a tutorial/blog post.
Publish to Gist/RPubs
names(iris) = gsub("\\.", "", names(iris))
r1 <- rPlot(SepalLength ~ SepalWidth | Species, data = iris,
color = 'Species', type = 'point')
r1$publish('Scatterplot', host = 'gist')
r1$publish('Scatterplot', host = 'rpubs')
Use with Shiny
rCharts is easy to embed into a Shiny application using the utility functions renderChart and showOutput. Here is an example of an rCharts Shiny App.
## server.r
require(rCharts)
shinyServer(function(input, output) {
output$myChart <- renderChart({
names(iris) = gsub("\\.", "", names(iris))
p1 <- rPlot(input$x, input$y, data = iris, color = "Species",
facet = "Species", type = 'point')
return(p1)
})
})
## ui.R
require(rCharts)
shinyUI(pageWithSidebar(
headerPanel("rCharts: Interactive Charts from R using polychart.js"),
sidebarPanel(
selectInput(inputId = "x",
label = "Choose X",
choices = c('SepalLength', 'SepalWidth', 'PetalLength', 'PetalWidth'),
selected = "SepalLength"),
selectInput(inputId = "y",
label = "Choose Y",
choices = c('SepalLength', 'SepalWidth', 'PetalLength', 'PetalWidth'),
selected = "SepalWidth")
),
mainPanel(
showOutput("myChart", "polycharts")
)
))
Credits¶
Most of the implementation in rCharts
is inspired by rHighcharts and rVega. I have reused some code from these packages verbatim, and would like to acknowledge the efforts of its author Thomas Reinholdsson, who has since merged his rHighcharts package into rCharts. I would also like to thank @timelyportfolio for adding Dimple JS to rCharts, as well as for his contagious enthusiasm, which has egged me on constantly.
License¶
rCharts is licensed under the MIT License. However, the JavaScript charting libraries that are included with this package are licensed under their own terms. All of them are free for non-commercial and commercial use, with the exception of Polychart and Highcharts, both of which require paid licenses for commercial use. For more details on the licensing terms, you can consult the License.md
file in each of the charting libraries.
See Also¶
There has been a lot of interest recently in creating packages that allow R users to make use of Javascript charting libraries.
- ggvis by RStudio
- clickme by Nacho Caballero
NVD3¶
hair_eye = as.data.frame(HairEyeColor)
p2 <- nPlot(Freq ~ Hair, group = 'Eye',
data = subset(hair_eye, Sex == "Female"),
type = 'multiBarChart'
)
p2$chart(color = c('brown', 'blue', '#594c26', 'green'))
p2
Morris¶
data(economics, package = "ggplot2")
econ <- transform(economics, date = as.character(date))
m1 <- mPlot(x = "date", y = c("psavert", "uempmed"), type = "Line", data = econ)
m1$set(pointSize = 0, lineWidth = 1)
m1
Highcharts¶
h1 <- hPlot(x = "Wr.Hnd", y = "NW.Hnd",
data = MASS::survey,
type = c("line", "bubble", "scatter"),
group = "Clap",
size = "Age"
)
h1
Rickshaw¶
usp = reshape2::melt(USPersonalExpenditure)
usp$Var2 <- as.numeric(as.POSIXct(paste0(usp$Var2, "-01-01")))
p4 <- Rickshaw$new()
p4$layer(value ~ Var2, group = "Var1", data = usp, type = "area")
p4$set(slider = TRUE)
p4
Libraries¶
rCharts supports multiple javascript visualization libraries
NVD3¶
NVD3 is an elegant visualization library that provides re-usable chart components based on d3.js. Here is an excerpt directly taken from the NVD3 website.
“This project is an attempt to build re-usable charts and chart components for d3.js without taking away the power that d3.js gives you. This is a very young collection of components, with the goal of keeping these components very customizeable, staying away from your standard cookie cutter solutions.”
Create¶
The NVD3 library supports most of the common chart types.
You can create an interactive plot making use of the NVD3 library using the nPlot()
function.
Argument | Type | Description |
---|---|---|
x | formula | A formula of the form y ~ x, with column names from the data frame. |
data | data frame | A data frame containing the data to be plotted |
type | string | The type of chart to plot |
group | string | Name of column based on which data should be grouped. |
Scatter Chart¶
p1 <- nPlot(mpg ~ wt, group = 'cyl', data = mtcars, type = 'scatterChart')
p1$xAxis(axisLabel = 'Weight')
p1
Multibar Chart¶
hair_eye = as.data.frame(HairEyeColor)
p2 <- nPlot(Freq ~ Hair, group = 'Eye',
data = subset(hair_eye, Sex == "Female"),
type = 'multiBarChart'
)
p2$chart(color = c('brown', 'blue', '#594c26', 'green'))
p2
Line Chart¶
data(economics, package = 'ggplot2')
p6 <- nPlot(uempmed ~ date, data = economics, type = 'lineChart')
p6
Line with Focus Chart¶
ecm <- reshape2::melt(
economics[,c('date', 'uempmed', 'psavert')],
id = 'date'
)
p7 <- nPlot(value ~ date, group = 'variable',
data = ecm,
type = 'lineWithFocusChart'
)
p7
Stacked Area Chart¶
dat <- data.frame(
t = rep(0:23, each = 4),
var = rep(LETTERS[1:4], 4),
val = round(runif(4*24,0,50))
)
p8 <- nPlot(val ~ t, group = 'var', data = dat,
type = 'stackedAreaChart', id = 'chart'
)
p8
Multi Chart¶
p12 <- nPlot(value ~ date, group = 'variable', data = ecm, type = 'multiChart')
p12$set(multi = list(
uempmed = list(type="area", yAxis=1),
psavert = list(type="line", yAxis=2)
))
p12$setTemplate(script = system.file(
"/libraries/nvd3/layouts/multiChart.html",
package = "rCharts"
))
p12
Tutorials¶
Visualizing Strikeouts¶
This tutorial explains in detail, how I used rCharts
to replicate this NY times interactive graphic on strikeouts in baseball. The end result can be seen here as a shiny
application.
Data¶
The first step is to get data on strikeouts by team across years. The NY Times graphic uses data scraped from baseball-reference, using the XML
package in R. However, I will be using data from the R package Lahman, which provides tables from Sean Lahman’s Baseball Database as a set of data frames.
The data processing step involves using the plyr package to create two data frames:
team_data
containingSOG
(strikeouts per game) byyearID
and teamname
league_data
containingSOG
by yearID averaged across the league.
require(Lahman) ; require(plyr); library(ascii)
dat = Teams[,c('yearID', 'name', 'G', 'SO')]
team_data = na.omit(transform(dat, SOG = round(SO/G, 2)))
league_data = ddply(team_data, .(yearID), summarize, SOG = mean(SOG))
ascii(head(team_data), type = 'rst')
yearID | name | G | SO | SOG | |
---|---|---|---|---|---|
1 | 1871.00 | Boston Red Stockings | 31.00 | 19.00 | 0.61 |
2 | 1871.00 | Chicago White Stockings | 28.00 | 22.00 | 0.79 |
3 | 1871.00 | Cleveland Forest Citys | 29.00 | 25.00 | 0.86 |
4 | 1871.00 | Fort Wayne Kekiongas | 19.00 | 9.00 | 0.47 |
5 | 1871.00 | New York Mutuals | 33.00 | 15.00 | 0.45 |
6 | 1871.00 | Philadelphia Athletics | 28.00 | 23.00 | 0.82 |
Charts¶
We will start by first creating a scatterplot of SOG by yearID across all teams. We use the rPlot function which uses the PolyChartsJS library to create interactive visualizations. The formula interface specifies the x and y variables, the data to use and the type of plot. We also specify a size and color argument to style the points. Finally, we pass a tooltip argument, which is a javascript function that overrides the default tooltip to display the information we require. You will see below the R code and the resulting chart.
require(rCharts)
p1 <- rPlot(SOG ~ yearID, data = team_data,
type = "point",
size = list(const = 2),
color = list(const = "#888"),
tooltip = "#! function(item){
return item.SOG + ' ' + item.name + ' ' + item.yearID
} !#"
)
p1
Now, we need to add a line plot of the average SOG
for the league by yearID
. We do this by adding a second layer to the chart, which copies the elements of the previous layer and overrides the data
, type, color
and tooltip
arguments. The R code is shown below and you will note that the resulting chart now shows a blue line chart corresponding to the league average SOG
.
p1$layer(data = league_data, type = 'line',
color = list(const = 'blue'), copy_layer = T, tooltip = NULL)
p1
Finally, we will overlay a line plot of SOG
by yearID
for a specific team name. Later, while building the shiny app, we will turn this into an input variable that a user can choose from a dropdown menu. We use the layer approach used earlier and this time override the data and color arguments so that the line plot for the team stands out from the league average.
myteam = "Boston Red Sox"
p1$layer(data = team_data[team_data$name == myteam,],
color = list(const = 'red'),
copy_layer = T)
p1$set(dom = 'chart3')
p1
Let us add a little more interactivity to the chart. To keep it simple, we will use handlers in PolychartJS to initiate an action when a user clicks on a point. The current handler is a simple one, which just displays the name of the team clicked on. If you are familiar with Javascript event handlers, the code should be self explanatory.
p2 <- p1$copy()
p2$setTemplate(afterScript = '
<script>
graph_chart3.addHandler(function(type, e) {
var data;
data = e.evtData;
if (type === "click") {
return alert("You clicked on the team: " + data.name["in"][0]);
}
});
</script>
')
p2
Application¶
Now it is time to convert this into a Shiny App. We will throw the data processing code into global.R so that it can be accessed both by ui.R and server.R. For the dropdown menu allowing users to choose a specific team, we will restrict the choices to only those which have data for more than 30 years. Accordingly, we have the following global.R.
## global.R
require(Lahman); require(plyr)
dat = Teams[,c('yearID', 'name', 'G', 'SO')]
team_data = na.omit(transform(dat, SOG = round(SO/G, 2)))
league_data = ddply(team_data, .(yearID), summarize, SOG = mean(SOG))
THRESHOLD = 30
team_appearances = count(team_data, .(name))
teams_in_menu = subset(team_appearances, freq > THRESHOLD)$name
For the UI, we will use a bootstrap page with controls being displayed in the sidebar. Shiny makes it really easy to create a page like this. See the annotated graphic below and the ui.R code that accompanies it to understand how the different pieces fit together.

We now need to write the server part of the shiny app. Thankfully, this is the easiest part, since it just involves wrapping the charting code inside renderChart and replacing user inputs to enable reactivity. We add a few more lines of code to set the height and title and remove the axis titles, since they are self explanatory.