Using gganimate with geom_point and geom_line - r

working with nfl data here.. trying gganimate for the first time... trying to use geom_point and geom_line but geom_line will not appear..
data frame here..
week = c(1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,17)
plays= c(9,10,5,3,4,4,3,5,6,5,11,12,6,11,7,3)
mean_epa= c(.67, .27, -.5, -1.09, -.3, .68, -.72, -.32, 1.03, 1.05, .56, .17, -.61, -.05, -.14, 1.5)
CLEdrive1b <- data.frame(week,plays,mean_epa)
within week variable, 7 is missing (because browns did not have game week 7)... not sure if that is causing issues?
my first attempt below
p <- ggplot(CLEdrive1b, aes(x=as.factor(week),y=mean_epa)) +
theme_minimal() +
geom_point(aes(group = seq_along(week)), color = "orange", size = 4) +
geom_line(alpha = 0.5)+
transition_reveal(week)+
geom_text(aes(label = mean_epa))+
xlab("Week") +
ylab("EPA/Play") +
labs(title="Browns Opening Drives",
subtitle = "EPA/Drive by Week",
caption="Data from nflscrapR")+
theme(axis.title = element_text(size = 10),
axis.text = element_text(size = 9),
plot.title = element_text(size = 15),
plot.subtitle = element_text(size = 10),
plot.caption = element_text(size = 8))
animate(p)
alternative method I tried..
pi <- ggplot(CLEdrive1b, aes(week,y=mean_epa)) +
theme_minimal() +
geom_point(aes(group = seq_along(week)), color = "orange", size = 4) +
geom_line(alpha = 0.5)+
transition_reveal(week)+
geom_text(aes(label = mean_epa))+
xlab("Week") +
ylab("EPA/Play") +
labs(title="Browns Opening Drives",
subtitle = "EPA/Drive by Week",
caption="Data from nflscrapR")+
theme(axis.title = element_text(size = 10),
axis.text = element_text(size = 9),
plot.title = element_text(size = 15),
plot.subtitle = element_text(size = 10),
plot.caption = element_text(size = 8))
animate(pi)
removed as.factor from x variable (week).. and geom_line appears! but x-axis loses labels I am seeking and geom_text stops performing how it was above..
thank you for spending time to help...

The problem is that when converting it to factors, ggplot doesn't "know" any more how to group the week variable, and does not connect the observations any more. Adding aes(group = 1) to your geom_line is all you need.
library(gganimate)
#> Loading required package: ggplot2
library(ggplot2)
week = c(1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,17)
plays= c(9,10,5,3,4,4,3,5,6,5,11,12,6,11,7,3)
mean_epa= c(.67, .27, -.5, -1.09, -.3, .68, -.72, -.32, 1.03, 1.05, .56, .17, -.61, -.05, -.14, 1.5)
CLEdrive1b <- data.frame(week,plays,mean_epa)
p <- ggplot(CLEdrive1b, aes(x=as.factor(week),y=mean_epa)) +
geom_point(aes(group = seq_along(week)), color = "orange", size = 4) +
geom_line(alpha = 0.5, aes(group = 1))+
transition_reveal(week)+
geom_text(aes(label = mean_epa))
animate(p)
Created on 2020-02-03 by the reprex package (v0.3.0)

Related

Creating Dual Axis plot (bar and line)

