1

Highcharts motion plugin - Requires 3 adjustments to a highchart.

  1. The inclusion of the js asset
  2. An option object for motion
  3. Data to be within sequence arrays.

It seems like there are two main R wrappers for Highcharts. Ramnath's rCharts and the recently released on CRAN highcharter.

So my question: is it possible to animate a bubble highchart over time with the currently available wrappers and if so how?

rCharts Attempt 1 Starting with a bubble chart and introducing the 3 required motion options:

library(rCharts) # highcharts wrapper hPlot()

# data
set.seed(1)
df.SO <- data.frame(date = sample(2005:2016, 21, replace = T)
                    , x = rnorm(21, 10, 4)
                    , y = rnorm(21, 150, 4)
                    , z = rbinom(21, 80, .8)
                    , entities = sample(c("entity1","entity2","entity3"), 21, replace = T))

# chart
h1 <- hPlot(  x     = "x"
              , y     = "y"
              , size  = "z"
              , group = "entities"
              , data  = df.SO
              , type  = "bubble")

### Motion Charts plugin ###
## 1. include motion js asset in head
h1$addAssets(jshead = "https://rawgit.com/larsac07/Motion-Highcharts-Plugin/master/motion.js")

## 2. add motion object
h1$params$motion  <- list(enabled = "true",
                          labels  = unique(sort(df.SO$date)),
                          loop    = "true",
                          series  = 1,
                          updateInterval = 50,
                          magnet  = list(
                              round = "round",
                              step = 0.1))

## 3. sequence data?? Dead end approach??

# view chart - displays bubbles and widget to play animation, but animation fails
print(h1)

rCharts - Attempt 2 Restructure data as sequences then feed into chart.

# 3. sequence data - cast data so entities are series and times are unique entries
library(data.table) ## v >= 1.9.6
test <- dcast(setDT(df.SO), date ~ entities, value.var = c("x", "y", "z"))

# chart
h1 <- Highcharts$new()
h1$chart(type = "bubble", height = 300)
h1$series(
    list(name = "entity1",
        data = list(
            sequence = test$x_length_entity1,
            sequence = test$y_length_entity1,
            sequence = test$z_length_entity1
        )
    ),
    list(name = "entity2",
         data = list(
             sequence = test$x_length_entity2,
             sequence = test$y_length_entity2,
             sequence = test$z_length_entity2
         )
    ), replace = T)

## 1. include motion js asset in head
h1$addAssets(jshead = "https://rawgit.com/larsac07/Motion-Highcharts-Plugin/master/motion.js")

## 2. add motion object
h1$params$motion  <- list(enabled = "true",
                          labels  = unique(sort(test$date)),
                          loop    = "true",
                          series  = 1,
                          updateInterval = 50,
                          magnet  = list(
                              round = "round",
                              step = 0.1))

