Coder Social home page Coder Social logo

rcharts's Introduction

rCharts

rCharts is an R package to create, customize and publish interactive javascript visualizations from R using a familiar lattice style plotting interface.

Installation

You can install rCharts from github using the devtools package

require(devtools)
install_github('ramnathv/rCharts')

Features

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. More documentation is underway on how to use rCharts with each of these libraries.

We will create our first chart using Polychart, a javascript charting library based on the grammar of graphics, and inspired by ggplot2.

r1 <- rPlot(mpg ~ wt | am + vs, data = mtcars, type = 'point', color = 'gear')
r1

polychart

There, we have our first embedded chart with nice tooltips! Let me add some interactivity to this chart now using javascript.

graph_chart1.addHandler(function(type, e){
  var data = e.evtData;
  if (type === 'click'){
    return alert("You clicked on car with mpg: " + data.mpg.in[0]);
  }
})

The next library we will be exploring is 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

morris

Hurray! There we have our second chart!


Next, I will demonstrate my all time favorite d3js library, NVD3, which produces amazing interactive visualizations with little customization.

hair_eye_male <- subset(as.data.frame(HairEyeColor), Sex == "Male")
n1 <- nPlot(Freq ~ Hair, group = "Eye", data = hair_eye_male, 
  type = 'multiBarChart')
n1

nvd3

See the interactivity that comes at zero cost!


The next library to demo would be xCharts, a slick looking charting library using d3js, made by TenXer.

require(reshape2)
uspexp <- melt(USPersonalExpenditure)
names(uspexp)[1:2] = c('category', 'year')
x1 <- xPlot(value ~ year, group = 'category', data = uspexp, 
  type = 'line-dotted')
x1

xchart

There is your xChart


h1 <- Highcharts$new()
h1$chart(type = "spline")
h1$series(data = c(1, 3, 2, 4, 5, 4, 6, 2, 3, 5, NA), dashStyle = "longdash")
h1$series(data = c(NA, 4, 1, 3, 4, 2, 9, 1, 2, 3, 4), dashStyle = "shortdot")
h1$legend(symbolWidth = 80)
h1

highcharts


map3 <- Leaflet$new()
map3$setView(c(51.505, -0.09), zoom = 13)
map3$marker(c(51.5, -0.09), bindPopup = "<p> Hi. I am a popup </p>")
map3$marker(c(51.495, -0.083), bindPopup = "<p> Hi. I am another popup </p>")
map3

leaflet


usp = reshape2::melt(USPersonalExpenditure)
p4 <- Rickshaw$new()
p4$layer(value ~ Var2, group = 'Var1', data = usp, type = 'area')
p4

rickshaw

Share

rCharts allows you to share your visualization in multiple ways, as a standalone page, embedded in a shiny application, or in a tutorial/blog post.

Standalone

You can publish your visualization as a standalone html page using the publish method. Here is an example. Currently, you can publish your chart as a gist or to 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')

Shiny Application

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')
    p1$addParams(dom = 'myChart')
    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")
  )
))

Blog Post

rCharts can also be embedded into an Rmd document using knit2html or in a blog post using slidify. Here are a few examples of tutorials written using rCharts and slidify.

  1. Parallel Coordinate Plots
  2. NY Times Graphics Tutorial

More in the rCharts website and the Gallery.

More

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.

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.

rcharts's People

Contributors

bbest avatar danielkrizian avatar grantbrown avatar kohske avatar mege avatar ramnathv avatar reinholdsson avatar rossilorenzo avatar smschauhan avatar timelyportfolio avatar victe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rcharts's Issues

Slidify rCharts integration and External Libraries

Here is a use case which motivates this idea. The rCharts_512Paths visualization by @timelyportfolio relies only on a 512paths lib folder and a few lines of R code. However, to get it working, I had to do the following:

  1. Copy 512paths to inst in rCharts.
  2. Copy 512paths as a widget to libraries/widgets in working directory or slidifyLibraries.

To encourage use of slidify and rCharts, a user should be able to do all of this by just specifying the path to the lib folder. I think this can be easily done within the R code.

p1 <- rCharts$new()
p1$field( 'lib', '512paths' )
p1$set( data = toJSONArray( data ) )
p1

Now lib is used in two ways

  1. determine path to the folder containing the library.
  2. adding a class to the div containing chartID.

One way to fix things is to treat lib as the actual path to the library. If nothing is found, then it can search the system library. A little bit of book-keeping is necessary to connect lib and lib_url, but that should be easy.

For it to integrate with slidify, more design changes are required. The key is to communicate with Slidify and add the necessary widgets. Now, this brings me to a bigger question as to how I can facilitate inter-package communication.

Maybe, environments is the solution. Slidify can create a special environment, that other packages can write to. This way, a widget can be automatically added while Slidify is run. This certainly requires more thought. Maybe, a question on SO?

Attempt to integrate with reactive.js

This is a cool tutorial showing how to use reactive.js a javascript library that supports reactivity (just like shiny) to control d3.js like charts.

It looks really easy to use, and might only require some book-keeping code to use with rCharts. A huge advantage of using reactive.js over shiny is that the application can be viewed on any server.

runExample does not work in Windows

I am guessing another Windows issue, but runExample does not work.

tempfile(pattern = '*.R')

[1] "C:\Users\KENT~1.TLE\AppData\Local\Temp\RtmpOswwy0*.R32c1e702e82"

Not sure if this messes other OSes but this changes fixes it.

tempfile( fileext = '.R')

Ideas on Documentation