I want to create a dual axis plot in ggplot R with a dual bar and line plot, like this one created in excel.
The y axis scales are different.
my data is as follows;
I've created a bar plot and line plot. But unsure on how to put them together (I've tried man various ways and they don't seem to work).
Here is my code for the bar plot.
inf_conc <- ggplot(data=data, aes(x=Day, y=inf)) +
geom_bar(stat="identity", width=0.4, color="red3", fill="red3") +
ggtitle("Influent Microplastic Concentration \n and Flow Rate") +
# \n splits long titles into multiple lines
xlab("Day") +
ylab("Microplastic Concentration (MPs/L)") +
scale_y_continuous(limits =c(0, 50), breaks = seq(0, 50, 5))
inf_conc + theme(axis.text = element_text(size = 20, colour = "black"),
plot.title = element_text(size =25, hjust = 0.5,
face = "bold"), axis.title = element_text(size = 20,
face = "bold", margin = 5))
inf_conc + theme(axis.text = element_text(size = 20, colour = "black"),
plot.title = element_text (size =25, hjust = 0.5, face = "bold"),
axis.title = element_text(size = 20, face = "bold", margin = 20))
and here is the code for the line plot:
inf_flow <- ggplot(data=data, aes(x=Day, y=flow, group = 1)) +
geom_line(stat = "identity", colour ="blue4") +
geom_point(colour ="blue4") +
ylab("Inlet flow L/s")+
xlab("Day")+
scale_y_continuous(limits=c(0,800), breaks = seq(0, 800, 100))
inf_flow + theme(axis.text = element_text(size = 20, colour = "black"),
plot.title = element_text (size =25, hjust = 0.5, face = "bold"),
axis.title = element_text(size = 20, face = "bold", margin = 5))
inf_flow + theme(axis.text = element_text(size = 20,
colour = "black"), plot.title = element_text (size =25, hjust = 0.5,
face = "bold"), axis.title = element_text(size = 20, face = "bold",
margin = 20))
Can anyone help with how I can get these onto one dual axis graph please.
GGplot doesn't make it especially easy, but you can do it:
library(ggplot2)
my_dat <- data.frame(
Day = paste("Day",rep(1:3, each=3), rep(c("(AM)", "(Midday)", "(PM)"), 3), sep= " "),
day_num = 1:9,
inf = seq(from = 13,to = 45, length=9),
flow = runif(9, 580, 740)
)
ggplot() +
geom_bar(data=my_dat, aes(x=day_num, y=inf, fill = "Influent Concentration"), stat="identity", width=.6) +
geom_line(data=my_dat, aes(x=day_num, y=flow*(50/800), colour="FLow Rate. L/s")) +
scale_fill_manual(values="red") +
scale_colour_manual(values="blue") +
scale_x_continuous(breaks=1:9, labels=my_dat$Day) +
scale_y_continuous(sec.axis = sec_axis(trans = ~.x*800/50, name = "Flow Rate L/S"), limits = c(0,50), name = "Influent. MPs/L") +
labs(fill="", colour="", x="") +
theme(legend.position="bottom",
axis.text.x = element_text(angle=45, hjust=1))
Created on 2023-01-17 by the reprex package (v2.0.1)
The main things you have to do are to
Transform the second-axis series to have the same range(ish) as the first-series axis. In your case, the excel graph had the second y-axis going from 0-800 and the first y-axis going from 0-50, so the transformation is simple, you multiply the second series values by 50/800.
In the scale_y_continuou() function there is an argument sec.axis which allows you to plot a second axis on the right-hand side of the plot. Here, you need to specify the trans argument to transform the values you're plotting back into the original values. That's what trans = ~.x*800/50 does.
EDIT: Modifying OP's code
I modified your code as much as I can without actually having the data. The picture of the data that you provided does not give enough information about the data, if you use dput(data) and post the results, I could likely help more. For now, try this:
inf_plot <- ggplot(data=data, aes(x=Day))+
geom_bar(aes(y=inf, fill="Influent conc"), stat = "identity", width=0.4)+
geom_line(aes(y=flow*(50/800), colour="flow rate"), size = 1.4, group=1)+
ggtitle("Influent Microplastic Concentration \n and Influent Flow Rate")+
xlab("\n\nDay") +
ylab("Microplastic Concentration (MPs/L)\n\n")+
scale_fill_manual(values="red4") +
scale_colour_manual(values="blue4") +
scale_y_continuous(sec.axis = sec_axis(~.*800/50, name = "Inlet flow rate (L/s)\n\n"), limits = c(0,50))
inf_plot + theme(axis.text = element_text( size = 20, colour = "black"),
plot.title = element_text (size =25, hjust = 0.5, vjust = 5, face = "bold"),
axis.title = element_text (size = 20, face = "bold"),
plot.margin =unit(c(1.5, 1.5, 1.5, 1.5), "cm"),
legend.position = "bottom")
The answer was a great help in how to transform my axis.
Initially produced the graph a slightly different way, but incorporated the same transformation of axis.
However, I can't seem to get the legend to appear at the bottom of the graph with the following code.
inf_plot <- ggplot(data=data, aes(x=Day))+
geom_bar(aes(y=inf, fill="Influent conc"), stat = "identity", width=0.4,
colour="red4", fill = "red4")+
ggtitle("Influent Microplastic Concentration \n and Influent Flow Rate")+
xlab("\n\nDay") +
ylab("Microplastic Concentration (MPs/L)\n\n")+
geom_line(aes(y=flow*(50/800), colour="flow rate"), size = 1.4, colour ="blue4", group = 1)+
scale_fill_manual(values="red4") +
scale_colour_manual(values="blue4") +
scale_y_continuous(sec.axis = sec_axis(~.*800/50, name = "Inlet flow rate (L/s)\n\n"), limits = c(0,50))
inf_plot + theme(axis.text = element_text( size = 20, colour = "black"),
plot.title = element_text (size =25, hjust = 0.5, vjust = 5, face = "bold"),
axis.title = element_text (size = 20, face = "bold"),
plot.margin =unit(c(1.5, 1.5, 1.5, 1.5), "cm"),
legend.position = "bottom")
enter image description here

