I have an issue with ordering of rows from source filtered dataset used for building gganimate object.
Here is the sample data:
df <- data.frame(grName = c("red", "red", "orange", "yellow", "green", "green", "orange",
"cyan", "blue", "blue", "violet", "yellow", "cyan", "violet") %>% as.factor,
grVal = c(1, 3, 2, 7, 4, 5, 3.5,
2, 4, 1, 6, 5, 6, 3),
grFill = c("red", "red", "orange", "yellow", "green", "green", "orange",
"cyan", "blue", "blue", "violet", "yellow", "cyan", "violet"),
frame = c(1,2,1,1,1,2,2,1,1,2,1,2,2,2)
)
When I build separate gglots for each frame value everything is OK:
ggplot(df)+
geom_bar(aes(grName, grVal),
data = function(x) filter(x, grVal < 7, frame == 2),
fill = filter(df, grVal < 7, frame == 2) %>% pull(grFill),
stat = "identity")
I am getting the desired frame:
But as soon as I apply gganimate the columns order and fill
get confused:
ggplot(df)+
geom_bar(aes(grName, grVal),
data = function(x) filter(x, grVal < 7),
fill = filter(df, grVal < 7) %>% pull(grFill),
stat = "identity") +
labs(title = 'Frame: {current_frame }') +
transition_manual(frame) +
ease_aes('linear')
When I was investigating into the issue I got an alike problem when plotting a facetted ggplot:
ggplot(df)+
geom_bar(aes(grName, grVal),
data = function(x) filter(x, grVal < 7),
#fill = ddd %>% pull(grFill),
fill = filter(df, grVal < 7) %>% pull(grFill),
stat = "identity") +
facet_grid(rows = vars(frame))
I would prefer not setting fill
/color
etc from inside aes()
along with scale_*_manual()
as in my real graph doing so resulted into another issue (uncontrollable hjust
of colored letters) correctly plotted when color
aes()
is not set and color is not set at all or set by color
property of geom_text()
. If I have time I'll report the issue separately.
I also have to apply filters to data objects inside constructed geoms as different (many various) geoms are plotted simultaneously in my real graph and I would like to keep reverse compatibility of new animated plot with previously used static one.
I assume that getting access to data
object of ggplot()
when setting color
(outside aes()
) like I do with geoms' data
: data = function(x) filter(x, ...
will help me to preserve order of rows from dataset filtered/grouped by gganimate engine and thus keep order and fill
/ color
etc. of plotted elements.
So I would appreciate any suggestions as I am stuck with the issue.
This is a nice example why in general I recommend to not pass vectors to arguments of the geom. Instead you could map on the fill
aesthetic and use scale_fill_identity
.
library(dplyr, warn=FALSE)
library(ggplot2)
library(gganimate)
gg <- ggplot(df) +
geom_col(aes(grName, grVal, fill = grName),
data = ~ filter(.x, grVal < 7),
) +
scale_fill_identity()
gg +
labs(title = 'Frame: {current_frame }') +
transition_manual(frame) +
ease_aes('linear')
#> nframes and fps adjusted to match transition
And this also fixes the assignment of the colors when facetting by frame
:
gg +
facet_wrap(~frame, ncol = 1)