I need to put some thought through designing a simple, yet elegant web page for rCharts. This issue here is mainly a stub for me to dump my thoughts on this subject.

Here is a laundry list of potential page types I need.

  1. Landing Page.
  2. Tutorial
  3. Gallery
  4. Example
  5. Blog
  6. Documentation
  7. Quick Start

sessionInfo from tmpl error

R version 2.15.3 (2013-03-01)
Platform: x86_64-w64-mingw32/x64 (64-bit)

locale:
[1] LC_COLLATE=English_United States.1252 LC_CTYPE=English_United States.1252
[3] LC_MONETARY=English_United States.1252 LC_NUMERIC=C
[5] LC_TIME=English_United States.1252

attached base packages:
[1] stats graphics grDevices utils datasets methods base

other attached packages:
[1] whisker_0.3-2 devtools_1.1 downloader_0.2.2 df2json_0.0.2 rjson_0.2.12
[6] clickme_0.1.0 reshape2_1.2.2 xtsExtra_0.0-1 xts_0.9-3 zoo_1.7-9
[11] rCharts_0.1.1 slidify_0.3.3

loaded via a namespace (and not attached):
[1] digest_0.6.3 evaluate_0.4.3 formatR_0.7 grid_2.15.3 httr_0.2
[6] knitr_1.2 lattice_0.20-15 markdown_0.5.4 memoise_0.1 parallel_2.15.3
[11] plyr_1.8 RCurl_1.95-4.1 stringr_0.6.2 tools_2.15.3 yaml_2.1.7

create_chart and $show(T) error

When I run create_chart or $show(T), I get the following error:

file association for 'C:\Users\KENT~1.TLE\AppData\Local\Temp\Rtmp4EKTH8\file2b7471735b47html' not available or invalid
Warning message:
running command 'open C:\Users\KENT~1.TLE\AppData\Local\Temp\Rtmp4EKTH8\file2b7471735b47html' had status 63 

It appears that I am losing a . in my file. I verified that the file exists and is just missing the . between file and extension. I'm not sure if this is a personal problem or possibly an error with Windows 7.

It appears to be with R tempfile.

> tempfile(fileext = "html")
[1] "C:\\Users\\KENT~1.TLE\\AppData\\Local\\Temp\\Rtmp4EKTH8\\file2b747baa1770html"
> tempfile(fileext = ".html")
[1] "C:\\Users\\KENT~1.TLE\\AppData\\Local\\Temp\\Rtmp4EKTH8\\file2b741a4f5d5d.html"

so the fix seems simple unless it affects behavior on other OSes.

Publishing as gist

I have implemented publishing as a gist using the Github API for basic authorization. One issue though is that my current workflow generates a new token every time I publish. I don't think this is desirable, as it results in many many tokens.

The solution I think is to save a token the first time it is generated, and use it as long as it is available and works. If rCharts can't find it, a new token will be generated.

So the natural question is where to save the token in a way that is safe and persists across sessions.

Add visual tests for all libraries

Right now I have examples.R which tests different type of charts. However, I need to do this more systematically with a test suite that tests different aspects. Here is an example for MorrisJS

dat = subset(haireye, Sex == "Female")

## test that labels default to group names when not provided
p2 <- mPlot(Freq ~ Eye, group = "Hair", data = dat, type = "Bar")
p2$show(T)

## test that label argument is respected when explicitly provided
p3 <- mPlot(Freq ~ Eye, group = "Hair", data = dat, type = "Bar", 
  labels = letters[1:4])
p3$show(T)

Mimic Highchart Polar

