Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gapminder animation scatter plot #247

Closed
piyayut-ch opened this issue Dec 7, 2020 · 2 comments
Closed

gapminder animation scatter plot #247

piyayut-ch opened this issue Dec 7, 2020 · 2 comments

Comments

@piyayut-ch
Copy link

piyayut-ch commented Dec 7, 2020

I tried to replicate the gapminder animation scatter plot from this example using echarts4r. I find out that the current e_scatter and e_scatter_ function do not allow me to add new dimension (column) to be used in visual_map i.e. mapping a column continent to color.

I find one work around solution. I modify e_scatter_ and .build_data_size function by adding an argument called color as follows.

.build_data_size <- function(data, x, y, size, scale, symbol_size, color, factor = 0, amount = NULL) {
  ...
  data %>%
    dplyr::select(x = x, y = y, size, "sizeECHARTS", color) %>%
    dplyr::mutate(
      x = .jitter(x, factor, amount),
      y = .jitter(y, factor, amount)
    ) %>%
    unname(.) -> data
  ...
}

e_scatter_ <- function(e, serie, size = NULL, bind = NULL, color = NULL,
                       symbol = NULL, symbol_size = 1,
                       scale = e_scale, scale_js = "function(data){ return data[3];}",
                       name = NULL, coord_system = "cartesian2d", jitter_factor = 0,
                       jitter_amount = NULL, legend = TRUE, y_index = 0, x_index = 0, rm_x = TRUE,
                       rm_y = TRUE, ...) {
    ...
    if (!is.null(size)) {
      xy <- .build_data_size(
        e$x$data[[i]], e$x$mapping$x, serie, size, scale, symbol_size, color, jitter_factor, jitter_amount
      )
    } else {
      xy <- .build_data_jitter(e$x$data[[i]], e$x$mapping$x, serie, jitter_factor, jitter_amount)
    }
    ....
}

In addition, the ability to add column(s) from the dataframe enables us to custom tooltip.

I believe this functionality is nice to add and you would have better way to solve this issue. If this is worth effort, please kindly add to the great echart4r package.

Many Thanks.

Here is the code used to generate the animation plot.

library(gapminder)
library(echarts4r)
library(tidyverse)

continents <- as.character(gapminder$continent) %>% unique()

p <- gapminder %>%
  mutate(continent_num = as.integer(continent)) %>%
  group_by(year) %>% 
  e_charts(gdpPercap, timeline = TRUE) %>% 
  e_scatter_(
    "lifeExp", 
    "pop", 
    "symbol_size" = 4,
    color = "continent",
    bind = "country",
    legend = FALSE
  ) %>%
  e_x_axis(
    type = "log",
    min = 100,
    max = 2e5,
  ) %>% 
  e_y_axis(
    max = 100,
  ) %>% 
  e_visual_map(
    type = "piecewise",
    dimension = 4,
    categories = continents,
    inRange = list(
      color = c('#442288', '#6CA2EA', '#B5D33D', '#FED23F', '#EB7D5B')
    ),
    orient = "horizontal",
    left = "center"
  ) %>%
  e_tooltip(
    formatter = htmlwidgets::JS("
      function(params){
        return( '<strong>' + params.name + '</strong><br />' +
                'Continent: ' + params.value[4] + '<br />' +          
                'Life Expectancy: ' + params.value[1] + '<br />' +
                'GDP per capita: ' + params.value[0] + '<br />' +
                'Population: ' + params.value[2]) 
                }
    ")
  ) %>%
  e_timeline_opts(
    axisType = "category", 
    autoPlay = FALSE,
    orient = 'vertical',
    inverse = TRUE,
    playInterval = 1000,
    right = 0,
    top = 20,
    bottom = 20,
    width = 55,
    symbol = 'none',
    lineStyle = list(
      color = "#555"
    ),
    controlStyle = list(
      showNextBtn = FALSE,
      showPrevBtn = FALSE,
      color = '#666',
      borderColor = '#666'
    ),
  ) %>% 
  e_animation(
    duration.update = 1000,
    easing.update = 'linear'
  )
@JohnCoene
Copy link
Owner

There are far too many arguments and far too many combinations of them to add them one by one like to for every single chart. What you ask here works for the scatter plot but not many others, that I, as the author, have to take into consideration.

Defining the color of bubbles can either be done with e_visual_map or should be doable with e_data (see docs) a function meant for those very cases where one would want to hard code nested aspects of some series' data.

Feel free to reopen if that does not work and I will fix it.

@piyayut-ch
Copy link
Author

Hi John!

Thank you for your kindly response. I tried e_data and it did not work out for me. However, after reading more docs I found one solution that allow me to add data (column) into the current echart object, so the echart have data for e_visual_map.

Using e_add function as a base, I create a new function called e_add_value where it takes the current echart object and column name available in the data. Basically, It adds the data of selected column(s) into the current series[[1]]$data[[j]]["value"].

If you think this is useful, feel free to add or modify as you like.

Thanks

Piyayut

e_add_value <- function(e, ...) {
  
  for (i in seq_along(e$x$data)) {
    data <- e$x$data[[i]] %>%
      dplyr::select(...)

    data <- apply(data, 1, as.list)

    for (j in seq_along(data)) {
      if (!e$x$tl) {
        data_origin <- e$x$opts$series[[i]]$data[[j]][["value"]]
        data_new <- list(data_origin, data[[j]] %>% unname()) %>%
          flatten %>% list()
        e$x$opts$series[[i]]$data[[j]]["value"] <- data_new
      } else {
        data_origin <- e$x$opts$options[[i]]$series[[1]]$data[[j]][["value"]]
        data_new <- list(data_origin, data[[j]] %>% unname()) %>%
          flatten %>% list()
        e$x$opts$options[[i]]$series[[1]]$data[[j]]["value"] <- data_new   
      }
    }
  }
  e
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants