How to create smooth transition between states in gganimate using geom_point? - r

I am trying to create an animated plot using gganimate.
When I pass the following factor dat$period to transition_states,
I get 3 static images. I would prefer to have the points "move" from state-to-
state.
Here is my code:
plot <-
ggplot(data = dat, aes(x = age, y = value, color = period)) +
geom_point(size = 3, aes(group = period)) +
facet_wrap(~group)+
transition_states(states=period, transition_length = 2, state_length = 1) +
ease_aes('linear')+
enter_fade()+
exit_fade()
plot
Here is my data:
record period value age group
1 1 start 45 24 a
2 2 start 6 22 c
3 3 start 23 32 b
4 4 start 67 11 a
5 1 middle 42 24 a
6 2 middle 65 22 c
7 3 middle 28 32 b
8 4 middle 11 11 a
9 1 end 23 24 a
10 2 end 14 22 c
11 3 end 34 32 b
12 4 end 21 11 a
13 5 start 5 12 c
14 6 start 9 23 c
15 7 start 53 47 b
16 8 start 17 32 a
17 5 middle 15 12 c
18 6 middle 6 23 c
19 7 middle 23 47 b
20 8 middle 67 32 a
21 5 end 51 12 c
22 6 end 16 23 c
23 7 end 8 47 b
24 8 end 41 32 a
The points appear/disappear - I would like the points to travel on the screen between states - any help appreciated

The group aesthetic is used to determine which rows in each period's data are treated as the same objects. You need group = record here:
ggplot(data = dat, aes(x = age, y = value, color = period)) +
geom_point(size = 3, aes(group = record)) +
facet_wrap(~ group)+
transition_states(states=period, transition_length = 2, state_length = 1) +
ease_aes('linear')+
enter_fade()+
exit_fade()

Related

How to put axes behind the graph?

