ggplot - using annotate across facets - r

This is a basic question but haven't been able to find the answer on here. I am creating a figure with ggplot from the following (overly simplified) data:
df.for.graph <- setNames(data.frame(matrix(ncol = 5,nrow = 8)), c("xp","yp","loc","cong","emotion"))
df.for.graph$xp <- c(948.7, 977.2, 1023.4, 953.3, 979.4,936.3, 911.6,877.2)
df.for.graph$yp <- c(923.0, 893.0, 294.9, 241.5, 898.6, 960.9, 154.4, 263.4)
df.for.graph$loc <- as.factor(c("Bottom", "Bottom", "Top", "Top", "Bottom", "Bottom", "Top", "Top"))
df.for.graph$cong <- as.factor(c("Incongruent","Congruent","Incongruent","Congruent", "Incongruent","Congruent","Incongruent","Congruent"))
df.for.graph$emotion <- as.factor(c("Angry", "Angry", "Angry", "Angry", "Happy","Happy", "Happy","Happy"))
My call to ggplot is as follows:
ggplot(df.for.graph,aes(x=xp,y=yp,color=loc,shape=cong)) +
geom_point() +
scale_color_manual(values=c("red","blue")) +
scale_shape_manual(values=c(1,4)) +
scale_fill_manual(values=c("green", "yellow")) +
scale_x_continuous(breaks = seq(from = 0, to = 1920, by = 160), limits=c(0,1920)) +
scale_y_reverse(breaks = seq(from = 0, to = 1200, by = 80), limits=c(1200,0)) +
labs(shape = "Congruence", color = "Probe Location",x = "X Position", y = "Y Position") +
facet_wrap(vars(emotion),nrow=2,ncol=1) +
theme(axis.title.x = element_text(face="bold",size=20),
axis.text.x = element_text(face="bold",size=15, color="black"),
axis.title.y = element_text(face="bold",size=20),
axis.text.y = element_text(face="bold",size=15, color="black"),
panel.background = element_rect(fill="white"),
panel.border = element_rect(colour = "black", fill=NA, size=2),
strip.text = element_text(face="bold",size=20),
legend.text = element_text(colour = "black", size=15),
legend.title = element_text(colour = "black", size=15)) +
annotate("rect",xmin=0, xmax=1920, ymin=0, ymax=599,alpha=.4) +
annotate("rect",xmin=0, xmax=1920, ymin=602, ymax=1200,alpha=.4)
This results in the following:
enter image description here
However I want the call to annotate to leave a line between the two rectangles on both facets of the plot. Currently it only leaves a line between the two on the top (Angry) facet. I thought that supplying the rect coordinates without specifying facets should draw the same two rectangles on each facet of the plot...
Any thoughts on how to make the bottom facet look like the top one?
Thanks in advance!

It's a matter of it displaying it properly on the device, i suggest you save it to a png or pdf. First save plot as object:
g1 = ggplot(df.for.graph,aes(x=xp,y=yp,color=loc,shape=cong)) +
geom_point() +
scale_color_manual(values=c("red","blue")) +
scale_shape_manual(values=c(1,4)) +
scale_fill_manual(values=c("green", "yellow")) +
scale_x_continuous(breaks = seq(from = 0, to = 1920, by = 160), limits=c(0,1920)) +
scale_y_reverse(breaks = seq(from = 0, to = 1200, by = 80), limits=c(1200,0)) +
labs(shape = "Congruence", color = "Probe Location",x = "X Position", y = "Y Position") +
facet_wrap(vars(emotion),nrow=2,ncol=1) +
theme(axis.title.x = element_text(face="bold",size=20),
axis.text.x = element_text(face="bold",size=15, color="black"),
axis.title.y = element_text(face="bold",size=20),
axis.text.y = element_text(face="bold",size=15, color="black"),
panel.background = element_rect(fill="white"),
panel.border = element_rect(colour = "black", fill=NA, size=2),
strip.text = element_text(face="bold",size=20),
legend.text = element_text(colour = "black", size=15),
legend.title = element_text(colour = "black", size=15)) +
annotate("rect",xmin=0, xmax=1920, ymin=0, ymax=599,alpha=.4) +
annotate("rect",xmin=0, xmax=1920, ymin=602, ymax=1200,alpha=.4)
And save:
ggsave(g1,file="g1.png",width=12,height=12)