ggplot: Using geom_col with facet_wrap

I have been using R for 6 months now (fairly new).
I have created a nice graph using the facet_wrap funciton, with geom_point.
However, i don't seem to have success with geom_col, when plotting another parameter i am interested in.
The code is below:
T <- Titers %>%
ggplot(aes(Sample_ID, Titer)) +
geom_col(aes(col=Day), size=1.1) +
facet_wrap(Strategy~Additives) +
scale_color_manual(values = Ahmad) +
ylab('Titer mg/L') +
xlab('Time (Day)') +
ggtitle('All data') +
geom_label_repel(aes(label = Sample_ID), data = tail(Titers, 14), nudge_x =
2, direction = "y", segment.size = 0.2, hjust = 0) + theme(strip.text.x =
element_text(size = 12), axis.title = element_text(size = 14), axis.text =
element_text(size = 14), legend.position = "none")
The code that have been working fine is the following:
Q2 <- USP20005 %>%
ggplot(aes(Day, Diameter)) +
geom_line(aes(col=Sample_ID), size=1.1) +
facet_wrap(Strategy~Additives) +
scale_color_manual(values = Ahmad) +
ylab('VCD E6 cells/mL') +
xlab('Time (Day)') +
ggtitle('All data') +
geom_label_repel(aes(label = Sample_ID), data = tail(USP20005, 24), nudge_x
= 2, direction = "y", segment.size = 0.2, hjust = 0) +
theme(strip.text.x = element_text(size = 12), axis.title = element_text(size =
14), axis.text = element_text(size = 14), legend.position = "none") +
scale_x_continuous(breaks = seq(0, 14, 2), limits = c(0, 14)) +
scale_y_continuous(breaks = seq(10, 20, 2), limits = c(10, 20))
Why are there spaces vetween the columns, even though i used facet_warp to split the samples into different boxes (it seems R is still reserving the empty spots?)
Just to be clear: I want to see every 2-4 samples together in on box, where the bars for each sample on the different days are stuck to each other. I WAS able to plot them stacked, but i dont want that.
What am I doing wrong here? Any help would be much appreciated.
Thank you in advance
Ahmad
If you use scale_x_*(), the x-axis will be fixed and maintain the spaces.

ggplot2 barplot with dual Y-axis and error bars