I created a graph using geom_line and geom_point via ggplot. I want my axes to meet at (0,0) and I want my lines and data points to be in front of the axes instead of behind as shown:
I've tried:
coord_cartesian(clip = 'off')
putting geom_line and geom_point at the end
creating a base graph then add geom_line and geom_point
playing around with the functions of coord_cartesian
manually setting xlim =c(-0.1, 25) and ylim=c(-0.1, 1500)
data7 is as follows:
Treatment Days N mean sd se
1 1 0 7 204.7000000 41.579963 15.7157488
2 1 2 7 255.0571429 41.116617 15.5406205
3 1 5 7 290.6000000 49.506498 18.7116974
4 1 8 7 330.8142857 49.044144 18.5369442
5 1 12 7 407.5142857 95.584194 36.1274294
6 1 15 7 540.8571429 164.299390 62.0993323
7 1 19 7 737.5285714 308.786359 116.7102736
8 1 21 7 978.4571429 502.506726 189.9296898
9 2 0 7 205.7428571 46.902482 17.7274721
10 2 2 7 227.5571429 47.099889 17.8020846
11 2 5 7 232.4857143 59.642922 22.5429054
12 2 8 7 247.9857143 66.478529 25.1265220
13 2 12 7 272.0428571 79.173162 29.9246423
14 2 15 7 289.1142857 82.847016 31.3132288
15 2 19 7 312.3857143 105.648591 39.9314140
16 2 21 7 334.7142857 121.569341 45.9488920
17 3 0 7 212.2285714 47.549263 17.9719320
18 3 2 7 235.4142857 52.689671 19.9148237
19 3 5 7 177.0714286 54.895225 20.7484447
20 3 8 7 205.2571429 72.611451 27.4445489
21 3 12 7 247.8142857 119.369558 45.1174522
22 3 15 7 280.4285714 140.825847 53.2271669
23 3 19 7 366.9142857 210.573799 79.5894149
24 3 21 7 451.0428571 289.240793 109.3227438
25 4 0 7 211.6857143 24.329161 9.1955587
26 4 2 7 227.8428571 28.762525 10.8712127
27 4 5 7 205.9428571 49.148919 18.5765451
28 4 8 7 153.1142857 25.189246 9.5206399
29 4 12 7 128.2571429 43.145910 16.3076210
30 4 15 7 104.1714286 45.161662 17.0695038
31 4 19 7 85.4714286 51.169708 19.3403318
32 4 21 7 66.9000000 52.724567 19.9280133
33 5 0 7 216.7857143 39.957829 15.1026398
34 5 2 7 212.2000000 27.037135 10.2190765
35 5 5 7 115.5000000 37.094070 14.0202405
36 5 8 7 46.1000000 34.925492 13.2005952
37 5 12 7 29.3142857 24.761222 9.3588621
38 5 15 6 10.0666667 13.441974 5.4876629
39 5 19 6 6.4000000 11.692733 4.7735382
40 5 21 6 5.3666667 12.662017 5.1692467
41 6 0 7 206.6857143 40.359155 15.2543269
42 6 2 7 197.0428571 40.608327 15.3485048
43 6 5 7 106.2142857 58.279654 22.0276388
44 6 8 7 46.0571429 62.373014 23.5747833
45 6 12 7 31.7571429 49.977457 18.8897031
46 6 15 7 28.1142857 45.437995 17.1739480
47 6 19 7 26.2857143 38.414946 14.5194849
48 6 21 7 32.7428571 53.203003 20.1088450
49 7 0 7 193.2000000 37.300447 14.0982437
50 7 2 7 133.2428571 26.462606 10.0019250
51 7 5 7 3.8142857 7.445900 2.8142857
52 7 8 7 0.7142857 1.496026 0.5654449
53 7 12 7 0.0000000 0.000000 0.0000000
54 7 15 7 0.0000000 0.000000 0.0000000
55 7 19 7 0.0000000 0.000000 0.0000000
56 7 21 7 0.0000000 0.000000 0.0000000
My code is as follows:
ggplot(data7, aes(Days, mean, color=Treatment)) +
geom_line() +
geom_errorbar(aes(ymin=mean-se, ymax=mean+se), width=0.5, size= 0.25) +
geom_point(size=2.5) +
scale_colour_hue(limits = c("1", "2", "3", "4", "5", "6", "7")) +
scale_x_continuous(expand = c(0, 0), limits = c(0, NA), breaks = scales::pretty_breaks(n = 10)) +
scale_y_continuous(expand = c(0, 0), limits = c(0, NA), breaks = scales::pretty_breaks(n = 8)) +
theme_classic() +
theme(axis.text = element_text(color = "#000000"), plot.title = element_text(hjust = 0.5)) +
coord_cartesian(clip = 'off')
Here's one approach that omits the axis lines/ticks and then explicitly layers them below the rest of the plot layers. Because the new lines/ticks are drawn as literal objects, they will then ignore any other theming you may later apply. With control comes responsibility ...
This method has the side-effect of a "simple" axis tick, just the + symbol, which shows as a cross-line at each point. This is in contrast to the standard way (typically just pointing outwards). I'm guessing that something more robust could be devised, but I thought "simple" up-front could be adapted in other ways.
Taking the literal code of your ggplot(...) + ... and storing as gg, no changes. First we'll extract the tick marks. If you are confident enough (or not OCD-enough) to determine the tick locations yourself, then feel free to hard-code it. This method (of using ggplot_build then extracting the ...$x$breaks) has the advantage of matching the tick and label locations, especially if they might change with different/updated data.
ticks <- with(ggplot_build(gg)$layout$panel_params[[1]],
na.omit(rbind(
data.frame(x = x$breaks, y = 0),
data.frame(x = 0, y = y$breaks)
)))
head(ticks,3); tail(ticks,3)
# x y
# 1 0 0
# 2 2 0
# 3 4 0
# x y
# 16 0 600
# 17 0 800
# 18 0 1000
From here, I'll take a cue from https://stackoverflow.com/a/20250185/3358272 and prepend some layers below all of the others. (This is where I identify the + symbol for axis ticks, using shape=3.)
gg$layers <- c(
geom_hline(aes(yintercept = 0)),
geom_vline(aes(xintercept = 0)),
geom_point(data = ticks, aes(x, y), shape = 3, inherit.aes = FALSE),
gg$layers)
Now we just plot the previously-generated gg, adding a cue to omit the theme axis lines/ticks.
gg + theme(axis.line = element_blank(), axis.ticks = element_blank())
Data, including converting Treatment to character (to avoid continuous/discrete warnings from scale_colour_hue):
data7 <- read.table(header=TRUE, text = "
Treatment Days N mean sd se
1 1 0 7 204.7000000 41.579963 15.7157488
2 1 2 7 255.0571429 41.116617 15.5406205
3 1 5 7 290.6000000 49.506498 18.7116974
4 1 8 7 330.8142857 49.044144 18.5369442
5 1 12 7 407.5142857 95.584194 36.1274294
6 1 15 7 540.8571429 164.299390 62.0993323
7 1 19 7 737.5285714 308.786359 116.7102736
8 1 21 7 978.4571429 502.506726 189.9296898
9 2 0 7 205.7428571 46.902482 17.7274721
10 2 2 7 227.5571429 47.099889 17.8020846
11 2 5 7 232.4857143 59.642922 22.5429054
12 2 8 7 247.9857143 66.478529 25.1265220
13 2 12 7 272.0428571 79.173162 29.9246423
14 2 15 7 289.1142857 82.847016 31.3132288
15 2 19 7 312.3857143 105.648591 39.9314140
16 2 21 7 334.7142857 121.569341 45.9488920
17 3 0 7 212.2285714 47.549263 17.9719320
18 3 2 7 235.4142857 52.689671 19.9148237
19 3 5 7 177.0714286 54.895225 20.7484447
20 3 8 7 205.2571429 72.611451 27.4445489
21 3 12 7 247.8142857 119.369558 45.1174522
22 3 15 7 280.4285714 140.825847 53.2271669
23 3 19 7 366.9142857 210.573799 79.5894149
24 3 21 7 451.0428571 289.240793 109.3227438
25 4 0 7 211.6857143 24.329161 9.1955587
26 4 2 7 227.8428571 28.762525 10.8712127
27 4 5 7 205.9428571 49.148919 18.5765451
28 4 8 7 153.1142857 25.189246 9.5206399
29 4 12 7 128.2571429 43.145910 16.3076210
30 4 15 7 104.1714286 45.161662 17.0695038
31 4 19 7 85.4714286 51.169708 19.3403318
32 4 21 7 66.9000000 52.724567 19.9280133
33 5 0 7 216.7857143 39.957829 15.1026398
34 5 2 7 212.2000000 27.037135 10.2190765
35 5 5 7 115.5000000 37.094070 14.0202405
36 5 8 7 46.1000000 34.925492 13.2005952
37 5 12 7 29.3142857 24.761222 9.3588621
38 5 15 6 10.0666667 13.441974 5.4876629
39 5 19 6 6.4000000 11.692733 4.7735382
40 5 21 6 5.3666667 12.662017 5.1692467
41 6 0 7 206.6857143 40.359155 15.2543269
42 6 2 7 197.0428571 40.608327 15.3485048
43 6 5 7 106.2142857 58.279654 22.0276388
44 6 8 7 46.0571429 62.373014 23.5747833
45 6 12 7 31.7571429 49.977457 18.8897031
46 6 15 7 28.1142857 45.437995 17.1739480
47 6 19 7 26.2857143 38.414946 14.5194849
48 6 21 7 32.7428571 53.203003 20.1088450
49 7 0 7 193.2000000 37.300447 14.0982437
50 7 2 7 133.2428571 26.462606 10.0019250
51 7 5 7 3.8142857 7.445900 2.8142857
52 7 8 7 0.7142857 1.496026 0.5654449
53 7 12 7 0.0000000 0.000000 0.0000000
54 7 15 7 0.0000000 0.000000 0.0000000
55 7 19 7 0.0000000 0.000000 0.0000000
56 7 21 7 0.0000000 0.000000 0.0000000")
data7$Treatment <- as.character(data7$Treatment)
A fairly straightforward way to do this is just to move the panel in front of the axes once the plot elements are created (i.e. as a grobTree). The grobTree contains a layout data frame which allows you to move plot elements forwards or backwards by adjusting their z component.
If you store your plot as p, then the code would be:
ggp <- ggplot_gtable(ggplot_build(p))
ggp$layout$z[which(ggp$layout$name == "panel")] <- max(ggp$layout$z) + 1
grid::grid.draw(ggp)
Plot code:
This is just the original plot except I have added a vline at 0 and an hline at 0 in case bringing the panel forwards clips your axis lines).
p <- ggplot(data7, aes(Days, mean, color=Treatment)) +
geom_hline(aes(yintercept = 0)) +
geom_vline(aes(xintercept = 0)) +
geom_line() +
geom_errorbar(aes(ymin=mean-se, ymax=mean+se), width=0.5, size= 0.25) +
geom_point(size=2.5) +
scale_colour_hue(limits = c("1", "2", "3", "4", "5", "6", "7")) +
scale_x_continuous(expand = c(0, 0), limits = c(0, NA), breaks = scales::pretty_breaks(n = 10)) +
scale_y_continuous(expand = c(0, 0), limits = c(0, NA), breaks = scales::pretty_breaks(n = 8)) +
theme_classic() +
theme(axis.text = element_text(color = "#000000"), plot.title = element_text(hjust = 0.5)) +
coord_cartesian(clip = 'off')