Related

ggplot: Adding a plot outline with the axis ticks

I'm trying to create plots where the x-axis ALSO appears above the plot as well as the y-axis to the right of the plot. Both should contain the same ticks as the normal axis, but NOT the axis text. This should result in a "box" with helpful tick-marks around the plot. I would also like to have smaller ticks in-between my major ticks (that are labelled) that do not have a label. Here is a figure I made:
I also drew in pink what I would like to achieve in R:
]3
My code for this plot:
p <- p + xlab("") + ylab("") + theme(legend.position = "none") + theme(axis.ticks.length = unit(-0.25, "cm"), axis.text.x = element_text(size = 30, hjust=1)) + theme(axis.text.y = element_text(size=35, hjust = 1), strip.text = element_text(size=35), axis.title.y = element_text(size = 40), legend.text = element_text(size=30), axis.title.x = element_text(size=40), legend.title = element_text(size=45))
p <- p + theme(text = element_text(family = "Helvetica")) + scale_x_continuous(limits=c(-0.5, 25), breaks = c(0, 2, 4, 6, 8, 24)) + theme(legend.background = element_rect(color = "black", linetype = "solid")) + scale_colour_manual(values = cbpallette)
p <- p + theme(legend.key.size = unit(2.5, "cm")) + theme(axis.text.x = element_text(margin = margin(t = .5, unit = "cm")), axis.text.y = element_text(margin = margin(r = .5, unit = "cm")))
p
*** Edit ***
Here is updated code, using Stefans advise. The figure looks like so, the ticks are there, the axis are missing:
p <- p + xlab("") + ylab("") + theme(legend.position = "none") + theme(axis.ticks.length = unit(-0.25, "cm"), axis.text.x = element_text(size = 30, hjust=1)) + theme(axis.text.y = element_text(size=35, hjust = 1, angle=45), strip.text = element_text(size=35), axis.title.y = element_text(size = 40), legend.text = element_text(size=30), axis.title.x = element_text(size=40))
p <- p + theme(text = element_text(family = "Helvetica")) + scale_colour_manual(values = cbpallette)
p <- p + theme(axis.text.x = element_text(margin = margin(t = .5, unit = "cm")), axis.text.y = element_text(margin = margin(r = .5, unit = "cm")))
p
You could duplicate the axes using argument sec.axis = dup_axis() for both scales like so:
library(ggplot2)
ggplot(mtcars, aes(hp, mpg)) +
geom_point() +
scale_x_continuous(sec.axis = dup_axis(name = NULL, labels = NULL)) +
scale_y_continuous(sec.axis = dup_axis(name = NULL, labels = NULL))

Specific Barplot in R ggplot