I am trying to generate a barplot with dual Y-axis and error bars. I have successfully generated a plot with error bars for one variable but I don't know how to add error bars for another one. My code looks like this. Thanks.
library(ggplot2)
#Data generation
Year <- c(2014, 2015, 2016)
Response <- c(1000, 1100, 1200)
Rate <- c(0.75, 0.42, 0.80)
sd1<- c(75, 100, 180)
sd2<- c(75, 100, 180)
df <- data.frame(Year, Response, Rate,sd1,sd2)
df
# The errorbars overlapped, so use position_dodge to move them horizontally
pd <- position_dodge(0.7) # move them .05 to the left and right
png("test.png", units="in", family="Times", width=2, height=2.5, res=300) #pointsize is font size| increase image size to see the key
ggplot(df) +
geom_bar(aes(x=Year, y=Response),stat="identity", fill="tan1", colour="black")+
geom_errorbar(aes(x=Year, y=Response, ymin=Response-sd1, ymax=Response+sd1),
width=.2, # Width of the error bars
position=pd)+
geom_line(aes(x=Year, y=Rate*max(df$Response)),stat="identity",color = 'red', size = 2)+
geom_point(aes(x=Year, y=Rate*max(df$Response)),stat="identity",color = 'black',size = 3)+
scale_y_continuous(name = "Left Y axis", expand=c(0,0),limits = c(0, 1500),breaks = seq(0, 1500, by=500),sec.axis = sec_axis(~./max(df$Response),name = "Right Y axis"))+
theme(
axis.title.y = element_text(color = "black"),
axis.title.y.right = element_text(color = "blue"))+
theme(
axis.text=element_text(size=6, color = "black",family="Times"),
axis.title=element_text(size=7,face="bold", color = "black"),
plot.title = element_text(color="black", size=5, face="bold.italic",hjust = 0.5,margin=margin(b = 5, unit = "pt")))+
theme(axis.text.x = element_text(angle = 360, hjust = 0.5, vjust = 1.2,color = "black" ))+
theme(axis.line = element_line(size = 0.2, color = "black"),axis.ticks = element_line(colour = "black", size = 0.2))+
theme(axis.ticks.length = unit(0.04, "cm"))+
theme(plot.margin=unit(c(1,0.1,0.1,0.4),"mm"))+
theme(axis.title.y = element_text(margin = margin(t = 0, r = 4, b = 0, l = 0)))+
theme(axis.title.x = element_text(margin = margin(t = 0, r = 4, b = 2, l = 0)))+
theme(
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank())+
ggtitle("SRG3")+
theme(legend.position="top")+
theme( legend.text=element_text(size=4),
#legend.justification=c(2.5,1),
legend.key = element_rect(size = 1.5),
legend.key.size = unit(0.3, 'lines'),
legend.position=c(0.79, .8), #width and height
legend.direction = "horizontal",
legend.title=element_blank())
dev.off()
and my plot is as follows:
A suggestion for future questions: your example is far from being a minimal reproducible example. All the visuals an the annotations are not related to your problem but render the code overly complex which makes it harder for others to work with it.
The following would be sufficient:
ggplot(df) +
geom_bar(aes(x = Year, y = Response),
stat = "identity", fill = "tan1",
colour = "black") +
geom_errorbar(aes(x = Year, ymin = Response - sd1, ymax = Response + sd1),
width = .2,
position = pd) +
geom_line(aes(x = Year, y = Rate * max(df$Response)),
color = 'red', size = 2) +
geom_point(aes(x = Year, y = Rate * max(df$Response)),
color = 'black', size = 3)
(Notice that I've removed stat = "identity" in all geom_s because this is set by default. Furthermore, y is not a valid aestetic for geom_errorbar() so I omitted that, too.)
Assuming that the additional variable you would like to plot error bars for is Rate * max(df$Response)) and that the relevant standard deviation is sd2, you may simply append
+ geom_errorbar(aes(x = Year, ymin = Rate * max(df$Response) - sd2,
ymax = Rate * max(df$Response) + sd2),
colour = "green",
width = .2)
to the code chunk above. This yields the output below.

overlay geom_point with position=dodge and facet grid in ggplot2