Can I plot the number count in ggplot2 using geom_text instead the size of points (geom_count)?

I'm trying to plot a ggplot graph and instead of the size of point indicating the count, I need to plot the overlapping count number. Can you help me?
https://imgur.com/a/pm1SsWd
Thank you very much!
My data:
ID CIM DD
1 8 8
2 8 8
3 8 4
4 4 4
5 2 2
6 8 8
7 8 8
8 8 8
9 2 2
10 2 2
11 2 4
12 4 4
13 8 4
14 2 2
15 4 4
16 4 8
17 2 4
18 16 8
19 8 16
20 16 16
21 2 4
22 16 8
23 8 8
24 8 8
25 8 8
26 4 4
27 1 2
28 4 8
29 8 8
30 2 4
31 8 8
32 2 2
33 1 2
34 4 8
35 8 8
36 16 8
37 8 8
38 4 4
39 4 8
40 4 8
41 8 8
42 8 8
43 2 2
I used the code below to make an overlapping count graph as shown in an image link:
https://imgur.com/a/pm1SsWd
breaks = c(1,2,4,8,16)
labels = as.character(breaks)
ggplot(data = Data,aes(CIM,DD)) +
geom_count()+
scale_x_continuous(limits = c(1, 32), breaks = breaks, labels = labels,name = "CIM")+
scale_y_continuous(limits = c(1, 32), breaks = breaks, labels = labels,name = "DD")
Take a look at this example:
Add count as label to points in geom_count
You could do the following with your data:
p <- ggplot(data = Data,aes(CIM,DD)) +
geom_count(show.legend = FALSE)+
scale_x_continuous(limits = c(1, 32), breaks = breaks, labels = labels,name = "CIM") +
scale_y_continuous(limits = c(1, 32), breaks = breaks, labels = labels,name = "DD") +
scale_size_continuous(range = c(10, 10))
p + geom_text(data = ggplot_build(p)$data[[1]], aes(x, y, label = n), color = "#ffffff")
You can adjust the range in scale_size_continuous if you wish to vary the size of points.

