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

Transition_reveal for both points and geom_smooth #209

Closed
Janzeero opened this issue Nov 7, 2018 · 27 comments
Closed

Transition_reveal for both points and geom_smooth #209

Janzeero opened this issue Nov 7, 2018 · 27 comments

Comments

@Janzeero
Copy link

Janzeero commented Nov 7, 2018

Here is a data. I can make through transition_reveal appearing geom_points. Looks nice, but I also wanna add exponential regression and visualise both simultaneously. Transition_reveal makes render neither with both smooth and points, nor with just smooth. Its possible only for geom_points. Whats wrong?
Gif only with geom_point
Static with both point and line

Here is a code and error. Should be exponential visualisation of decomposition process of tree wood, where t - age of sampling, Pt - its density.
gif<-ggplot(data, aes(t,Pt))+geom_point(shape=21, aes(fill=group),col="black",size=3)+stat_smooth(method="nls", data=decay, method.args = list(formula = y~a*exp(-b*x), start = list(a=570,b=2*log(2)/570)), se=F,size=0.5, col="black",linetype="dotted")+transition_reveal(Pt,t)
Error:
Error in [.data.frame(df, , c("alpha", "colour", "size", "linetype")) : undefined columns are chosen

Thank you a lot for any suggestion and attention!

@Janzeero
Copy link
Author

Janzeero commented Nov 8, 2018

Column group is missing, lts made like data$group<-with(data, ifelse(Pt<100,0,ifelse(Pt<200,1,ifelse(Pt<300,2,ifelse(Pt<400,3,ifelse(Pt<500,4,5)))))

@ptoche
Copy link

ptoche commented Nov 30, 2018

Edit your first post above with a reprex and remove the second comment for clarity.

https://reprex.tidyverse.org/

@MichaelChirico
Copy link
Contributor

MichaelChirico commented Dec 9, 2018

I think this is similar to something I'm trying to accomplish now:

library(ggplot2)
library(gganimate)
library(data.table)

DT = data.table(
  grp = sample(4L, 1e3, TRUE)
)
DT[ , v := rnorm(.N, sd = 1/.BY$grp), by = grp]
DT[ , grpI := seq_len(.N), by = grp]

Static plot = final frame of animation:

ggplot(DT, aes(grp, v)) + geom_jitter(width = .2)

screen shot 2018-12-09 at 3 55 03 pm

Attempt (doesn't work) in gganimate:

ggplot(DT, aes(grp, v)) + 
  geom_jitter(width = .2) + 
  transition_reveal(grp, grpI)

fail_example

I think it's failing because ?transition_reveal suggests it only works for polygons/lines at the moment.

I think this is a nice animation for showing how points can accumulate to make a distribution.

Here's a workaround that's quite slow to render since it quadratically explodes the number of rows in the input:

ggplot(DT[DT, .(i.grpI, x.grp, x.v), 
          on = .(grpI <= grpI, grp == grp), allow.cartesian = TRUE], 
       aes(x.grp, x.v)) + 
  geom_jitter(width = .2) + 
  transition_states(
    i.grpI,
    transition_length = 1,
    state_length = 2
  )

success_example

@thomasp85
Copy link
Owner

I think you should be able to accomplish what you want by giving a unique group aesthetic to each point

@MichaelChirico
Copy link
Contributor

Thanks @thomasp85. Could you elaborate? I'm also new to most things ggplot2 as well...

@thomasp85
Copy link
Owner

thomasp85 commented Dec 9, 2018

All geoms have a group aesthetic even though it is unused by many. gganimate used it though, in order to figure out which graphic elements are part of the same “entity”.

If you do geom_jitter(aes(group=seq_len(x.v)), width = .2) I think you’d get what you want

@MichaelChirico
Copy link
Contributor

(assume you mean seq_along)

Hmm, not sure I follow.

These both look the same as above to me:

ggplot(DT, aes(grp, v)) + 
  geom_jitter(aes(group = seq_along(v)), width = .2) + 
  transition_reveal(grp, grpI)
ggplot(DT[DT, .(i.grpI, x.grp, x.v), 
          on = .(grpI <= grpI, grp == grp), allow.cartesian = TRUE], 
       aes(x.grp, x.v)) + 
  geom_jitter(aes(group=seq_along(x.v)), width = .2) + 
  transition_states(
    i.grpI,
    transition_length = 1,
    state_length = 2
  )

Anyway, I'm ~basically fine with how the second one looks (constructing the full "scatter boxplot" gradually), the problem is that it's a bit awkward to create the data to mimic the transition_reveal animation (imperfectly at that, since jitter is re-applied for each grpI).

My aim is to make the first one use transition_reveal to more naturally/concisely evoke the same behavior

@Janzeero
Copy link
Author

Thanks, I have already got that through this code
%>% mutate(gr=factor(case_when(Pt<200 ~ 1, Pt<300 ~ 2, Pt<400 ~ 3, Pt<500 ~ 4, TRUE ~ 5))) %>% arrange(t) %>% rowid_to_column() %>% # arrange and add rowid for the transition_reveal mutate(predict=predict(loess(Pt ~ t, data=.), .)) %>% # calculate the predicted values mutate(predict_lag=lag(predict,default = max(predict)), # add the next values for segments t_lag=lag(t,default = min(t))) %>% ggplot(aes(t,Pt)) + geom_point(aes(fill=gr), shape=21,col="black", size=3, show.legend = F) + geom_segment(aes(x=t, y=predict, xend=t_lag, yend=predict_lag), col="black",linetype="dotted") + transition_reveal(rowid, rowid)
Using exponential code instead of loess function.

@thomasp85
Copy link
Owner

@MichaelChirico can you provide a reproducible example... the code you have given produces an error as grpI does not exist

@MichaelChirico
Copy link
Contributor

@thomasp85 sorry, bad copy-pasting... included in original post here

@thomasp85
Copy link
Owner

hmm... I can see that adding a unique group doesn't really alter the output, though it should... I'll look into it

@Janzeero
Copy link
Author

Janzeero commented Dec 10, 2018

Sorry, I am not so good in writing examples :(
data is called decay
decaying_plot <- ggplot(decay, aes(t,Pt)) + geom_point(shape=21, aes(fill=group),col="black",size=3) + stat_smooth(method="nls", data=decay, method.args = list(formula = y~a*exp(-b*x), start = list(a=570,b=2*log(2)/570)), se=F,size=0.5, col="black",linetype="dotted")+xlab("Вік зразка, років")+ylab("Щільність зразка, кг/м3")+theme(legend.position="none")

decay %>% mutate(gr=factor(case_when(Pt<200 ~ 1, Pt<300 ~ 2, Pt<400 ~ 3, Pt<500 ~ 4, TRUE ~ 5))) %>% arrange(t) %>% rowid_to_column()%>%

mutate(predict=predict(nls(Pt ~ a*exp(-b*t),start = list(a=570,b=2*log(2)/570), data=.), .)) %>% mutate(predict_lag=lag(predict,default = max(predict)), t_lag=lag(t,default = min(t))) %>% ggplot(aes(t,Pt)) + geom_point(aes(fill=gr), shape=21,col="black", size=3, show.legend = F) + geom_segment(aes(x=t, y=predict, xend=t_lag, yend=predict_lag), col="black",linetype="dotted") + transition_reveal(rowid, rowid)

So I get something like this

@thomasp85
Copy link
Owner

Ah... I'm messing up my head because I'm currently doing some last minute changes to the transition api's... Setting group will work in the future, but for now you should do transition_reveal(seq_along(grp), grpI)

@ptoche
Copy link

ptoche commented Dec 10, 2018

reprex below

library(reprex)

library(ggplot2)
library(gganimate)
library(data.table)

DT = data.table(
  grp = sample(4L, 1e3, TRUE)
)
DT[ , v := rnorm(.N, sd = 1/.BY$grp), by = grp]
DT[ , grpI := seq_len(.N), by = grp]


# Example 1
ggplot(DT, aes(grp, v)) + 
  geom_jitter(aes(group = seq_along(v)), width = .2) + 
  transition_reveal(grp, grpI)

# Example 2
ggplot(DT[DT, .(i.grpI, x.grp, x.v), 
          on = .(grpI <= grpI, grp == grp), allow.cartesian = TRUE], 
       aes(x.grp, x.v)) + 
  geom_jitter(aes(group=seq_along(x.v)), width = .2) + 
  transition_states(
    i.grpI,
    transition_length = 1,
    state_length = 2
  )

Created on 2018-12-10 by the reprex package (v0.2.0).

@Janzeero
Copy link
Author

thanks, looking good!

@thomasp85
Copy link
Owner

ggplot(DT, aes(grp, v)) + 
  geom_jitter(width = .2) + 
  transition_reveal(seq_along(grp), grpI)

reveal_points

@MichaelChirico
Copy link
Contributor

@thomasp85 looking exactly like I envisioned! love it! excellent!

@thomasp85
Copy link
Owner

@MichaelChirico be aware that I will soon deprecate the id argument in all transitions and wholeheartedly embrace the use of the group aesthetic (should have done this from the beginning - don't know what happened), so you'll have to adjust this to the first proposed solution

@thomasp85
Copy link
Owner

@Janzeero your issue is entangled in a lot of stuff that I'm working on right now - a fix will be provided soon

@thomasp85
Copy link
Owner

@Janzeero just to be sure - Is this the result you are after?
reveal_points

@thomasp85
Copy link
Owner

@MichaelChirico the changes I talked about has been merged and you should now do:

ggplot(DT, aes(grp, v, group = seq_along(v))) + 
  geom_jitter(width = .2) + 
  transition_reveal(grpI)

to get the correct result

@fmmattioni
Copy link

I would be curious to know how this was produced with the new API. There are some tutorials online, but they all use the deprecated gganimate().

@Janzeero just to be sure - Is this the result you are after?
reveal_points

@jlopezper
Copy link

jlopezper commented Apr 9, 2019

I join the request of @fmmattioni. @thomasp85 could you please provide an example of how to make that last plot? I just also found examples with deprecated API like this.

@thomasp85
Copy link
Owner

My last response includes the code

@jlopezper
Copy link

Ok, sorry, I didn't get it! Thanks!

@johannesbjork
Copy link

My last response includes the code

Where exactly? I only see the code for the scatter plot... Thanks!

@jhelvy
Copy link

jhelvy commented Mar 2, 2021

My last response includes the code

Where exactly? I only see the code for the scatter plot... Thanks!

I also am not seeing any code to produce the animated points + smooth chart.

When I run this code, I get the following error:

ggplot(mtcars, aes(x = mpg, y = hp)) +
    geom_point() +
    geom_smooth(method = 'loess', formula = 'y ~ x', se = FALSE) +
    transition_reveal(mpg)
Error in `$<-.data.frame`(`*tmp*`, "group", value = "") : 
  replacement has 1 row, data has 0

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

8 participants