Hello I will try for a last time,
I am doing my best to draw a barplot like the following Figure:
However it seems impossible with R.
Any idea?
Thanks in advance,
Peter
Attached the code I used.
groupe2<-rep(c(rep("P",4),rep("I",4)),2)
groupe<-rep(c("PPP","PPI","PIP","PII","IPP","IPI","IIP","III"),2)
OR_A<-c(1.00,0.86,0.88,0.90,0.77,0.68,0.77,0.70)
ICinf_A<-c(NA,0.70,0.72,0.76,0.60,0.50,0.61,0.61)
ICsup_A<-c(NA,1.06,1.07,1.06,1.00,0.92,0.96,0.81)
OR_B<-c(1.00,0.97,1.01,0.81,0.73,0.69,0.61,0.58)
ICinf_B<-c(NA,0.78,0.77,0.62,0.61,0.57,0.50,0.52)
ICsup_B<-c(NA,1.20,1.28,1.05,0.81,0.82,0.71,0.65)
OR_C<-c(1.00,1.03,0.86,0.65,0.68,0.58,0.47,0.37)
ICinf_C<-c(NA,0.84,0.67,0.50,0.59,0.49,0.40,0.33)
ICsup_C<-c(NA,1.27,1.10,0.86,0.78,0.69,0.56,0.41)
Cohort<-c(rep(" PC",8), rep("RIC",8))#, rep("RIC",8))
OR<-c(OR_A,OR_B)#,OR_C)
ICinf<-c(ICinf_A,ICinf_B)#,ICinf_C)
ICsup<-c(ICsup_A,ICsup_B)#,ICsup_C)
rm(dataOR)
dataOR<-data.frame(OR,groupe,Cohort,groupe2,ICinf,ICsup)
names(dataOR)
dataOR[, "groupe"] <- factor(dataOR[, "groupe"] ,
levels = c("PPP","PPI","PIP","PII","IPP","IPI","IIP","III"))
##########
library(ggdag)
ggplot(dataOR, aes(fill=outcome, y=OR, x=groupe)) +
geom_bar(position="dodge", stat="identity", color = "gray95", size = 0.25) +
# scale_fill_brewer(palette="Blues")+
scale_fill_manual(values = RColorBrewer::brewer.pal(5, "Blues")[3:5]) +
geom_errorbar(aes(ymin=ICinf, ymax=ICsup), width=.4, position=position_dodge(.9))+
geom_hline(yintercept=1) +
geom_point(position = position_dodge(0.9), size = 0.5, show.legend = F) +
scale_y_continuous(expand = expand_scale(mult = c(0, 0.05))) +
facet_wrap(~groupe, nrow = 1, scales = "free_x") +
labs(fill = NULL) +
theme(legend.position = "top",
legend.key.height = unit(0.2, "cm"),
legend.background = element_rect(color = "black", size = 0.4),
axis.line = element_line(color = "black"),
axis.text.x = element_blank(),
axis.ticks = element_blank(),
panel.grid.major.x = element_blank(),
axis.title = element_text(face = "bold"))

How do I adjust the limits of the axes tick marks to be the same as the border in ggplot?