Numeric axis labels in incorrect order

I have the following generated data frame called Raw_Data:
Time Velocity Type
1 10 1 a
2 20 2 a
3 30 3 a
4 40 4 a
5 50 5 a
6 10 2 b
7 20 4 b
8 30 6 b
9 40 8 b
10 50 9 b
11 10 3 c
12 20 6 c
13 30 9 c
14 40 11 c
15 50 13 c
When plotting each Type, with the following:
ggplot(Raw_Data, aes(x=Time, y=Velocity))+geom_point() + facet_grid(Type ~.)
the y-axis increments as:
1, 11, 13, 2, 3, 4, 5, 6, 7, 8, 9
The y-axis labels should be in order - why has 11 and 12 appeared after 1?
I have created the data frame as follows using your sample data:
mydata <- read.table(text="Time Velocity Type
1 10 1 a
2 20 2 a
3 30 3 a
4 40 4 a
5 50 5 a
6 10 2 b
7 20 4 b
8 30 6 b
9 40 8 b
10 50 9 b
11 10 3 c
12 20 6 c
13 30 9 c
14 40 11 c
15 50 13 c", header=TRUE)
Followed by the command
ggplot(mydata, aes(x=Time, y=Velocity))+geom_point() + facet_grid(Type ~.)
which correctly displays the plot as shown in picture below
Note: changing the call to ggplot as shown below:
ggplot(mydata, aes(x=Time, y=as.character(Velocity))) +
geom_point() +
facet_grid(Type ~.)
reproduces the problem you mentioned. So you need to convert the Velocity variable to appropriate type i.e. integer in your case.

How to separate one graph to different new graphs?

I have a database which includes laws per different years from 1985-2012. I would like to make different 17 plots (and thus, to make a function) for each year that will include its' values and the years before, and to keep the same design of x and y axis for each graph, as you can see in the following figure:
That's how I made the graph above, between 1985-2012:
> v <- ddply(leg.by.melt, .(year), summarise, count = sum(value))
> v
year count
1 1985 2
2 1987 5
3 1988 9
4 1989 12
5 1990 14
6 1991 11
7 1992 16
8 1993 23
9 1994 25
10 1995 10
11 1996 11
12 1997 24
13 1998 35
14 1999 32
15 2000 24
16 2001 22
17 2002 65
18 2003 42
19 2004 56
20 2005 42
21 2006 47
22 2007 36
23 2008 16
24 2009 54
25 2011 28
> ggplot(v, aes(x = year, y = count))
+ theme_bw()
+ geom_contour(colour = "black", lty = 3, lend = 2, lwd = 1, stat = "identity")
+ scale_x_continuous(breaks = round(seq(min(v$year), max(v$year), by = 1),1))
+ scale_y_continuous(breaks = round(seq(min(v$count), max(v$count), by = 3),1))
+ theme(axis.text.x = element_text(angle = 0, vjust = 0.2))
As I wrote before, I would like to have a different 17 plots - for 1985, for 1985+1986, for 1985+1986+1987 and so forth, and stil to have the same design of the x and y axis (x axis from 1985:2012 and y axis from 2 to 65).
How can I make a function to achieve it?
if you plot is called p, I would do the following,
plyr::l_ply(v$year, function(.year) p %+% subset(v, year <= .year), .print=TRUE)

Repeating X axis labels and legend labels in ggplot2

I'm not sure why I am having such a problem with my x-scale labels repeating as opposed to just labeling where there is a measured point. Additionally, my labels for my legend are not working.
FamIncome Ethnicity mean.bmi
1 1 1 28.54250
2 1 2 26.66300
3 1 3 26.62105
4 1 4 29.51396
5 1 5 25.66722
6 2 1 29.62404
7 2 2 28.08393
8 2 3 28.62215
9 2 4 28.97561
10 2 5 25.57714
11 3 1 29.52630
12 3 2 28.27235
13 3 3 29.67060
14 3 4 31.36768
15 3 5 26.13361
16 4 1 30.83368
17 4 2 30.80814
18 4 3 29.29594
19 4 4 29.18521
20 4 5 24.80550
21 5 1 29.76500
22 5 2 29.24404
23 5 3 28.89435
24 5 4 31.48172
25 5 5 28.02522
26 6 1 30.05087
27 6 2 29.88574
28 6 3 29.53793
29 6 4 30.97993
30 6 5 25.57857
31 7 1 30.31787
32 7 2 29.28055
33 7 3 28.50421
34 7 4 30.65427
35 7 5 26.66094
36 8 1 29.15000
37 8 2 29.02789
38 8 3 28.36507
39 8 4 33.51915
40 8 5 28.38263
41 9 1 28.17679
42 9 2 28.74731
43 9 3 28.06196
44 9 4 31.38483
45 9 5 26.96000
46 10 1 28.71633
47 10 2 33.44409
48 10 3 30.63048
49 10 4 30.22587
50 10 5 27.36375
51 14 1 30.78161
52 14 2 27.43575
53 14 3 28.96817
54 14 4 32.22378
55 14 5 25.62778
56 15 1 29.15982
57 15 2 27.42672
58 15 3 27.60567
59 15 4 30.05013
60 15 5 26.80271
code below:
a <- ggplot(nh1, aes(x=FamIncome, y=mean.bmi)) + geom_line(aes(group=Ethnicity, colour = Ethnicity)) + geom_point()
a = a + labs(list(title="Average BMI versus Family Income", x = "Family Income", y = "Average BMI"))
a = a + scale_x_discrete(breaks=c("1","2","3","4","5","6","7","8","9","10","14","15"),
labels = c("0-4,999", "5K-9,999", "10K-14,999", "15K-19,999", "20K-24,999", "25K-34,999", "35K-44,999", "45K-54,999", "55K-64,999", "65K-74,999", "75K-100K", "Over 100K"))
a = a + theme(axis.text.x=element_text(angle=-90))
a = a + scale_colour_continuous(name = "Ethnicity",
breaks=c("5","4","3","2","1"),
labels=c("Other Race/Multi", "Black","White","Other Hispanic", "Mexican-American"))
a
I cannot post a picture of the image that I'm getting until I get 2 more "reputation" points
Try converting your x variable to a factor:
a <- ggplot(nh1, aes(x=factor(FamIncome), y=mean.bmi)) + geom_line(aes(group=Ethnicity, colour = factor(Ethnicity)))
a = a + labs(list(title="Average BMI versus Family Income", x = "Family Income", y = "Average BMI"))
a = a + scale_x_discrete("Family Income", labels = c("0-4,999", "5K-9,999", "10K-14,999", "15K-19,999", "20K-24,999", "25K-34,999", "35K-44,999", "45K-54,999", "55K-64,999", "65K-74,999", "75K-100K", "Over 100K"))
a = a + opts(axis.text.x=theme_text(angle=-90))
a = a + scale_colour_discrete(name = "Ethnicity",
breaks=c("5","4","3","2","1"),
labels=c("Other Race/Multi", "Black","White","Other Hispanic", "Mexican-American"))
With a numeric x variable, ggplot is treating it as a numeric scale, when you really intended it to be categorical. Also note the confusing between fill and colour. fill is for two dimensional filled regions.

Resources