Hi,
I try to understand how programmatic approach work starting from trying to mimic polar graph for HighCharts (http://www.highcharts.com/demo/polar-spider)
I can see the huge refactoring work to gather all JS libraries into one framework and see the rPlot function.
Though, with the current state of documentation, I don't see how to start from rPlot.
So I started to investigate directly to HighChart layer and tried:

x=data.frame("S1"=c(9,8,9,1,3),"S2"=c(7,3,7,6,4))
rownames(x)=paste("factor",rownames(x))

a=rCharts:::Highcharts$new()
a$addParams(width = 550)
a$chart(type='line',polar=TRUE)
a$pane(size='80%')
a$title(text='Polarize-It',x=-80)
a$xAxis(categories=rownames(x),tickmarkPlacement='on',lineWidth=0)
a$yAxis(gridLineInterpolation='polygon',lineWidth=0,min=0)
a$data(x,pointPlacement='on')
a$printChart("testPolar")

Error in file(con, "r") : invalid 'description' argument

Can you help: what should be corrected?

Thank you,

Eric

PS: no pressure but I am really working on your sample gallery

Fix getLayer

Here is an example that does not work

p2 <- rPlot(~ time, color = 'sex', data = tips, type = 'bar')

The problem is that when the y variable is missing, the data frame is run through count to compute the frequency automatically. It does not take into account other aesthetics like color, facet, etc.

Figure out how to handle CDN assets

I see two issues of hotlinking directly to unversioned assets.

  1. The nosniff policy is going to break raw links.
  2. Modifications at the library end will break things, and leave me with no control.

Solution.

  1. Hotlink only to CDN hosted assets that are versioned.
  2. Serve other assets either from Google Code or Github gh-pages.

This is easy to fix, since I only need to modify the CDN links to assets. Once I make a call on where to host stuff, this should be relatively easy.

Figure out how to handle JS functions in payload

Many of the JS charting libraries use functions to handle formatting and other interactions. Now, converting R objects to a payload invokes toJSON which transforms everything into JSON objects, which are quoted.

I had several ideas on how to handle this.

  1. Use a post-fix function on the payload that scans for appearances of "function(...){...}" and removes the quotes using regex manipulation.
  2. Add a addFunction method to the rCharts class, and return an object called jsFunctions in the payload, which is a list of functions. These functions can be referred to in the main payload, however I would still face the issue of having to unquote those objects.
  3. Use eval on function objects.

Revisit layouts

Currently, every JS charting library needs three files:

  1. config.yml
  2. layouts/chart.html
  3. layouts/script.html

It should be possible to reduce them to two files: config.yml and layouts/chart.html with the full HTML being generated by combining the two using a generic template common to all charting libraries.

The other issue to worry about is specification of CDN vs using assets locally.

Log Calls within Reference Class

I thought it would be cool if the reference class could log all the calls made, thereby making it easy to recreate a plot. @hadley provided a concise answer on SO and here is a proof-of-concept making use of the idea.

The variable foo$calls contains a list of all the calls made. Since, I don't want the function to log calls when an xPlot function is called, I will need an extra flag argument, that defaults to TRUE, but can be set to FALSE, to prevent logging of these calls inside the xPlot function.

This is just a proof-of-concept and I need to make sure it is robust enough before pushing it out.

Foo <- setRefClass('Foo', fields = list(params = 'list', calls = 'list'), 
    methods = list(
  bar1 = function(...){
    params$bar1 <<- list(...)
    calls <<- c(calls, list(match.call()))
  },
  bar2 = function(...){
    params$bar2 <<- list(...)
    calls <<- c(calls, list(match.call()))
  }
))

foo = Foo$new()
foo$bar1(x = 1, y = 2)
foo$bar2(x = 1, y = 4)

Figure out a way to keep rCharts libraries updated

I want to use the same strategy I am using with SlidifyLibraries.

  1. Use giternal to sync repo with slidifyLibraries/libraries.
  2. Add layouts and config.yml to repo and commit changes.
  3. Add script to makefile that will copy files to slidifyLibraries/inst/libraries.

The key step that messes me up is that I tend to fiddle around with config.yml and layouts in slidifyLibraries/inst/libraries. This renders the copy in the main repo outdated and as a result running the makefile might leave me hanging with an older version of these files.

I need to add a note to clean up slidifyLibraries by going through the timestamps on the files so that I am using the most recent copy of all files.

Switch from rjson to RJSONIO

The use case is when I want to pass JS objects in my JSON payload. My current approach is to enclose JS objects between #! and !# tags, and use a regular expression to remove the quotes. Here is an example.

x = list(tickFormat = "#! function(d) {
  return d3.time.format('%Y-%m-%d')(new Date(d))
} !#"

I have a function toObj that destringifies contents within special markup tags.

toObj <- function(x){
  gsub('\"#!(.*)!#\"', "\\1", x)
}

So essentially, I would do something like toObj(toJSON(x)). There are three cases.

The first case is what I am doing now, using rjson::toJSON

cat(toObj(rjson::toJSON(x)))
{"tickFormat": function(d) {\n  return d3.time.format('%Y-%m-%d')(new Date(d))\n} }

The second case is using RJSONIO::toJSON, but not invoking the .escapeEscapes option.

cat(toObj(RJSONIO::toJSON(x)))
{
 "tickFormat":  function(d) {\n  return d3.time.format('%Y-%m-%d')(new Date(d))\n}  
}

If I use the .escapeEscapes = F option in RJSONIO::toJSON, I get exactly what I want.

{
 "tickFormat":  function(d) {
  return d3.time.format('%Y-%m-%d')(new Date(d))
}  
}

So, I think it makes sense to switch to RJSONIO.

Nice Examples of Tutorials

This here is a great example of how to do a tutorial explaining the charting functions of a library. I can create a slidify layout that captures this flow and use it to create tutorials for each JS library I include.

For starters, it would be useful to recreate the tutorial for Rickshaw using rCharts, which would also help me implement functionality that is currently dormant.

Another nice example for Sidebar: http://www.chartjs.org/docs/

Refactoring To Do

  • Move common portions of the initialize method to the main rCharts class, and use callSuper() in the individual chart classes.
  • Figure out if users should be allowed to set width and height of plot from within the *Plot function.

A question that remains is whether or not to allow the users to set width and height of the plot from within the *Plot function. A case in favor is that most plots should be single line R commands and width and height of a plot are important components.

params <<- list(
  dom   = basename(tempfile('chart')),
  width  = getOption('RCHART_WIDTH', 700), 
  height = getOption('RCHART_HEIGHT', 300)
)

Example of using callSuper to override initialization inside child classes.

Class1 = setRefClass('Class1', fields = list(params = 'list'), methods = list(
  initialize = function(){
    params <<- list(x = 1, y = 2)
  }  
))

Class2 = setRefClass('Class2', fields = list(params = 'list'), contains = 'Class1', 
     methods = list(
  initialize = function(){
    callSuper()
    params <<- modifyList(params, list(x = 3))
  }  
))

Major Refactoring

One important refactoring that remains to be done is consistency in terms of names used. Right now the code base is a mish-mash of camelcase, snakecase, and allcaps. I need to adhere to some kind of a style guide here, before the code base explodes into a nightmare.

This requires me to do the following:

  1. Choose a coding style guide.
  2. Revisit variable and method names.
  3. Modify slowly and test at every change.

replicate examples given by js libraries

Another good test would be to replicate the examples provided in the libraries. I started on polycharts.

polychart.js examples in rCharts

Dow Jones (Simple Line)

require(quantmod)
require(reshape2)
require(rCharts)

DJIA <- na.omit(getSymbols("DJIA",src='FRED',auto.assign=FALSE)["2012-12-04::2013-03-10"])

xtsMelt <- function(xtsData,metric,names=NULL){
  df <- data.frame(index(xtsData),coredata(xtsData),stringsAsFactors=FALSE)
  df.melt <- melt(df,id.vars=1)
  df.melt <- data.frame(df.melt,rep(metric,NROW(df.melt)))
  #little unnecessary housekeeping
  df.melt <- df.melt[,c(1,2,4,3)]
  if(is.null(names)) {
    colnames(df.melt) <- c("date","indexname","metric","value")
  } else {colnames(df.melt) <- names}
  df.melt[,1]<- as.Date(df.melt[,1])
  return(df.melt)
}

DJIA.melt <- xtsMelt(DJIA,"price",names=c("Date","Index","Metric","Close"))
DJIA.melt[,1] <- format(DJIA.melt[,1],"%m/%d/%Y")

p1 <- rPlot(Close ~ Date, data = DJIA.melt,
            type="line",
            size=list(const=3))
p1$guides(x=list(numticks=10),y=list(min=12000,max=15000)) 
p1$set(title = "Dow Jones Daily Closing Value")
p1$show(F)

Dow Jones (Auto Updating)

Browser Shares (Multiple Lines)

browsershare <- read.csv("http://gs.statcounter.com/chart.php?statType_hidden=browser&region_hidden=ww&granularity=monthly&statType=Browser&region=Worldwide&fromMonthYear=2008-07&toMonthYear=2013-03&csv=1")
browsershare.melt <- melt(browsershare,id.vars=1)
colnames(browsershare.melt)[c(2,3)] <- c("Browser","Share")
p3 <- rPlot(Share ~ Date, color = "Browser",
            data=browsershare.melt,
            size=list(const=3),
            type="line")
p3$set(title="Browser Shares Over Time")
p3$show()

Operating Systems Shares Area

osshare <- read.csv("http://gs.statcounter.com/chart.php?statType_hidden=os&region_hidden=ww&granularity=monthly&statType=Operating%20System&region=Worldwide&fromMonthYear=2008-07&toMonthYear=2013-03&csv=1",stringsAsFactors=FALSE)
#if we wanted to sort by last value
#osshare <- osshare[,c(1,order(last(osshare[,-1]),decreasing=TRUE)+1)]
#osshare.melt <- read.csv("http://www.polychartjs.com/s/data/OSStatistics.csv")
osshare.melt <- reshape2::melt(osshare,id.vars=1)
colnames(osshare.melt)[c(2,3)] <- c("OS","Share")

p4 <- rPlot(y="Share",x="Date", color = "OS",  #could do Share ~ Date
            data=osshare.melt,
            size=list(const=3),
            opacity=list(const=0.7),
            type="area",
            height=500)
#demonstrate how we can change axis and legend titles
p4$guides(color=list(numticks=10,title="Oper System"),y=list(title="Market Share"))
p4$set(title="OS Market Shares Over Time")
p4$show()

Iris Flower Scatter Plot

data(iris)
colnames(iris) <- sapply(colnames(iris), FUN=gsub, pattern="\\.", replacement="")
p5 <- rPlot(SepalWidth ~ SepalLength, data = iris, color = "Species", type="point", height=400)
#again match polychartjs example exactly to show how we can change axis and legend titles
p5$guides(color=list(title="Category"),y=list(title="sepalWidth"),x=list(title="sepalLength"))
p5$set(title="Iris Flowers")
p5$html()
p5$show()

Bubble Chart (Animated)

LOTR Box Office Gross

jsondata = data.frame(
    c("The Fellowship of the Ring","The Two Towers","The Return of the King","The Hobbit"),
    c(871530000, 926047000, 1119929000, 949541000)
)
colnames(jsondata) <- c("movie","gross")
p7 <- rPlot(gross ~ movie, data = jsondata, type = "bar", color=list(const="darkgreen"))
p7$set(title = "Lord of the Rings Box Office Gross")
p7$html()
p7$show()

Histogram of Heights (Histogram)

names = c('Joe', 'Jay', 'Jen', 'Jane', 'John', 'Jone', 'Jake', 'Jule', 'Jack')
height = c(1.62, 1.63, 1.71, 1.66, 1.79, 1.58, 1.55, 1.62, 1.72) #actually error in example, 1.63)
data = data.frame(names,height)
p8 <- rPlot(x="bin(height,0.05)", y="count(names)", data=data, type="bar")
p8$guides(x=list(title="Height in Meters"), y=list(title="Density"))
p8$set(title = "Histogram of Heights")
p8$html()
p8$show()

Highest Paid Athletes (Flipped)

jsondata = data.frame(rbind(
    c('Floyd Mayweather', 85000000, 'Boxing'), 
    c('Manny Pacquaio', 62000000, 'Boxing'), 
    c('Tiger Woods', 59400000, 'Golf'), 
    c('LeBron James', 53000000, 'Basketball'), 
    c('Roger Federer', 52700000, 'Tennis'), 
    c('Kopaye Bryant', 52300000, 'Basketball'), 
    c('Phil Mickelson', 47800000, 'Golf'), 
    c('David Beckham', 46000000, 'Soccer'), 
    c('Cristiano Ronaldo', 42500000, 'Soccer'), 
    c('Peyton Manning', 42400000, 'Football'))
)
colnames(jsondata) <- c("name","pay","sport")
p9 <- rPlot(x = list(var="name", sort="pay"), y = "pay", data = jsondata, color = "sport",type = "bar" )
p9$guides(y = list(title = "Athlete Pay (in $)"), x = list(title = "Name of Athlete", numticks = 10), color = list(title = "Type of Sport"))
p9$coord(type = "cartesian", flip = "true")
p9$set(title= "Top 10 Highest Paid Athletes 2012")
p9$html()
cat(p9$render())
p9$show()

Sales Funnel (Stacking)

data = data.frame(list(
    segment=c(
        "FirstTime", "FirstTime", "FirstTime", "Return", "Return", "Return",
        "Sale", "Sale", "Sale"
    ),
    source= c(
        "Referral", "LinkedIn", "Cold Call","Referral", "LinkedIn", "Cold Call",
        "Referral", "LinkedIn", "Cold Call"
    ),
    value= c(10,15,20,5,10,18,3,5,8)
))

p10 <- rPlot(x = list(var = "segment", sort = "sum(value)", desc = "true"),
             y = "value",
             data = data,
             color = "source",
             type = "bar",
             height = 200,
             width = 720)
p10$guides(x = list(renderLine = "false", renderTick = "false", renderLabel = "true", renderGrid = "false"),
           y = list(position = "none"))
p10$coord(type = "cartesian", flip = "true")
p10$set(title = "Sales Funnel")
p10$show()

Department Salaries (Dodging)

data = list(
    names = c('Joe', 'Jay', 'Jessica', 'Mayfield', 'Candice', 'Alice'),
    department = c('Sales', 'Sales', 'IT', 'IT', 'HR', 'HR'),
    salary = c(100000, 98000, 110000, 50000, 55000, 80000)
  )
p11 <- rPlot(salary ~ department, color = 'names', data = data, type = "bar", position = "dodge")
p11$set(title = "Department Salaries")
p11$show()

Favourite Pets (Simple)

data = list(
    name=c('Lisa', 'Samson', 'Fravic', 'Zach', 'Raymond', 'Tim'),
    pet=c('cat', 'dog', 'cat', 'cat', 'dog', 'none')
)
p12 <- rPlot(y = "count(name)", x="pet", color="pet", data = data, type = "bar")
p12$coord(type="polar")
p12$guides(x = list(position = "none", padding = 0), y = list(position = "none"))
p12$show()

Favourite Pets (Animating)

p13

Volunteer Requirements (Facet)

data=data.frame(
        c( "Grade 9",  10,  'Yes'),
        c( "Grade 9",  90,  'No'),
        c( "Grade 10",  40,  'Yes'),
        c( "Grade 10",  60,  'No'),
        c( "Grade 11",  70,  'Yes'),
        c( "Grade 11",  30,  'No'),
        c( "Grade 12",  90,  'Yes'),
        c( "Grade 12",  10,  'No')
)
colnames(data) <- c("grade","percent","completed")

p14 <- rPlot(width = 720, height = 230,
             y = "percent", color = "completed", data = data)
p14$guides(x=list(position="none", padding=0),
           y=list(position="none"),
           color(scale = 'function(value) {return value === 'Yes' ? "#62bf9c" : "#DDD"'))
p14$coord(type="polar")
p14$facet(type="wrap", var=list(grade), cols=4, formatter='function(index){return index.grade}')
p14$set(title = "Percent of Students Completing Volunteer Requirement")
p14$show()

Boxplot

## Use InsectSprays Data since Polychart Example is Fake Data
data(InsectSprays)
#boxplot(count~spray, data=InsectSprays, col="lightgray")
p15 <- rPlot(width=720,
             x = "spray",
             y = "box(count)",
             data = InsectSprays,
             type = "box")
p15$guides(x=list(min=0, max=110))
p15

Iris Flower Tile Plot (Tile, Binning)

data(iris)
colnames(iris) <- sapply(colnames(iris), FUN=gsub, pattern="\\.", replacement="")
p16 <- rPlot(height = 400,
             width = 720,
             x = "bin(SepalLength, 1)",
             y = "bin(SepalWidth, 0.5)",
             color = "mean(PetalWidth)",
             data = iris,
             type = "tile")
p16$guides(color = list(scale = list(type="gradient", lower = "#EEE", upper = "#a23")))
p16$facet(type="wrap",var="Species" ) #,formatter='function(object) { return object.category }')
p16$set(title = "Iris Flowers")
p16

Population (Interactive)

If we can create this one, we know we can do almost anything

p17

Iris Flower Facetted Plot

data(iris)
colnames(iris) <- sapply(colnames(iris), FUN=gsub, pattern="\\.", replacement="")
p18 <- rPlot(width = 720,
             height = 300,
             x = "SepalLength",
             y = "SepalWidth",
             color = "Species",
             data = iris,
             type = "point")
p18$facet(type = "wrap", var = "Species")
p18$set(title = "Iris Flowers")
p18

pass meta to polycharts

can we add the ability to pass meta to polycharts? I believe it is fairly easy by changing the layout chart.html from

el.data = polyjs.data(el.data)

to

 el.data = polyjs.data(el.data, el.meta)

Check out present.js by Michael Bostock

Here is the source and the slides.

The basic idea is to use a separate html for each slide. It is ideal for showcasing rCharts, since every slide can be a standalone chart. It should be fairly easy to set this up using a template and some ideas from slidify.

Think of making static = T the default for show

I am thinking I should make static = T the default for the show method. The idea is that it is annoying to have to close the shiny server after every call to view the chart.

My earlier rationale to use static = F was directed at cases where the data is in an external JSON file and has to be read in using AJAX, which will work only with a server. However, currently, data is inline in the HTML, so a server is really not required.

I could control the static variable based on whether a server is required or not, when I implement the external data file idea referred to in the issues list here.

error with new publish

I get this now when I publish() after the user and pwd request.

Error in post_gist(gist) : could not find function "POST"

Make chart types consistent across libraries

I think it would be good to make chart types consistent across libraries. This can be achieved using a combination of a translation dictionary and guess work based on the dataset.

For example type = "bar" for NVD3 libraries should be interpreted as discreteBarChart if there is no grouping variable and as multiBarChart if there is a grouping variable. Similarly, type = "point" should become scatterChart etc.

investigate best method of handling dates as x with various libraries

Each javascript library seems to like dates as x in a different way. I wanted to document the behavior and then explore how rCharts should handle.

nvd3 fairly agnostic but rCharts provides x in a difficult form

.x(function(d) { return d[opts.x] })

which means we cannot parse here like this

 .x(function(d)  { return new Date(d)); }

or

 .x(function(d)  { return d3.time.format("%Y-%m-%d").parse(d); }

. Rather we format the date through a function call like this if we converted the date to milliseconds since 1970-01-01. We could really provide any date format and just adjust the function provided to the xAxis.

edhec.melt$date <- as.double(as.POSIXct(as.Date(edhec.melt$date),origin="1970-01-01")) * 1000
....

 chart.xAxis
  .tickFormat(function(d) {return d3.time.format("%Y-%m-%d")(new Date(d));})

polycharts likes %Y-%m-%d

The convert is easy, but polycharts does not seem to handle the date in the tooltip hover, only in the x axis.

managers.melt$date <- format(managers.melt$date,"%Y-%m-%d") 

Rickshaw likes seconds since 1970-01-01 or Unix time

rCharts implementation is not complete but Rickshaw seems to handle this universally.

edhec.melt$date <- as.double(as.POSIXct(as.Date(edhec.melt$date),origin="1970-01-01"))

Morris likes %Y-%m-%d like polycharts and seems to handle really well

managers.melt$date <- format(managers.melt$date,"%Y-%m-%d") 

I have not yet explored date handling in xCharts or Highcharts, but will as their support.

rCharts responsibility in handling dates

The question is

  1. Should rCharts automatically handle dates to prevent users from having to convert dates into each specific format?

clickme and rCharts integration

@nachocab will be the most helpful in this discussion, but I know he is buried in PHD stuff currently. I'll try to comment based on my own understanding of the spirit of clickme. In terms of create_chart, this almost replaces clickme for this limited functionality in that

 {{ create_chart(file.R) }} 

could be the entire template.Rmd. This might be still be in the spirit of clickme if you added the ability to pass parameters in create_chart like

{{ create_chart(file.R, {{opts$data}} ) }}

but I think is is a stretch.

Rather I think the more useful function to integrate clickme and rCharts is the method

$printChart()
$html()

as this allows us to include the div+script or the script in a template.Rmd through a {{ functiontorun_rCharts(opts) }} type call. I will work on a minimal example and hope to post in the next 30 minutes.

Embedding an rPlot in Wordpress.org fails

I cannot make a plot with rCharts work in a self-hosted Wordpress installation blog work.

I have included the following before the </head>
<script 
  src="https://raw.github.com/Polychart/polychart2/develop/polychart2.standalone.js">
</script>
<style>
    .rChart {
      display: block;
      margin-left: auto; 
      margin-right: auto;
      width: 900px;
      height: 500px;
    }  
 </style>

and then I only replicated a graph of your example in the body of the post.

Pie and Donut Charts in Polycharts

As much as I hate pie charts and donut charts because a bar chart can convey the same idea more succinctly, they do have some visual appeal, and provide some piazzaz to an otherwise boring infodeck.

Here is some code showing the construction of a faceted pie chart in PolychartJS

var data = polyjs.data({
    data: [
        {grade: "Grade 9", percent: 10, completed: 'Yes'},
        {grade: "Grade 9", percent: 90, completed: 'No'},
        {grade: "Grade 10", percent: 40, completed: 'Yes'},
        {grade: "Grade 10", percent: 60, completed: 'No'},
        {grade: "Grade 11", percent: 70, completed: 'Yes'},
        {grade: "Grade 11", percent: 30, completed: 'No'},
        {grade: "Grade 12", percent: 90, completed: 'Yes'},
        {grade: "Grade 12", percent: 10, completed: 'No'}
    ],
    meta: {
      grade: { type: 'cat' },
      percent: { type: 'num' },
      completed: { type: 'cat' }
    }
});
polyjs.chart({
    title: 'Percent of Students Completing Volunteer Requirement',
    dom: 'chart',
    width: 720,
    height: 230,
    layer: {
        data: data,
        type: 'bar',
        y: 'percent',
        color: 'completed'
    },
    guides: {
        x: {position: 'none', padding: 0},
        y: {position: 'none'},
        color: {
            scale: function(value) {
                return value === 'Yes' ? '#62bf9c' : '#DDD';
            }
        }
    },
    coord: {
        type: 'polar'
    },
    facet: {
        type: 'wrap',
        'var': 'grade',
        cols: 4,
        formatter: function(index) {
            return index.grade;
        }
    }
});

Replicate figures from R Cookbook Graphs

The best way to provide examples is to relate them to something users understand. Given the popularity of ggplot2, it makes complete sense to replicate the plots here on the R Cookbook.

This would also help me tweak the UI for PolyCharts, since it is essentially built on the Grammar of Graphics approach. The idea would be to keep the UI as close as possible to ggplot2, so that users can easily adopt the same in their workflows.

polycharts pie does not require x and rCharts always requires x

When replicating http://www.polychartjs.com/demo?favourite_pet, I realized that no x is a potential scenario for polycharts when doing a pie chart. As far as I can tell x is required by rCharts. I tried to hack around it but could not find a good solution.

code to replicate:

data = list(
    name=c('Lisa', 'Samson', 'Fravic', 'Zach', 'Raymond', 'Tim'),
    pet=c('cat', 'dog', 'cat', 'cat', 'dog', 'none')
)
p12 <- rPlot(y = "count(name)", color="pet", data = data, type = "bar")
p12$coord(type="polar")
p12$guides(x = list(position = "none", padding = 0), y = list(position = "none"))
p12$show()

sample examples from today; really a blog post when issues are resolved and rCharts is deemed ready

Performance Summary with rCharts

Of all the very useful functions in the R PerformanceAnalytics package, I would guess that charts.PerformanceSummary is probably the most used. I spot in the wild almost daily and use it myself often hourly. In my post plot.xts is wonderful, I recreated it using the new xtsExtra package. While I like that result, a d3 or other javascript version would provide a very helpful level of interactivity.

rCharts to the Rescue

rCharts is still very early in development, but given the author's wonderful slidify package and very conscientious efforts, I do not hesitate to go ahead and put it to use. So far, rCharts provides a R lattice-like interface for NVD3, polychart2, highcharts, morris, and incomplete xcharts. Let's test it out by creating a basic charts.PerformanceSummary with rCharts polycharts.

Example 1 Polychart

biggest issue I have is what I think is the inability to do lattice scale relation="free"
I guess the best way around this if it really is a limitation
is to create 2 plots much like the http://www.polychartjs.com/demo?interactive example
however I need to make sure this is even possible in R

I also am having trouble getting the tooltips to properly display the date
imagine this is fairly easy and I am just missing it.

#uncomment these if you have not installed rCharts and you are comfortable using a development package
#require(devtools)
#install_github('rCharts', 'ramnathv')

require(PerformanceAnalytics)
require(rCharts)

data(managers)

managers.cumul <- cumprod(1+managers[,c(1,8,9)])
managers.drawdown <- Drawdowns(managers[,c(1,8,9)])

xtsMelt <- function(xtsData,metric){
  df <- data.frame(index(xtsData),coredata(xtsData),stringsAsFactors=FALSE)
  df.melt <- melt(df,id.vars=1)
  df.melt <- data.frame(df.melt,rep(metric,NROW(df.melt)))
  #little unnecessary housekeeping
  df.melt <- df.melt[,c(1,2,4,3)]
  colnames(df.melt) <- c("date","indexname","metric","value")
  df.melt$date <- as.Date(df.melt$date)
  return(df.melt)
}

managers.melt <- rbind(xtsMelt(managers.cumul,"CumulGrowth"),xtsMelt(managers.drawdown,"Drawdown"))

managers.melt$metric <- factor(managers.melt$metric,levels=c("Drawdown","CumulGrowth"))

xyplot(value~date|metric,groups=indexname,data=managers.melt,
       type="l",
       layout=c(1,2),
       scales=list(x=list(tck=c(1,0)),y=list(relation="free")),
       xlab=NULL, ylab=NULL)

#remove troublesome . using modified method from this Stack Overflow
#http://stackoverflow.com/questions/2851015/convert-data-frame-columns-from-factors-to-characters
i <- sapply(managers.melt, is.factor)
managers.melt[i] <- lapply(managers.melt[i], gsub, pattern="\\.", replacement="")
#get date as text
managers.melt$date <- format(managers.melt$date,"%Y-%m-%d")  

p1 <- rPlot(value ~ date, data = managers.melt, color = 'indexname', type = 'point', size=list(const=1), height = 500) 
#p1$set( verticalSpacing =  25 )
p1$set( legendPosition = "top" )
p1$facet(type= "wrap",var="metric",cols=1,formatter="function(object) {return object.metric;}")
p1$html()
cat(p1$render())
p1$show()

Example 1 NVD3

biggest issue is the lack of facetting which will also require combining two separate charts
to accomplish the simultaneous viewing of CumulGrowth and Drawdown
using two y scales does not work in this instance unfortunately

#uncomment these if you have not installed rCharts and you are comfortable using a development package
#require(devtools)
#install_github('rCharts', 'ramnathv')

require(PerformanceAnalytics)
require(rCharts)

data(managers)

managers.cumul <- cumprod(1+managers[,c(1,8,9)])
managers.drawdown <- Drawdowns(managers[,c(1,8,9)])

xtsMelt <- function(xtsData,metric){
  df <- data.frame(index(xtsData),coredata(xtsData),stringsAsFactors=FALSE)
  df.melt <- melt(df,id.vars=1)
  df.melt <- data.frame(df.melt,rep(metric,NROW(df.melt)))
  #little unnecessary housekeeping
  df.melt <- df.melt[,c(1,2,4,3)]
  colnames(df.melt) <- c("date","indexname","metric","value")
  df.melt$date <- as.Date(df.melt$date)
  return(df.melt)
}

managers.melt <- rbind(xtsMelt(managers.cumul,"CumulGrowth"),xtsMelt(managers.drawdown,"Drawdown"))

managers.melt$metric <- factor(managers.melt$metric,levels=c("Drawdown","CumulGrowth"))

xyplot(value~date|metric,groups=indexname,data=managers.melt,
       type="l",
       layout=c(1,2),
       scales=list(x=list(tck=c(1,0)),y=list(relation="free")),
       xlab=NULL, ylab=NULL)

#remove troublesome . using modified method from this Stack Overflow
#http://stackoverflow.com/questions/2851015/convert-data-frame-columns-from-factors-to-characters
i <- sapply(managers.melt, is.factor)
managers.melt[i] <- lapply(managers.melt[i], gsub, pattern="\\.", replacement="")


n1 <- nvd3Plot(value ~ date,
               group = 'indexname',
               data = managers.melt[which(managers.melt$metric=="CumulGrowth"),],
               type = 'lineChart')
#n1$yAxis(tickFormat='d3.format(\",.2f\")',replace=T)
n1$show()

rChartApp broken?

It appears to me that http://glimmer.rstudio.com/ramnathv/rChartApp/ seems to be broken at the moment.

As well I can't get the "rCharts: Interactive Charts from R using polychart.js" example working with your server.r and ui.r, but I really don't know what I'm doing. I end up with:
Error in if (!grepl("^[a-z][a-z0-9-_]*$", prefix, ignore.case = TRUE, :
argument is of length zero

traceback()
25: addResourcePath(lib, system.file(lib, package = package))
24: singleton(addResourcePath(lib, system.file(lib, package = package)))
23: withCallingHandlers(expr, message = function(c) invokeRestart("muffleMessage"))
22: suppressMessages(singleton(addResourcePath(lib, system.file(lib,
package = package)))) at showOutput.R#25
21: getAssets(lib, package)
20: tagList(getAssets(lib, package))
19: tag("div", list(...))

Figure out how to make charts responsive

One of the nice things about the charts generated by datawrapper is that they are responsive, which makes them easy to embed on any site. They also come with a nice fullscreen button, which allows a user to view the chart fullscreen.

I need to figure out if there is an easy way to make the charts generated by rCharts responsive.

Issues with moving to a common template rChart.html

So far, the following libraries work great.

  • Polycharts
  • NVD3
  • MorrisJS

Rickshaw uses a different div for each component of the plot. This makes things a little trickier in rChart.html. One idea is to initialize it in the master rCharts class (as say chartDiv), and override it in the child classes. This way, only those libraries, which required a different setup like Rickshaw, will need to redefine it.

This is straightforward to implement, but requires careful work. So, I will table it till I sort out other refactoring issues.

<div id="{{{ params.dom }}}" class='Rickshaw'></div>
<div id="yAxis{{{ params.dom }}}" class='Rickshaw'></div>

class nvd3 for all

in the rCharts object render reads

chartDiv = sprintf("<div id='%s' class='rChart nvd3Plot'></div>", chartId)

now with all the types should it just be rChart, or should there be logic to fill based on javascript library?

Create custom theme using Swatchmaker

I like the Cosmo theme on Bootswatch, but would like to customize the colors. The best way to do this is to use SwatchMaker

  1. Copy the less file from Cosmo.
  2. Make changes to the colors.
  3. Run make swatch to create css files for custom Cosmo theme.

TODO

  • test it without any modifications to cosmo
  • test after making modifications to cosmo
  • figure out a way to automate customization further

Add documentation about save, show and printChart

I need to make it clear to users that there are four ways to display an rChart.

p1 <- rPlot(mpg ~ cyl, data = mtcars, type = 'point')
p1                             # opens plot using shiny server. sames as p1$show(static = F)
p1$show(static = T)    # opens plot as static html
p1$save('myplot.html') # saves the plot as standalone html
p1$printChart('chart1')  # prints chart js along with div containing plot

While using printChart, you will need to explicitly add the js and css assets required. If you are using it with Slidify, you just need to include the JS library being used as a widget, and Slidify will automatically add the required assets.

xdg-open instead of open?

The show method uses system(sprintf("open %s", tf)) to open a browser. I get the error "Couldnt get a file descriptor referring to the console". If I use xdg-open instead of open everything works correctly. Am I doing something wrong? Or perhaps is it safer to use xdg-open instead of open?

Thanks for your package!

Oscar

polycharts other options

As I was trying to to do the PerformanceSummary, I discovered these other spec-level options of polycharts https://github.com/Polychart/polychart2/wiki/Chart-options. Can these be added similar to width and height, so they could work something like

p1 <- rPlot(value ~ date, data = managers.melt, color = 'indexname', 
type = 'point', size=list(const=1), 
verticalSpacing =  list(const=200), 
legendPostion = list(const="bottom")
)

and end up in the spec like

 var chartParams = {"dom":"chart1b2c2a1d1da3",
                   "width":700,
                   "height":400,
                   "verticalSpacing":15,
                   "legendPosition":"top",
                    "layers":[{

Design a page for examples

I need a nice template for examples. The idea would be to take an R file with source code for generating a chart, along with a few themable options and producing a standalone html page that can be published. A sample design is shown below

Screen Shot 2013-04-21 at 8 09 17 PM


The page would include the chart, along with the source code used to produce it. In addition, a user can provide a README, which will appear in the sidebar. Other optional elements are a title and subtitle.

CSS Fixes

  • Set width and height for MorrisJS charts

Allow external data sources

Currently, all data is written inline in the HTML file. While this behavior is desirable by default, there are situations where it might be better to save the data as a json/csv file, and then use d3.json or one of the many reader functions to read the data in the HTML file.

It would be good to implement this feature across the board for all libraries. I will need to pick a data library that is able to handle multiple data formats, especially json and csv.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.