Considering the following data, I am able to generate a plot which describes how the risk of a react over a time interval changes.
risk_1 <- c(0.121,0.226,0.333,0.167,0.200,0.273,0.138,0.323,0.394,0.250,0.200,0.545,0.190,0.355,0.515,0.333,0.300,0.818)
risk_minus_SE <- c(0.060,0.114,0.198,0.047,0.057,0.097,0.072,0.186,0.247,0.089,0.057,0.280,0.109,0.211,0.352,0.138,0.108,0.523)
risk_plus_SE <- c(0.229,0.398,0.504,0.448,0.510,0.566,0.249,0.499,0.563,0.532,0.510,0.787,0.309,0.531,0.675,0.609,0.603,0.949)
Status <- rep(c(rep('With placebo',3),rep('With drug',3)),3)
durtn <- rep(c('(3-15]','(15-30]','(30-46]'),6)
react <- c(rep("x\u226516",6),rep("x\u226509",6),rep("x\u226504",6))
df1 <- data.frame(risk_1, risk_minus_SE, risk_plus_SE, Status, durtn, react)
dodge <- position_dodge(width=0.45)
ggplot(df1,aes(colour=react, y=risk_1, x=durtn)) +
geom_point(aes(shape=durtn), shape=16, size = 5, position=dodge) +
geom_errorbar(aes(ymin=risk_minus_SE, ymax=risk_plus_SE), position = dodge, width=0.5, size=1, lty=1) +
scale_colour_manual(values = c('black','red','blue')) +
facet_grid(~Status) +
scale_shape_manual(values = c(8,19))+
theme_bw() +
scale_x_discrete(limits=c('(3-15]','(15-30]','(30-46]')) +
coord_cartesian(ylim = c(0, 0.8)) +
theme(legend.position = c(.1, .85), legend.background = element_rect(colour = "black"),
plot.title = element_text(lineheight=1.5, face="bold", size=rel(1.5), hjust = 0.5),
panel.grid.major.x = element_blank(),
axis.text.x = element_text(vjust=0.5, size=16),
axis.text.y = element_text(vjust=0.5, size=16),
axis.title.y = element_text(size=20),
axis.title.x = element_text(size=20),
legend.text = element_text(size = 16, face = "bold"),
strip.text = element_text(size=25)) +
xlab("\ntime (min)") + ylab("Risk")
What I want to do is overlay a series of points at given x and y coordinates.
That being at With drug & durtn==(3,15], manually insert points at.....
Risk==0.5 for react=x≥04 in black
Risk==0.2 for react=x≥09 in red
Risk==0.0 for react=x≥16 in blue
Such that the desired output should look like
How does one use the geom_point() in combination with a facet_grid and dodge
First, you have to create a separate data frame that contains the data for the additional points.
dat <- data.frame(risk_1 = c(0.5, 0.2, 0),
react = levels(df1$react),
durtn = '(3-15]',
Status = 'With drug')
This new data frame dat can be used with geom_point to add an additional layer to the existing plot.
+ geom_point(data = dat, position = dodge, shape = 4, size = 5, show.legend = FALSE)

how to get and modify size legend in ggplot2

I am having some trouble displaying the size legend in my plot and changing the name of my size legend.
My data is corp already has a size column which is either of the values 5, 10, 20
I am using ggplot2 I already have a legend for the color
I want to add one for the size and manually change the size labels..
How do I increase the the font of the legend ? It's super tiny (FIN, IND UTIL)
also the 15 for the size shouldnt be there i want to just omit it and display both legends side by side.
p <- ggplot(corp, aes(x=annRisk, y=annRet, color = corp$subsector1, face = "bold"))
p<- p + geom_point(aes(size = corp$Colsize), alpha = 0.55)
p<-p + scale_size(range = c(8, 20))
p<-p + scale_colour_manual("", values = c("UTIL" = "#fdcc8b", "IND" = "#fc8d59", "FIN" = "#d7301f",
"ABS" = "#74a9cf", "CMBS" = "#0570b0", "LA" = "#8c96c6", "SOV"= "#88419d", "SUPRA" = "#b3cde3"))
p<-p+labs(title = "SOME TITLE")
print(p)
p<-p+theme(plot.title = element_text(face = "bold", size = 20))
p<-p+theme(axis.title.x = element_text(size = 20), axis.text.x = element_text(size = 13))
p<-p+theme(axis.title.y = element_text(size = 20), axis.text.y = element_text(size = 13))
p<-p+geom_text(aes(label=ifelse(Colsize>=10,subsector2,"")), size=5,color = "black", face = "bold", hjust=-0.1, vjust = 0.1)
p<-p+scale_x_continuous(labels = percent, name = "Annualized Risk", limits = c(0.05, 0.09))
p<-p+scale_y_continuous(labels = percent, name = "Annualized Return", limits = c(0.04, 0.08))
p<-p+ theme(legend.position = "bottom")
print(p)
Although I can't use your data yet, you can try adding the following code:
p <- p + theme(legend.position = "bottom",
legend.title = element_blank(),
legend.text = element_text(size=14),
legend.box = "horizontal")
p <- p + scale_size_manual(values=c(5,10,20), labels = c("5","10","20"))

Resources