At its code G2.js comprises of just a few primitive figures.

  • fig_point
  • fig_interval (bar)
  • fig_line
  • fig_polygon
  • fig_edge
  • fig_schema
  • fig_area
  • fig_heatmap

However, g2r provides many more. This is simply to say that all figures provided by g2r but not G2.js are actually built, under-the-hood, by the aforementioned primitive figures.

Take for instance fig_ribbon which G2.js does not handle out of the box. A ribbon chart is essentially an area chart that holds two y values for every x, where the first is the lower bound and the second is the higher bound.

So why add fig_ribbon? Well because the shape of the data that must be passed to G2.js is somewhat unwieldy.

Instead of using fig_ribbon one could simply build the a list column tibble that resembles the above and use fig_area.


df <- tibble(
  x = 1:100,
  y = runif(100)
) %>% 
    y = lapply(y, function(x) list(x - 1, x + 1))

df %>% 
  head() %>% 
x y
1 -0.6933894, 1.3066106
2 -0.1931425, 1.8068575
3 -0.1679667, 1.8320333
4 -0.2772296, 1.7227704
5 -0.2001063, 1.7998937
6 -0.7516763, 1.2483237

With the list column where the y column actually holds two values one can now simply use fig_area.

g2(df, asp(x, y)) %>% 

All of the custom figures provided by g2r are in the figures.R file, feel free to take a look to learn more about how they work.


It may be somewhat counterintuitive at first but G2.js allows multiple “aspects” where one would often only expect one. For instance the tooltip of a visualisation can make use or present multiple variables.

mtcars %>% 
  mutate(vs = as.factor(vs)) %>% 
  g2(asp(mpg, wt, size = qsec, tooltip = gear, tooltip = carb)) %>% 
  fig_point(asp(shape = "circle", color = vs))

Also, while in ggplot2 one can pass operations to the aes function, e.g.: aes(x = y + 20) one cannot do that with g2r. This is because g2r does not process the data is receives in any way. It likely never will either.

This is because, in an attempt to improve performances, g2r does not “bind” the data used in a figure to it. If data was passed to the initialisation function g2 then that data is used but no subset of it is copied or processed.

“Binding” the data to the figure would enable preprocessing it but would also dramatically increase the amount of data to serialise from R and read from JavaScript.


It’s not strictly true that g2r does not preprocess the data, it performs one operation: reordering. This is because G2.js expects the data to be reordered along the x axis. At the exception of a few figures where it is either not necessary (e.g.: fig_point) or where it would result in a an erroneous output.

  • path
  • polygon
  • edge
  • point
  • heatmap


In G2.js variables can be aliases which changes the name that is displayed across the visualisation, in labels, tooltips, etc.

E.g.: Aliasing the variable below with aka changes the way it is displayed on the tooltip.

g2(freeny, asp(income.level, market.potential)) %>% 
  fig_point() %>% 
  aka(market.potential, "Market Potential")