# view chart - this approach doesn't display any bubbles
print(h1)
Luke Singham
  • 1,536
  • 2
  • 20
  • 38
  • 2
    Hi @luke-singham, I'll look it how to implement this feature in highcharter, if have success I'll let you know. – jbkunst Mar 14 '16 at 14:51
  • @jbkunst brilliant, thank you! This might be helpful: The [motion.js](https://github.com/larsac07/Motion-Highcharts-Plugin/blob/master/motion.js) uses [`update.point`](http://api.highcharts.com/highcharts#Point) which handles numbers, arrays and objects. Suggesting the multivariate data required for a motion bubble chart is possible. – Luke Singham Mar 15 '16 at 00:08

3 Answers3

3

Luke,

motion.js plugin was added to highcharter. Is in development version (download via devtools), it's need more testing but is it a start.

Please check the example in http://jkunst.com/highcharter/plugins.html#motion:

  highchart() %>% 
    hc_chart(type = "column") %>% 
    hc_yAxis(max = 6, min = 0) %>% 
    hc_add_series(name = "A", data = c(2,3,4), zIndex = -10) %>% 
    hc_add_series(name = "B",
                  data = list(
                    list(sequence = c(1,2,3,4)),
                    list(sequence = c(3,2,1,3)),
                    list(sequence = c(2,5,4,3))
                  )) %>% 
    hc_add_series(name = "C",
                  data = list(
                    list(sequence = c(3,2,1,3)),
                    list(sequence = c(2,5,4,3)),
                    list(sequence = c(1,2,3,4))
                  )) %>% 
    hc_motion(enabled = TRUE,
              labels = 2000:2003,
              series = c(1,2))

If you find any suspicions behavior (aka bugs) please report here: https://github.com/jbkunst/highcharter/issues

Hope it helps

jbkunst
  • 3,009
  • 1
  • 22
  • 28
2

Have you considered shiny as a temporary solution?

library(shiny)
library(rCharts)
library(dplyr)

server <- shinyServer(function(input, output) {

  output$bubblePlot <- renderChart2({

    # data
    set.seed(1)
    df.SO <- data.frame(date = sample(2005:2016, 21, replace = T)
                        , x = rnorm(21, 10, 4)
                        , y = rnorm(21, 150, 4)
                        , z = rbinom(21, 80, .8)
                        , entities = sample(c("entity1","entity2","entity3"), 21, replace = T))

    # filter data based on selected year
    df.SO.select <- dplyr::filter(df.SO, date == input$date)

    # chart
    h1 <- hPlot(  x     = "x"
                  , y     = "y"
                  , size  = "z"
                  , group = "entities"
                  , data  = df.SO.select
                  , type  = "bubble")
    h1$addParams(dom = "bubbleChart")
    h1$plotOptions(series = list(animation = FALSE))
    h1$xAxis(min = min(df.SO$x), max = max(df.SO$x))
    h1$yAxis(min = min(df.SO$y), max = max(df.SO$y))
    h1

  })

})

ui <- shinyUI(fluidPage(

  # Application title
  titlePanel("Highcharts Bubble Motion Chart"),

  # Sidebar with a slider input for the selected year
  sidebarLayout(
    sidebarPanel(
      sliderInput("date",
                  "Date:",
                  min = 2007,
                  max = 2016,
                  value = 2007,
                  animate = TRUE,
                  sep = "")
    ),

    # Show a bubble plot for the selected year
    mainPanel(
      showOutput("bubblePlot", "highcharts")
    )
  )
))

shinyApp(ui = ui, server = server)
Paul Govan
  • 673
  • 6
  • 20
  • Welcome to SO! Thanks for your answer. About a year and a half ago I used `shiny` in this way with `ggplot` as the viz. The disadvantage of using `slidertInput(... animate = TRUE)` is that the bubbles aren't _really_ in motion - they just reappear. It might suffice if the data used had a high number of periods (like frames in a video) and the amount of change between periods for each entity was low - neither apply for the data used. – Luke Singham Mar 18 '16 at 03:09
  • Well again it might be a temporary solution until @jbkunst can add the [motion.js](http://www.highcharts.com/plugin-registry/single/40/Motion) plugin to the awesome [highcharter](http://jkunst.com/highcharter/) library. I use this approach quite often with just a few frames, and to the untrained eye, most don't know the difference. – Paul Govan Mar 23 '16 at 23:07
0

Surprising I couldn't find any posted examples demonstrating bubble or scatter as the chart type with hc_motion. All examples are either, bar, column, map, pie.

Anyway, after a fair bit of hit & miss, I managed to get scatter plot working doing the following on the sequence. each vector c(1,1) represents x & y coordinates. I'm still trying to get it working with bubble with no luck. Hoping someone might be able to post an code snippet for bubble using the hcaes() format.

Bubble would be handy for motion, as you can then do Gapminder style charts. http://www.gapminder.org/

library(highcharter)

    highchart() %>% 
            hc_chart(type = "scatter") %>% 
            hc_yAxis(max = 6, min = 0) %>% 
            hc_xAxis(max = 6, min = 0) %>%
            hc_add_series(name = "Australia",
                          data = list(
                                  list(sequence = list(c(1,1),c(2,2),c(3,3),c(4,4)))
                          )) %>%
            hc_add_series(name = "United States",
                          data = list(
                                  list(sequence = list(c(0,0),c(3,2),c(4,3),c(4,1)))
                          )) %>%
            hc_add_series(name = "China",
                          data = list(
                                  list(sequence = list(c(3,2),c(2,2),c(1,1),c(2,5)))
                          )) %>% 
            hc_motion(enabled = TRUE,
                      labels = 2000:2003,
                      series = c(0,1,2))
Clay
  • 1,721
  • 2
  • 10
  • 18