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

Timeline VS Categorical groupby | Potential limitation [scatter3d/scatter/area etc] #593

Open
MrMisc opened this issue Nov 22, 2023 · 3 comments
Labels

Comments

@MrMisc
Copy link

MrMisc commented Nov 22, 2023

From all the examples I have seen so far regarding timeline, I have seen timeline being used to groupby one variable, and each frame being one homogeneous set of points, usually with little to no distinction between them in terms of grouping. Considering the following dataset

3D Scatterplot Example | ECharts

library(echarts4r)
# library(echarts4r.assets)
library(dplyr)
library(pandoc)
library(rjson)
library(echarty)

N<-300
df <- data.frame(x = runif(N,1,20),
                 y = runif(N,10,25),
                 z = rnorm(N,100,50),
                 Time = runif(N,5,500),
                 label = sample(c("interaction1", "interaction2", "interaction3", "interaction4", "interaction5"), N, replace = TRUE),
                 zone = sample(c("zone0", "zone1", "zone3"), N, replace = TRUE))

df_toadd<-data.frame(x = runif(N,80,100),
                     y = runif(N,10,25),
                     z = rnorm(N,100,50),
                     Time = runif(N,5,500),
                     label = sample(c("interaction1", "interaction2", "interaction3", "interaction4", "interaction5"), N, replace = TRUE),
                     zone = sample(c("zone0", "zone1", "zone3"), N, replace = TRUE))
df<-rbind(df,df_toadd)



df|>group_by(label)|>e_charts(x)|>
  e_scatter_3d(y,z,Time)|>
  e_visual_map(Time,inRange = list(symbol = "diamond",symbolSize = c(25,5)),scale = my_scale)|>
  e_tooltip()|>
  e_theme("westeros")|>
  e_legend(show = TRUE)

So far this part works just fine, but the moment I want to use timeline to "scroll" through the zone column, I am forced to turn label into a numerical variable and do this

##Timeline
df$mylabel<-as.numeric(substr(df$label,12,12))
my_scale <- function(x) scales::rescale(x, to = c(min(df$Time),max(df$Time)))

df|>group_by(zone)|>e_charts(x,timeline = TRUE)|>
  e_scatter_3d(y,z,Time,mylabel,label)|>
  e_visual_map(Time,inRange = list(symbol = "diamond",symbolSize = c(35,5)),scale = my_scale,dimension = 3)|>
  e_visual_map(mylabel,inRange = list(colorLightness = c(0.5,0.8), colorHue = c(180,260),colorSaturation = c(120,200)),dimension = 4,bottom = 300)|>
  e_tooltip()|>
  e_theme("westeros")|>
  e_legend(show = TRUE)

Is there a way to do a categorical form of grouping WITHIN each frame?

Scatterplot Timeseries Across Timeline WITH categories | Plotly

I find this issue popping up for me a number of times. For example, say we had a dataset like so:
output.csv

and the columns meant the following

data<-read.csv("output.csv",header = FALSE)
colnames(data) <- c(
  "ContaminantPct1","TotalSamples1_","ContaminantSamples1",
  "HitPct1", "TotalSamples1", "HitSamples1",
  "HitPct2", "TotalSamples2", "HitSamples2","HitPct3","HitSamples3","HitPct4", "TotalSamples4", "HitSamples4","Zone"
)

In plotly, I can make a frame-by-frame plot for each zone, where each of the HitPct{i} & ContaminantPct1 numbers are a category of their own (totalling to 5 categories of time series, for each zone). I can use plotly to make a plot that looks like this

#Round up values
data$ContaminantSamples1<-ceiling(data$ContaminantSamples1) #Contaminated Hosts
data$HitSamples1<-ceiling(data$HitSamples1) #Infected Hosts
data$HitSamples2<-ceiling(data$HitSamples2) #Eggs
data$HitSamples3<-ceiling(data$HitSamples3) #Colonized Hosts
data$HitSamples4<-ceiling(data$HitSamples4) #Faeces
# Scatter plot for the first 2 sets of data
# Define custom theme colors
thematic_on(bg = "#FCE9D7", fg = "orange", accent = "purple",font = "Yu Gothic")
# 



# Create a unique identifier for each time unit
no_of_zones<-length(unique(data$Zone))
data$TimeUnit <- rep(seq_len(nrow(data) / no_of_zones), each = no_of_zones)

# Farm

