Ggplotly: Make ggplot2 graphs into shareable D3 graphs

Ggplotly and Plotly's R API let you make ggplots, add py$ggplotly(), and get an interactive, shareable, online plot. Your plots are even drawn with D3. Let's make one, and then jump into why these technologies are special.

You can copy and paste these examples straight into your R environment and make the first graph in about 26 seconds (let me know if you find otherwise).

I. Getting Started

install.packages("devtools")
library(devtools)
install_github("plotly", "ropensci")

Install:

library(plotly)
## Loading required package: RCurl
## Loading required package: bitops
## Loading required package: RJSONIO
## Loading required package: ggplot2
library(ggplot2)

Sign up on Plot.ly or like this:

signup("new_username", "your_email@domain.com")

Use your account or our “RgraphingAPI” test account and key:

py <- plotly("RgraphingAPI", "ektgzomjbx")

II. Interactive graphs, in Plotly

First up, we'll draw a basic graph from the CO2 dataset.

a <- qplot(conc, uptake, data = CO2, colour = Type) + scale_colour_discrete(name = "")
py$ggplotly(a)

When you run the plot, it will call it in your browser. It will make a graph, visible at this URL:

https://plot.ly/~RgraphingAPI/1000/

We can also go in and see the data. I forked the graph, and shared the grid here:

https://plot.ly/~MattSundquist/1192

Plotly's goal is to be a unified online platform where you can make your plots, analyze and share data, and collaborate. Our dream is to be a GitHub for data, where you can share and find plots, data, and code.

Plotly is part of the rOpenSci project is creating packages that give you access to tools and data for science. And since every Plotly graph stores the data and the graph together, when you make and share Plotly graphs, you can share your data. Sharing your code, data, and graphs means your work can be reproducible and you can easily collaborate with others. You can also share all your work in a profile. Check out our R profile as an example:

https://plot.ly/~RgraphingAPI.

To help you collaborate, your can edit your plots and data with our R API, our GUI, or our APIs for Python, MATLAB, and Arduino. You control the privacy by setting world_readable to false or true, and can control your sharing.

Second, thanks to Aaron Gonzales for his examples.

ids <- factor(c("1.1", "2.1", "1.2", "2.2", "1.3", "2.3"))

values <- data.frame(id = ids, value = c(3, 3.1, 3.1, 3.2, 3.15, 3.5))

positions <- data.frame(id = rep(ids, each = 4), x = c(2, 1, 1.1, 2.2, 1, 0, 
    0.3, 1.1, 2.2, 1.1, 1.2, 2.5, 1.1, 0.3, 0.5, 1.2, 2.5, 1.2, 1.3, 2.7, 1.2, 
    0.5, 0.6, 1.3), y = c(-0.5, 0, 1, 0.5, 0, 0.5, 1.5, 1, 0.5, 1, 2.1, 1.7, 
    1, 1.5, 2.2, 2.1, 1.7, 2.1, 3.2, 2.8, 2.1, 2.2, 3.3, 3.2))

# Currently we need to manually merge the two together
datapoly <- merge(values, positions, by = c("id"))

b <- ggplot(datapoly, aes(x = x, y = y)) + geom_polygon(aes(fill = value, group = id))
py$ggplotly(b)

We'll run a few examples from an excellent tutorial by Toby Hocking, who is also writing ggplotly.

#' Generate data
data <- data.frame(x=rep(1:10, times=5), group = rep(1:5, each=10))
data$lt <- c("even", "odd")[(data$group%%2+1)] # linetype
data$group <- as.factor(data$group)
data$y <- rnorm(length(data$x), data$x, .5) + rep(rnorm(5, 0, 2), each=10)

d <- ggplot() + geom_line(data=data, aes(x=x, y=y, colour=group, group=group, linetype=group)) +
    ggtitle("geom_line + scale_linetype automatic")
py$ggplotly(d)

To draw points:

# Randomly generate some data
scatterdata <- data.frame(x=rnorm(100, 50, 15))
scatterdata$y <- with(scatterdata, runif(100, x-5, x+5))
scatterdata$xnew <- round(scatterdata$x/20)*20
scatterdata$xnew <- as.factor(scatterdata$xnew)
scatterdata$class <- factor(round(scatterdata$x/10)%%2, labels=c("high", "low"))
scatterdata$class4 <- factor(rowSums(sapply(quantile(scatterdata$x)+c(0,0,0,0,.1), function(i) scatterdata$x<i)), levels=1:4, labels=c("high", "medhigh", "medlow", "low"), ordered=TRUE)

e <- ggplot() + 
    geom_point(data=scatterdata, aes(x=xnew, y=y, colour=class, fill=class)) + 
    scale_colour_manual(values=c("#FF0000", "#0000FF")) + 
    scale_fill_manual(values=c("#FF0000", "#0000FF")) +
    ggtitle("Manual colour/fill scales")
py$ggplotly(e)

And more:

library(plyr)
scatterdata2 <- data.frame(x=rnorm(1000, 0, .5), y=rnorm(1000, 0, .5))
scatterdata2$quad <- c(3, 4, 2, 1)[with(scatterdata2, (3+sign(x)+2*sign(y))/2+1)]
scatterdata2$quad <- factor(scatterdata2$quad, labels=c("Q1", "Q2", "Q3", "Q4"), ordered=TRUE)
scatterdata2 <- ddply(scatterdata2, .(quad), transform, str=sqrt(x^2+y^2)/4)
scatterdata2.summary <- ddply(scatterdata2, .(quad), summarise, xmin=min(x), xmax=max(x), ymin=min(y), ymax=max(y), xmean=mean(x), ymean=mean(y))
f <- ggplot() + 
    geom_point(data=scatterdata2, aes(x=x, y=y, colour=quad, fill=quad, alpha=quad))+
    geom_point(data=scatterdata2, aes(x=x, y=y, colour=quad, fill=quad, 
                                      alpha=quad, clickSelects=quad, showSelected=quad)) +
    guides(colour = guide_legend(override.aes = list(alpha = 1)), 
           fill = guide_legend(override.aes = list(alpha = 1))) +
    scale_alpha_discrete(guide="none")+
    ggtitle("Discrete alpha")
py$ggplotly(f)

V. Conclusion

We're on GitHub. We welcome your thoughts, issues, and pull requests.