echarts4r
echarts4r copied to clipboard
Morphing possible between scatter and aggregated bar charts?
Hi @JohnCoene!
Just wondering. Do you think it is possible to use the new morph-function for a tranistion between a scatter plot and a bar plot?
This is an example of what I mean. It uses an avarage calculation function and uses it as a value in data, but I have no idea how to incoporate this in in echarts4r.
Thanks in advance!
@rdatasculptor, calculating averages is on the data preparation stage, not related to visualization. No need to use JS for it since R has function mean() and others to do the same job. Just build the two data/charts and plug them into e_morph - should work.
@helgasoft yes, I am aware of the possibilities within R itself, but with that approach there is no real morph. In the example of echarts the bars seem to be build of all the pieces of data the avarage is taken from. So the issue I am aimin at is the smoothness of the trainsition of scatter plot into the bar chart. If I have some more time I will show what I mean with an example.
Could be integrated but evaluating R code via htmlwidgets is less than ideal, is it for shiny or Rmd?
It's for Rmd. (I always intend to not be too dependent on shiny, and thanks too echarts4r I succeed very often :))
Hi @JohnCoene! I don't know if it is of any worth, but using e_list()
is at least one way to bring @helgasoft's example of smooth transition between differenct plot types, mentioned here, to echarts4r
:
library(dplyr)
library(echarts4r)
mc <- mtcars |> filter(cyl<8)
datt <- function(idx) { return(mc[mc$cyl==idx,]$hp) }
colors <- c("blue","red")
oscatter <- list(
title= list(subtext='press button to morph'),
xAxis= list(scale=TRUE),
yAxis= list(scale=TRUE), color= colors,
series=list(
list(type='scatter', id=4, dataGroupId=4, data= datt(4),
universalTransition= list(enabled= TRUE)),
list(type='scatter', id=6, dataGroupId=6, data= datt(6),
universalTransition= list(enabled=TRUE))
)
)
obar <- list(
title= list(text= 'Average'),
xAxis= list(type= 'category', data= list('cyl4', 'cyl6')),
yAxis= list(show= TRUE), color= colors,
series= list(list(
type= 'bar', id= 'average', colorBy= 'data',
data= list(
list(value= mean(datt(4)), groupId=4),
list(value= mean(datt(6)), groupId=6)),
universalTransition=list(enabled= TRUE,
seriesKey=c(4, 6))
))
)
e1 <- e_charts() |>
e_list(obar)
e2 <- e_charts() |>
e_list(oscatter)
e_morph(e1, e2, callback = cb) %>%
htmlwidgets::prependContent(
htmltools::tags$button("Toggle", id = "toggle")
)
e_morph(e1, e2, callback = cb) %>%
htmlwidgets::prependContent(
htmltools::tags$button("Toggle", id = "toggle")
)
Maybe it generates new ideas? Somehow the charts should be connected by id's and dataGroupIds. I guess I can add them to the lists programmattically, but haven't succeeded yet in doing that properly (in finding a generic way)
Another attempt with an example script of my own. Obviously I overlook something or I misunderstand the docs about universal transition, but using dataGroupId
should be at least one of the necassary ingredients. Th example below gives a transition but not the transition what I am looking for: bar chart breaking into smaller pieces and turning into the scatter plot.
df <- data.frame(nummer = 1:10, y1 = sample(1:100, 10), group=as.character(sample(1:2, 10, replace = TRUE)))
e1 <- df %>%
e_charts(nummer) %>%
e_scatter(y1, symbol_size = 20,
dataGroupId = = "data",
universalTransition = list(enabled= TRUE,
seriesKey= "data")),
animationDurationUpdate = 1000L)
e2 <- df %>% group_by(group) %>% summarise(y1 = sum(y1)) %>% ungroup() %>%
e_charts(group) %>%
e_bar(y1,
dataGroupId = "data",
universalTransition = list(enabled= TRUE,
seriesKey= "data", divideShape = "clone"),
animationDurationUpdate = 1000L)
cb <- "() => {
let x = 0;
document.getElementById('toggle')
.addEventListener('click', (e) => {
x++
chart.setOption(opts[x % 2], true);
});
}"
e_morph(e1, e2, callback = cb) %>%
htmlwidgets::prependContent(
htmltools::tags$button("Toggle", id = "toggle")
)
Hi @JohnCoene, sorry for bothering you again, but I kind of succeeded in making a smooth transition between a scatter plot and a bar chart. (@helgasoft put me in the right direction). I still don't know exactly what I am doing, but it works.... :)
But this approach needs some tweaks in the object structure. First I turn the echarts4r object into a list, then I do the tweaks, and finally I render the plots using e_list()
.
Maybe you can find a way (if you have time ofcourse...) to somehow make it possible to these kind of transitions without needing to tweak before rendering? But then again, maybe it is harder to implement such a feature than I think.
Here is a wokring example of the smooth transition:
library(echarts4r)
library(dplyr)
set.seed(2022)
df <- data.frame(nummer = 1:10, y1 = sample(1:100, 10),
group=as.character(sample(1:2, 10, replace = TRUE))) %>% dplyr::group_by(group)
oscatter <- df %>%
e_charts(nummer) %>%
e_scatter(y1, symbol_size = 20) %>% e_inspect()
oscatter$series[[1]]$universalTransition <- list(enabled = TRUE, seriesKey = c(1))
oscatter$series[[2]]$universalTransition <- list(enabled = TRUE, seriesKey = c(2))
oscatter$series[[1]]$id <- 1
oscatter$series[[2]]$id <- 2
oscatter$series[[1]]$dataGroupId <- 1
oscatter$series[[2]]$dataGroupId <- 2
oscatter <- e_charts() %>%
e_list(oscatter)
obar <- df %>% summarise(y1 = sum(y1)) %>% ungroup() %>%
e_charts(group) %>%
e_bar(y1, colorBy= "data", universalTransition = list(enabled= TRUE)) %>% e_inspect()
obar$series[[1]]$data[[1]]$groupId <- 1
obar$series[[2]]$data[[1]]$groupId <- 2
obar$series[[1]]$universalTransition <- list(enabled = TRUE, seriesKey = c(1,2))
obar <- e_charts() %>%
e_list(obar)
cb <- "() => {
let x = 0;
document.getElementById('toggle')
.addEventListener('click', (e) => {
x++
chart.setOption(opts[x % 2], true);
});
}"
e_morph(oscatter, obar, callback = cb) %>%
htmlwidgets::prependContent(
htmltools::tags$button("Toggle", id = "toggle")
)
If someone can find a solution for not being able to morph between bar charts and scatter plots using echart4r (@munoztd0 .. :)), well, for me he earns the nobel prize ....
In my imagination we just give the scatterplot and the bar chart that should be morphed into one another the same "morph id". Under the hood echarts4r takes care of all the necessary echarts settings :). Experimented with it, but haven't made it work yet.