fig_dots <- data %>%
  plot_ly(type = "scatter",
          mode = "markers+lines", line = list(width = 0.35))%>%
  add_trace(x = ~TimeUnit,
            y = ~ContaminantPct1,
            frame = ~Zone,  # Use TimeUnit for animation frames
            color = "Contaminated Hosts",
            colors = c("#2A6074", "#00C9B1"),
            size = ~TotalSamples1_,
            customdata = ~{
              zone_data <- data[data$TimeUnit == TimeUnit, ]
              paste(zone_data$ContaminantSamples1, "out of ", zone_data$TotalSamples1_, " hosts @ ",zone_data$TimeUnit," hours")
            },
            hovertemplate = "%{y} % of motile hosts <br> are contaminated  <br> ie %{customdata}") %>%
  add_trace(x = ~TimeUnit,
            y = ~HitPct1,
            frame = ~Zone,  # Use TimeUnit for animation frames
            color = "Infected Hosts",
            colors = c("#2A6074", "#00C9B1"),
            size = ~TotalSamples1,
            customdata = ~{
              zone_data <- data[data$TimeUnit == TimeUnit, ]
              paste(zone_data$HitSamples1, "out of ", zone_data$TotalSamples1, " hosts @ ",zone_data$TimeUnit," hours")
            },
            hovertemplate = "%{y} % of motile hosts <br> are infected  <br> ie %{customdata}") %>%
  add_trace(x = ~TimeUnit,
            y = ~HitPct3,
            frame = ~Zone,  # Use TimeUnit for animation frames
            color = "Colonized Hosts",
            colors = c("#2A6074", "#00C9B1"),
            size = ~TotalSamples1,
            customdata = ~{
              zone_data <- data[data$TimeUnit == TimeUnit, ]
              paste(zone_data$HitSamples3, "out of ", zone_data$TotalSamples1, " colonized hosts @ ",zone_data$TimeUnit," hours")
            },
            hovertemplate = "%{y} % of motile hosts <br> are colonized  <br> ie %{customdata}") %>%            
  add_trace(
    x = ~TimeUnit,
    y = ~HitPct2,
    frame = ~Zone,  # Use TimeUnit for animation frames
    color = "Deposits",
    colors = c("#FFF184", "#FFDD80"),
    size = ~TotalSamples2,
    customdata = ~{
              zone_data <- data[data$TimeUnit == TimeUnit, ]
              paste(zone_data$HitSamples2, "out of ", zone_data$TotalSamples2, " edible/consumable deposits @ ",zone_data$TimeUnit," hours")
            },
    hovertemplate = "%{y} % of sessile deposits <br> are infected  <br> ie %{customdata}",
    line = list(width = 0.35)
  )%>%
  add_trace(x = ~TimeUnit,
            y = ~HitPct4,
            frame = ~Zone,  # Use TimeUnit for animation frames
            color = "Faeces",
            colors = c("#2A6074", "#00C9B1"),
            size = ~TotalSamples4,
            customdata = ~{
              zone_data <- data[data$TimeUnit == TimeUnit, ]
              paste(zone_data$HitSamples4, "out of ", zone_data$TotalSamples4, " faecal matter @ ",zone_data$TimeUnit," hours")
            },
            hovertemplate = "%{y} % of faecal matter <br> are infected  <br> ie %{customdata}") %>%
  layout(title = "Infection Trend within cultivation",
         plot_bgcolor = '#FFF8EE',
         xaxis = list(
           title = "Time (Hours)",
           zerolinecolor = '#ffff',
           zerolinewidth = 0.5,
           gridcolor = '#F4F2F0'),
         yaxis = list(
           title = "Percentage of Infected",
           zerolinecolor = '#ffff',
           zerolinewidth = 0.5,
           gridcolor = '#F4F2F0')) %>%
  animation_slider(
    currentvalue = list(font = list(color = "darkgreen"))
  ) %>%
  animation_opts(mode = "next",
                 easing = "exp-in", redraw = FALSE
  )

plotlyoutput

I have tried doing something similar with ECharts but I end up forced to remove the valuable distinction between said categories here. I have the same issue within other charts too such as e_area etc. I can't seem to split between categorical groups within each frame when timeline gets involved. (PS: I find visual map to also be quite confusing sometimes too, especially with my other concurrent issue with e_geo/e_scatter not apparently following my colouring instructions like here)

Symbols per group

Small note here, but in the couple of visualization libraries I have dabbled with, I noticed that all the ones I have tried seem to not have the capability to intuitively allow the user to have different symbols for each group. In plotly, if you categorise scatterpoints via colour for group1 for instance, you are never going to be able to allocate separate symbols successfully for those same scatterpoints via a different group2 for example.

In echarts4r it seems, you can use different "icons" for scatterpoints if you want across the different groups. I have not checked to see if this is still possible within each frame in the timeline, however. Nevertheless, you can't quite do it for scatterpoint symbols at all. As far as I am aware, there is no direct way to have the scatterpoints randomly be given a different symbols per group. Is there any chance of this being incorporated into echarts4r in the near future perhaps? Or maybe someone knows of a way to currently give different symbols for each group (including within a timeline)?

Any help would be greatly appreciated. Thank you for your time.

@MrMisc MrMisc changed the title Timeline | Potential limitation [scatter3d/scatter/area etc] Timeline VS Categorical groupby | Potential limitation [scatter3d/scatter/area etc] Nov 22, 2023
@rdatasculptor
Copy link
Contributor

Just a thought: have you considered to experiment with e_morph()? Maybe not ideal, and I could be mistaken (haven't tried out your seemingly excellent reproducible code yet), but I used it for cases like yours before.

@MrMisc
Copy link
Author

MrMisc commented Nov 26, 2023

Just a thought: have you considered to experiment with e_morph()? Maybe not ideal, and I could be mistaken (haven't tried out your seemingly excellent reproducible code yet), but I used it for cases like yours before.

Since your comment I have actually been looking into how to use e_morph to work for a number of scenarios. Unfortunately I am still very much in a learning phase for that. I have trouble even replicating simple emorphs for 2 scatterplots for example.

Additionally, I wonder if it is even possible to do e_morphs exhaustively or if it is possible to ascribe morphing to a button, instead of it being automatic as I have seen from the example here

@rdatasculptor
Copy link
Contributor

rdatasculptor commented Nov 26, 2023

The good news: yes you can ascribe the morphing to a button! @JohnCoene put some very helpful examples in this issue: #440. I experimented a lot with it. It's simply great!

Morphing between two scatter plots should be definitely possible using echarts4r. Can you give an example script? Maybe I can take a look. I have not much time lately though.

Also, Thank you for all your finds and questions! In the end it will help us improve echarts4r.

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

No branches or pull requests

3 participants