I have the following figure and I want it formatted such that the tick marks on each axes are the upper and lower extent of the area bounded by the thick black border.
ggplot(WPND, aes(x = Year)) +
geom_line(aes(y=FOX_LS), colour="black", size=1.2, linetype=1) +
geom_line(aes(y=FOX_HS), colour="red", size=1.2, linetype=1) +
theme_light() +
theme(axis.text.x = element_text(color= "black", size=11, angle=90, hjust =
-2, vjust = 0.5)) +
theme(axis.text.y = element_text(color = "black", size = 11)) +
ylab(expression("BAI (cm "*{}^2*")")) +
scale_x_continuous(breaks = seq(1960, 2015, by=5)) +
scale_y_continuous(limits = c(0,60), breaks = seq(0, 60, b=10)) +
theme(panel.border = element_rect(color = "black", fill = NA, size = 1.5),
panel.grid.minor = element_blank(),
panel.grid.major = element_line(color = 'grey', linetype= 'dashed'),
axis.ticks.length = unit(-0.25, "cm"),
axis.ticks = element_line(color = "black", size = 1),
axis.text.x = element_text(margin = unit(c(0.5,0.5,0.5,0.5), "cm")),
axis.text.y = element_text(margin = unit(c(0.5,0.5,0.5,0.5), "cm")))`
figure I've made in ggplot
how I want the tick marks/margins to look (figure made in excel)
You have to add expand = c(0,0) argument to the x and yscales:
... +
scale_x_continuous(breaks = seq(1960, 2015, by=5), expand = c(0,0)) +
scale_y_continuous(limits = c(0,60), breaks = seq(0, 60, b=10), expand = c(0,0)) +
...

Add legend to ggplot object (why two legends?)

I created a ggplot2 object:
a <- replicate(8,rnorm(100))
colnames(a) <- letters[1:8]
b < -melt(a,id.vars=1:1)
colnames(b) <- c("c","variable","value")
ggplot(b,aes(x = c,y = value, colour = variable, linetype = variable)) +
geom_line()+
geom_point(aes(shape = factor(variable)), size = 1.7) +
scale_x_continuous(limits = c(-1, 1),
breaks = seq(-1, 1, 0.1),
expand=c(0.01, 0.01)) +
scale_y_continuous(limits = c(-1, 1),
breaks = seq(-1, 1, 0.1),
expand = c(0.01, 0.01))+
theme_bw(base_size = 12, base_family = "Helvetica") +
theme(axis.text=element_text(size = 10),
axis.title=element_text(size = 10),
text = element_text(size = 10),
axis.line = element_line(size = 0.25),
axis.ticks=element_line(size = 0.25),
panel.grid.major = element_blank(),
#panel.grid.minor = element_blank(),
panel.border = element_rect(colour = "black", fill = NA, size = 0.5),
panel.background = element_blank(),
legend.position = "top" ,
legend.direction = "vertical",
legend.title = element_blank(),
legend.text = element_text(size = 13),
legend.background = element_blank(),
legend.key = element_blank()) +
labs(x = '', y = '', title = "") +
theme(plot.title = element_text(size=10)) +
theme(strip.text.x = element_text(size = 8,color="black"),
strip.background = element_blank()) +
theme(strip.text.x = element_text(size = 8, colour = "black"))
My problem is the following:
when I create the legend, there is a separate legend for the colors and a separate one for the points.
How can I create a single legend for each of the 8 variables?
Let me minimise your code and focus on the legend issue. This is what you have now.
ggplot(b,aes(x = c, y = value, colour = variable, linetype = variable)) +
geom_line() +
geom_point(aes(shape = factor(variable)),size=1.7)
Your data frame, b has variable as factor. You use this in two ways here; variable and factor(variable). You can simply use variable for shape in geom_point; make all variable identical.
ggplot(b,aes(x = c, y = value, colour = variable, linetype = variable)) +
geom_line()+
geom_point(aes(shape = variable),size = 1.7)
I saw some warning messages related to colours and other things. You may want to take care of them. But, for legend, this is one way to go.
Take from the ideas on this page: http://www.cookbook-r.com/Graphs/Legends_(ggplot2)/#modifying-the-text-of-legend-titles-and-labels
I edited your code to make the data visible (you had problems with your x-axis limits. Note the final three lines. These commands tell ggplot to create only one legend.
a<-replicate(6,rnorm(100))
colnames(a)<-letters[1:6]
b<-melt(a,id.vars=1:1)
colnames(b)<-c("c","variable","value")
ggplot(b,aes(x=c,y=value,colour=variable,linetype=variable)) +
geom_line() + geom_point(aes(shape=factor(variable)),size=1.7)+
scale_x_continuous(limits=c(0,100))+
scale_y_continuous(limits=c(-2,2),breaks=seq(-2,2,0.1),expand=c(0.01,0.01))+
theme_bw(base_size=12, base_family="Helvetica") +
theme(axis.text=element_text(size=10),
axis.title=element_text(size=10),
text = element_text(size=10),
axis.line = element_line(size=0.25),
axis.ticks=element_line(size=0.25),
panel.grid.major = element_blank(),
#panel.grid.minor = element_blank(),
panel.border = element_rect(colour="black",fill=NA,size=0.5),
panel.background = element_blank(),
legend.position="top" ,
legend.direction="vertical",
legend.title=element_blank(),
legend.text=element_text(size=13),
legend.background=element_blank(),
legend.key=element_blank())+
labs(x='', y='',title="")+
theme(plot.title=element_text(size=10))+
theme(strip.text.x = element_text(size = 8,color="black"),strip.background=element_blank())+
theme(strip.text.x = element_text(size = 8,color="black"))+
scale_colour_discrete(name ="Factor")+
scale_linetype_discrete(name ="Factor") +
scale_shape_discrete(name ="Factor")

In ggplot how do I eliminate wasted space below 0 on the axis?

I would like to eliminate the the dead space in the chart below the two 0's. How would I do this?
I'm not sure how to have the wording more clear. An image would have worked best to explain what I'm looking for but Stackoverflow didn't let me post one.
My code is:
ggplot(data=temp,
aes(x=s, y=SumOfAverage,)) +
geom_line() +
scale_x_continuous(breaks = seq(0, 1, by = 0.1),labels = percent_format())+
scale_y_continuous(breaks = seq(0, 35000, by = 1000),labels = comma_format())+
theme(axis.title.x = element_blank()) +
labs(y = "kWh")+
opts(
panel.grid.major.x = theme_line(size = 0.1, colour = '#1391FF'),
panel.grid.major.y = theme_line(size = 0.1, colour = '#1391FF'),
panel.grid.minor = theme_line(colour = "lightblue"),
panel.background = theme_rect(colour = "grey"),
axis.ticks = theme_blank()
)+
theme(panel.background = element_rect(fill = "grey"))

Resources