Add secondary X-axis with facets - r

Seems that this topic has not been covered this since the ggplot2.2.2 update where old solutions like this one and this one no longer apply. Fortunately, the process is far simpler than before. One line of code and you have a secondary Y-axis (as shown here).
But I cannot get a secondary X-axis on my plots...
I am comparing a depth profile of metal concentrations along the sediment core. I would like to display carbon and phosphate concentrations as an geom_area behind the metal's concentration. The problem is that both carbon and phosphate concentrations are no on the same scale as the metal. Thus I need a second axis.
The theme is the following (taken from this website):
theme_new <- theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.background = element_blank(), axis.line = element_line(colour = "black"), strip.text.x = element_text(size=10, angle=0, vjust=0), strip.background = element_blank(), strip.text.y = element_text(angle = 0), legend.position="none",panel.border = element_blank(), axis.text.x=element_text(angle=45,hjust=1)) # Axis tick label angle
And this code gives me a second Y-axis even though I specify it under X-axis.
ggplot(MasterTable)+
geom_line(aes(Depth,Conc.nM))+
geom_area(aes(Depth,Conc.uM, fill=Variable))+
scale_x_continuous("Depth (cm)", sec.axis = sec_axis(~ . *100, name = "Carbon & Phosphate"))+
scale_y_continuous("Metal concentration (nM)")+
coord_flip()+
theme_new+
theme(legend.position = "right")+
facet_grid(. ~ Assay, scales = "free")
Can anyone help me place the secondary axis on the top of the figure?
Thanks!!
dput of my MasterTable is the following:
structure(list(Depth = c(15L, 5L, 2L, -1L, -3L, -5L, -7L, -9L,
-11L, -13L, -15L, -17L, -19L, -21L, -23L, -25L, -27L, -29L, -31L,
15L, 5L, 2L, -1L, -3L, -5L, -7L, -9L, -11L, -13L, -15L, -17L,
-19L, -21L, -23L, -25L, -27L, -29L, -31L), Conc.nM = c(24L, 24L,
24L, 100L, 100L, 75L, 75L, 85L, 85L, 120L, 300L, 1000L, 200L,
240L, 240L, 800L, 1100L, 1500L, 2300L, 0L, 10L, 0L, 50L, 200L,
200L, 50L, 50L, 200L, 15L, 0L, 0L, 10L, 120L, 200L, 1500L, 2100L,
2000L, 2000L), Assay = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L,
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("Instrument 1",
"Instrument 2"), class = "factor"), Conc.uM = c(0L, 0L, 0L, 1L,
4L, 10L, 10L, 10L, 5L, 7L, 10L, 14L, 14L, 14L, 14L, 13L, 12L,
12L, 12L, 1L, 1L, 1L, 4L, 6L, 9L, 11L, 11L, 8L, 8L, 8L, 20L,
10L, 9L, 9L, 9L, 10L, 10L, 10L), Variable = structure(c(2L, 2L,
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,
2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L), .Label = c("Carbon", "Phosphate"), class = "factor")), .Names = c("Depth",
"Conc.nM", "Assay", "Conc.uM", "Variable"), class = "data.frame", row.names = c(NA,
-38L))

Thanks to Brian's answer, and modifying the theme proposed above, I got the following figure.
As he suggested, you have to first modify your data manually using something like this:
MasterTable$Conc.uM <- MasterTable$Conc.uM *100
Then, in the code, adjust your axis with the same correction factor as the one used above. Here is the code to make the figure.
ggplot(MasterTable)+
geom_line(aes(Depth,Conc.nM))+
geom_area(aes(Depth,Conc.uM, fill=Variable), alpha=0.6)+ #Area for second X-axis
geom_area(aes(Depth,Conc.nM), alpha=0.95)+
geom_point(aes(Depth,Conc.uM), size=1, shape=16, alpha=0.3)+ #Adding points for second X-axis
geom_point(aes(Depth,Conc.nM), size=1, shape=16, alpha=0.8)+
scale_fill_manual(values=colours) + scale_colour_manual(values=colours) +
labs(title="Sediment core", color="",fill="") + #Place legend title in both color="" and fill=""
scale_y_continuous("Metal concentration (nM)",
sec.axis = sec_axis(~ . /100, name = "[Pi] (uM) DOC (mg/L)"))+
scale_x_continuous("Depth (cm)", breaks=pretty_breaks(n=7))+
coord_flip()+ #Required to make a proper depth profile
theme_new+ #Reference to custom theme
facet_grid(. ~ Assay, scales = "free") #Scales makes that the axis size can change
Now I just have one problem left to solve. I would like for the tick marks and labels to be under the facet. Seems more logical and less busy than having it at the top of the figure.

From your code:
...
scale_x_continuous("Depth (cm)", sec.axis = sec_axis(~ . *100, name = "Carbon & Phosphate"))+
scale_y_continuous("Metal concentration (nM)") +
coord_flip() ...
Consider which primary axis you want "Carbon & Phosphate" to be parallel to. Also consider what "x-axis" and "y-axis" mean in the context of using coord_flip.
TL;DR: Just move your secondary axis into scale_y_continuous.

Related

How can I easily ad one colour in each bar and make it descending? [duplicate]

This question already has answers here:
Reorder bars in geom_bar ggplot2 by value
(3 answers)
Change bar plot colour in geom_bar with ggplot2 in r
(2 answers)
Closed last year.
How can I easily ad one color in each bar and make it descending?
QG4 %>%
filter(value=="Yes") %>%
ggplot(aes(y=Freq, x=variable))+
geom_bar(position = "dodge", stat = "identity")+
theme_bw()+
coord_flip()+
labs(x="Mode", y=NULL, title = "What is your usual (or most frequently used) mode of travel to work/place of study?")
I used dput(QG4) to avoid using a picture of the dataset:
structure(list(variable = structure(c(1L, 2L, 3L, 4L, 5L, 6L,
7L, 8L, 9L, 10L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L), .Label = c("Bicycle",
"Bicycle (Yélo)", "Bus", "Car", "Car (Yélo)", "Carpool", "Motorcycle/scooter",
"On foot", "Scooter (trottinette)", "Train"), class = "factor"),
value = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("No",
"Yes"), class = "factor"), Freq = c(1634L, 2143L, 1781L,
1532L, 2281L, 2202L, 2267L, 1331L, 2265L, 2172L, 655L, 146L,
508L, 757L, 8L, 87L, 22L, 958L, 24L, 117L)), class = "data.frame", row.names = c(NA,
-20L))
enter image description here

Cannot plot the correct x-axis in ggplot2

I am plotting the following data using ggplot2 in R.
dat<-structure(list(Month = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L,
3L, 3L, 3L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 6L, 6L, 6L, 7L, 7L, 7L,
8L, 8L, 8L, 9L, 9L, 9L, 10L, 10L, 10L, 10L, 11L, 11L, 11L, 11L,
12L, 12L, 12L, 12L), grp1 = structure(c(1L, 2L, 3L, 4L, 1L, 2L,
3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 1L, 2L, 3L,
1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 4L, 1L, 2L, 3L,
4L, 1L, 2L, 3L, 4L), .Label = c("(-Inf,2]", "(2,7]", "(7,14]",
"(14, Inf]"), class = "factor"), n = c(71L, 59L, 36L, 10L, 55L,
73L, 18L, 10L, 97L, 82L, 22L, 5L, 120L, 79L, 15L, 2L, 140L, 62L,
15L, 174L, 60L, 11L, 188L, 71L, 2L, 183L, 53L, 2L, 211L, 50L,
2L, 171L, 69L, 7L, 1L, 98L, 85L, 13L, 6L, 72L, 62L, 24L, 9L)), class
= "data.frame", row.names = c(NA,-43L))
Here's my script:
library(ggplot2)
p<-ggplot(data=test,aes(Month, n, fill = grp1))
p<- p + geom_col()
p <- p + theme(panel.background=element_rect(fill="white"),
plot.margin = margin(0.5,0.5,0.5,0.5, "cm"),
panel.border=element_rect(colour="black",fill=NA,size=1),
axis.line.x=element_line(colour="black"),
axis.line.y=element_line(colour="black"),
axis.text=element_text(size=20,colour="black",family="sans"),
axis.title=element_text(size=20,colour="black",family="sans"),
legend.position = "right", legend.key = element_rect(fill = 'white'))
p <- p + scale_y_continuous(limits = c(0,300),breaks=c(seq(0,300,50)), expand=c(0,0))
p <- p + scale_x_discrete(breaks=c(seq(1,12,1)),labels=c("JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"),expand=c(0,0))
p <- p + labs(x = "Month", y = "Number of Days")
Here's the output:
Why is it that I cannot plot the x-axis values?
If I don't set the scale_x_discrete, the plot will look like this:
Any ideas on how to solve this?
I'll appreciate any help.
If you want the Month name along the xaxis, then you can add in as.factor(Month) to your ggplot script. Heres an example:-
p<-ggplot(data=dat,aes(as.factor(Month), n, fill = grp1))
p<- p + geom_col()
p <- p + theme(panel.background=element_rect(fill="white"),
plot.margin = margin(0.5,0.5,0.5,0.5, "cm"),
panel.border=element_rect(colour="black",fill=NA,size=1),
axis.line.x=element_line(colour="black"),
axis.line.y=element_line(colour="black"),
axis.text=element_text(size=20,colour="black",family="sans"),
axis.title=element_text(size=20,colour="black",family="sans"),
legend.position = "right", legend.key = element_rect(fill = 'white'))
p <- p + scale_y_continuous(limits = c(0,300),breaks=c(seq(0,300,50)), expand=c(0,0))
p <- p + scale_x_discrete(breaks=c(seq(1,12,1)),labels=c("JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"),expand=c(0,0))
p <- p + labs(x = "Month", y = "Number of Days")
p
Which gives you this:-

How to bring model predict line in front of geom_rect

I am investigating the effect of time since fire on species diversity. I am attempting to make a graph that has different colours at different time since fire ages. However, putting the colours onto the graph has made the model prediction line fade away. I am wondering if there is some way to bring the line in front of geom_rect?
Loaded packages:
library(voxel)
library(gamm4)
library(ggplot2)
My data:
data <- read.csv('StacksOverflow.csv')
structure(list(Lscape = c(158L, 158L, 158L, 158L, 158L, 158L),
TSF = c(5, 5, 5, 18.5, 5, 18.5), VegtypeNew = structure(c(1L,
1L, 1L, 2L, 1L, 1L), .Label = c("spinsandplain", "woodlndsandplain"
), class = "factor"), FF = c(2L, 2L, 2L, 1L, 2L, 1L), ThreeYearRain = c(913.799997,
913.799997, 913.799997, 913.799997, 913.799997, 913.799997
), Div = c(2.2629743, 1.9630117, 1.7336569, 1.2816843, 2.4155056,
1.4240443), triodia_low = c(19L, 6L, 21L, 32L, 11L, 32L)), row.names = c(NA,
6L), class = "data.frame")
Extended data:
structure(list(Lscape = c(158L, 158L, 158L, 158L, 158L, 158L,
158L, 158L, 201L, 201L, 201L, 201L, 201L, 201L, 201L, 201L, 235L,
235L, 235L, 235L, 235L, 235L, 235L, 235L, 237L, 237L, 237L, 237L,
237L, 237L, 237L, 237L, 254L, 254L, 254L, 254L, 254L, 254L, 254L,
254L, 287L, 287L, 287L, 287L, 287L, 287L, 287L, 287L, 304L, 304L,
304L, 304L, 304L, 304L, 304L, 304L, 311L, 311L, 311L, 311L, 311L,
311L, 311L, 311L, 312L, 312L, 312L, 312L, 312L, 312L, 312L, 312L,
323L, 323L, 323L, 323L, 323L, 323L, 323L, 323L, 326L, 326L, 326L,
326L, 326L, 326L, 326L, 326L, 327L, 327L, 327L, 327L, 327L, 327L,
327L, 327L, 337L, 337L, 337L, 337L, 337L, 337L, 337L, 337L, 355L,
355L, 355L, 355L, 355L, 355L, 355L, 355L, 370L, 370L, 370L, 370L,
370L, 370L, 370L, 370L, 379L, 379L, 379L, 379L, 379L, 379L, 379L,
379L, 411L, 411L, 411L, 411L, 411L, 411L, 411L, 411L, 414L, 414L,
414L, 414L, 414L, 414L, 414L, 414L, 435L, 435L, 435L, 435L, 435L,
435L, 435L, 435L, 437L, 437L, 437L, 437L, 437L, 437L, 437L, 437L,
438L, 438L, 438L, 438L, 438L, 438L, 438L, 438L, 447L, 447L, 447L,
447L, 447L, 447L, 447L, 447L, 452L, 452L, 452L, 452L, 452L, 452L,
452L, 452L), TSF = c(5, 5, 5, 18.5, 5, 18.5, 18.5, 18.5, 11.5,
4.5, 0.5, 20, 11.5, 0.5, 1, 4.5, 1, 1, 4.5, 5, 4.5, 2, 5, 1,
6, 6, 4.5, 6, 14.5, 17, 4.5, 6, 1, 1, 7, 4.5, 2, 2, 7, 7, 20,
4, 3.5, 4, 3.5, 3.5, 11.5, 20, 6, 0.5, 5, 6, 6, 0.5, 7, 6, 3.5,
3.5, 3.5, 11.5, 11.5, 1, 1, 11.5, 1, 1, 4, 1, 1, 4, 1, 10.5,
7, 17.5, 0.5, 0.5, 0.5, 17.5, 7, 0.5, 18, 1.5, 3.5, 18, 18, 5,
3.5, 18.5, 14.5, 1.5, 7, 1.5, 7, 7, 7, 7, 10.5, 1.5, 0, 1.5,
7, 3, 7, 10.5, 0.5, 20, 0.5, 2, 2, 1.5, 2, 3, 20, 1, 1.5, 10.5,
17, 1.5, 1.5, 10.5, 3, 1, 1, 1, 4.5, 1, 6.5, 1, 10, 1.5, 12.5,
1.5, 1.5, 1.5, 1.5, 1.5, 2, 7, 12.5, 2, 7, 2, 2, 2, 1.5, 18.5,
18.5, 1.5, 7, 1.5, 1.5, 5, 12.5, 6.5, 1.5, 1.5, 1.5, 1.5, 1.5,
1.5, 6.5, 6.5, 1.5, 6.5, 18.5, 6.5, 7, 1.5, 1, 7, 7, 1, 7, 1,
7.5, 7.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5), VegtypeNew = structure(c(1L,
1L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L,
2L, 1L, 1L, 1L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 1L, 1L,
1L, 1L, 1L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 2L, 1L, 1L, 1L, 2L, 1L, 1L, 1L, 1L, 2L, 1L, 2L, 2L,
2L, 2L, 1L, 2L, 2L, 2L, 2L), .Label = c("spinsandplain", "woodlndsandplain"
), class = "factor"), FF = c(2L, 2L, 2L, 1L, 2L, 1L, 1L, 1L,
3L, 3L, 4L, 2L, 2L, 5L, 3L, 4L, 5L, 5L, 2L, 2L, 4L, 3L, 5L, 4L,
5L, 4L, 4L, 5L, 3L, 3L, 4L, 5L, 5L, 3L, 4L, 6L, 5L, 5L, 3L, 4L,
1L, 5L, 3L, 4L, 4L, 4L, 2L, 1L, 2L, 2L, 3L, 4L, 4L, 3L, 2L, 3L,
3L, 3L, 4L, 3L, 3L, 3L, 4L, 2L, 6L, 6L, 6L, 6L, 5L, 2L, 7L, 3L,
2L, 1L, 2L, 2L, 2L, 2L, 2L, 1L, 3L, 3L, 4L, 4L, 3L, 4L, 3L, 3L,
4L, 5L, 2L, 3L, 3L, 2L, 2L, 2L, 2L, 4L, 3L, 6L, 4L, 4L, 3L, 3L,
4L, 0L, 2L, 4L, 3L, 2L, 3L, 3L, 0L, 2L, 2L, 1L, 1L, 2L, 2L, 1L,
3L, 2L, 5L, 6L, 3L, 3L, 3L, 3L, 2L, 4L, 3L, 4L, 5L, 4L, 3L, 3L,
6L, 4L, 3L, 5L, 5L, 5L, 5L, 4L, 3L, 2L, 1L, 2L, 2L, 3L, 2L, 2L,
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 2L, 2L, 2L, 3L, 2L, 2L, 2L, 3L,
2L, 2L, 2L, 3L, 2L, 4L, 2L, 3L, 4L, 5L, 5L, 3L, 4L, 3L, 3L, 4L
), ThreeYearRain = c(913.799997, 913.799997, 913.799997, 913.799997,
913.799997, 913.799997, 913.799997, 913.799997, 938.899988, 938.899988,
938.899988, 938.600004, 938.899988, 938.899988, 938.899988, 938.499989,
930.700005, 932.800001, 930.700005, 930.700005, 932.800001, 930.700005,
930.700005, 932.800001, 932.699991, 934.799987, 934.799987, 934.799987,
932.699991, 934.799987, 932.699991, 934.799987, 896.99999, 896.99999,
908.999991, 908.999991, 908.999991, 908.999991, 910.199991, 898.399994,
928.000009, 939.800006, 935.500004, 928.000009, 928.000009, 923.700007,
931.499996, 931.499996, 866.200004, 866.200004, 867.000003, 867.000003,
867.000003, 867.300002, 867.000003, 869.3, 926.800003, 926.800003,
926.800003, 926.800003, 933.800003, 934.600006, 934.600006, 934.600006,
924.2, 925.100002, 924.2, 924.2, 924.2, 922.2, 924.2, 924.7,
974.799995, 983.500006, 983.500006, 983.500004, 983.500006, 974.799995,
974.799994, 983.500006, 839.1, 839.1, 839.1, 839.100001, 839.300001,
839.1, 838.699999, 839.100001, 839.100001, 838.699999, 842.300004,
842.300004, 842.900006, 842.300004, 842.900006, 842.300004, 936.900014,
936.900014, 936.900014, 932.999984, 933.099983, 932.999984, 936.900014,
936.900014, 870.499995, 870.499995, 877.399998, 877.399998, 876.099997,
876.099997, 876.099997, 859.199997, 957.199982, 966.299982, 955.699998,
955.699998, 957.199982, 955.699998, 955.699998, 956.299985, 852.2,
852.2, 852.600006, 852.500001, 852.500001, 852.500001, 852.600006,
852.500001, 906.700011, 904.700001, 912.600007, 912.600007, 914.600007,
906.700001, 906.399998, 914.600007, 925.599982, 933.299992, 933.299992,
933.299992, 933.299992, 926.500012, 935.899994, 935.199992, 916.800001,
916.100001, 916.800001, 916.400003, 918.700003, 904.100001, 916.800001,
918.700003, 899.1, 904.100001, 906.000003, 903.400002, 904.100001,
903.400002, 906.000003, 906.000003, 905.7, 903.099999, 903.099999,
905.7, 912.199994, 893.200002, 905.399999, 904.999998, 933.700012,
933.700012, 933.700012, 933.700012, 933.700012, 932.30001, 932.300008,
932.300008, 878.500006, 878.500006, 878.500006, 879.300004, 879.300004,
879.300004, 879.300004, 873.200008), Div = c(2.2629743, 1.9630117,
1.7336569, 1.2816843, 2.4155056, 1.4240443, 1.5178948, 0.8993031,
1.2022801, 1.9287665, 2.0237769, 2.004871, 1.5020684, 2.1776591,
2.093787, 2.3139276, 2.7244402, 2.7026829, 1.6644725, 2.0696347,
1.9561853, 2.6018987, 2.5800017, 2.1867866, 2.4144821, 1.7389892,
2.1427451, 1.6544538, 1.8651966, 1.7569776, 1.8257533, 1.4048204,
2.7384914, 2.9344488, 2.2306909, 2.5085619, 1.8874836, 2.3431509,
1.8401602, 1.8620274, 1.8038997, 2.5909049, 2.2265328, 2.0882065,
2.4737837, 2.2995223, 1.4231311, 2.0577752, 1.6463134, 2.1464331,
2.2636437, 2.0992589, 1.7666974, 1.835061, 1.7732171, 2.0813243,
1.865505, 2.0200607, 1.2510612, 1.021761, 0.8111482, 0.2617645,
2.0282081, 1.1145976, 2.2596683, 2.3517629, 1.9424972, 1.9191269,
1.4222035, 2.6007698, 2.0071984, 1.9049132, 1.073374, 0.9576897,
1.6273043, 1.7701581, 0.6890092, 1.5764456, 0.384906, 1.5099996,
1.6713486, 2.5483064, 2.2033185, 2.0798843, 1.9082985, 2.1580972,
1.6952798, 1.6303402, 1.9461221, 1.4116405, 1.5347693, 2.6924921,
1.727278, 1.9384415, 1.6659585, 1.612819, 1.6592884, 2.7129796,
0, 2.7098898, 1.3785924, 2.7635218, 1.1481271, 1.8597007, 2.2191531,
1.088549, 2.431015, 1.3702099, 2.1018035, 2.3442348, 2.3599146,
2.789816, 1.8340235, 1.0606126, 2.5852679, 1.7791063, 1.2273106,
2.2432636, 2.5642458, 1.3306642, 2.6771856, 1.5062567, 2.0903266,
2.0398412, 2.4821503, 0.5979376, 1.479214, 1.9188301, 1.2267089,
2.4491421, 1.5366949, 2.516592, 2.4084849, 2.4385928, 2.549348,
2.7090074, 2.3337573, 1.8982968, 1.7956341, 2.3752386, 1.6587394,
2.6663039, 2.4853204, 1.9325793, 2.4431141, 1.6976331, 0.8791745,
2.6625573, 1.9596877, 1.9287565, 2.4590816, 2.4963942, 1.8767916,
1.3954333, 2.5155936, 2.2327274, 2.6613726, 2.580748, 2.3142567,
2.2280879, 1.7925025, 1.663008, 2.3488945, 2.0746398, 1.7050203,
2.0108246, 1.7317251, 2.4936515, 0.9556999, 1.3716151, 2.0694067,
1.4944032, 1.0984774, 1.2868726, 1.6429103, 1.3720737, 1.8037795,
1.8745583, 1.8921264, 1.8320377, 1.201682, 1.8489571, 1.798546,
0.8486856), triodia_low = c(19L, 6L, 21L, 32L, 11L, 32L, 16L,
29L, 17L, 20L, 0L, 24L, 37L, 0L, 3L, 29L, 4L, 2L, 31L, 28L, 20L,
12L, 6L, 6L, 26L, 28L, 27L, 32L, 37L, 26L, 15L, 27L, 2L, 1L,
19L, 5L, 13L, 10L, 33L, 14L, 25L, 22L, 15L, 34L, 15L, 7L, 36L,
25L, 25L, 0L, 25L, 4L, 21L, 0L, 33L, 16L, 16L, 15L, 22L, 25L,
25L, 0L, 0L, 18L, 2L, 0L, 26L, 0L, 0L, 7L, 0L, 13L, 28L, 35L,
0L, 0L, 0L, 31L, 29L, 0L, 14L, 5L, 14L, 11L, 12L, 16L, 21L, 26L,
22L, 7L, 23L, 10L, 23L, 17L, 19L, 7L, 27L, 3L, 0L, 2L, 29L, 14L,
30L, 12L, 0L, 35L, 0L, 29L, 4L, 5L, 14L, 15L, 33L, 0L, 3L, 21L,
34L, 0L, 2L, 28L, 16L, 0L, 1L, 0L, 11L, 0L, 32L, 0L, 27L, 2L,
28L, 3L, 0L, 4L, 1L, 6L, 14L, 27L, 25L, 12L, 7L, 10L, 16L, 9L,
4L, 15L, 40L, 2L, 18L, 5L, 3L, 6L, 1L, 33L, 2L, 5L, 12L, 4L,
7L, 3L, 17L, 30L, 5L, 7L, 17L, 15L, 16L, 9L, 0L, 26L, 16L, 0L,
24L, 1L, 27L, 32L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L)), class = "data.frame", row.names = c(NA,
-184L))
The model:
m1b <-gamm4(Div~TSF+FF+s(triodia_low, k=6)+VegtypeNew+ThreeYearRain,random=~(1|Lscape),data=data)
Plotting:
p <-plotGAMM (m1b,smooth.cov="triodia_low",groupCovs = NULL,orderedAsFactor=T,rawOrFitted="raw",plotCI=T,grouping = NULL)
p + labs(x= "Years since fire") +
labs(y="Species diversity (H')") +
theme_bw() +
theme(panel.grid.major = element_blank()) +
theme(panel.grid.minor = element_blank()) +
theme(panel.border = element_blank()) +
theme(axis.line = element_line(colour="black")) +
theme(axis.title = element_text(size=22)) + # face="bold"
theme(axis.ticks = element_line()) +
scale_x_continuous(breaks = seq(0,40,by=5)) +
geom_rect(aes(xmin=0,xmax=0.6,ymin=-Inf,ymax=Inf),alpha=0.002, fill="coral4") +
geom_rect(aes(xmin=.6,xmax=1,ymin=-Inf,ymax=Inf),alpha=0.002, fill="gold") +
geom_rect(aes(xmin=1,xmax=5,ymin=-Inf,ymax=Inf),alpha=0.002, fill="darkred") +
geom_rect(aes(xmin=5,xmax=10,ymin=-Inf,ymax=Inf),alpha=0.002,fill="chocolate") +
geom_rect(aes(xmin=10,xmax=40,ymin=-Inf,ymax=Inf),alpha=0.002,fill="orangered") +
theme(axis.text = element_text(size=18, colour="black")) +
theme(text = element_text(family = "Arial")) +
theme(legend.position= "none")
The plot:
Any help would be greatly appreciated :)
Using the development version of gratia you can replicate the plot you showed with a few simple calls to create the data, predict etc.
To install the development version of gratia do
# install.packages("remotes")
remotes::install_github("gavinsimpson/gratia")
Once installed you can produce an object suitable for plotting using:
library('mgcv')
library('gamm4')
library('gratia')
library('ggplot2')
library('dplyr')
## model fit
m1b <- gamm4(Div ~ TSF + FF + s(triodia_low, k=6) + VegtypeNew + ThreeYearRain,
random = ~ (1|Lscape), data = df)
## data to predict at
new_df <- data_slice(m1b, var1 = 'triodia_low', n = 100)
## predict and cast to a tibble
pred_df <- as_tibble(predict(m1b[["gam"]], new_df, se.fit = TRUE))
## add to the data we're predicting at
pred_df <- bind_cols(new_df, pred_df)
## grab the inverse link of the model (not needed here, but is for non-Normal fits)
ilink <- inv_link(m1b)
## create the upper and lower credible interval
pred_df <- mutate(pred_df,
lwr = ilink(fit - (2 * se.fit)),
upr = ilink(fit + (2 * se.fit)),
fit = ilink(fit))
The plot itself can be created using:
ggplot(pred_df, aes(x = triodia_low, y = fit)) +
labs(x = "Years since fire", y = "Species diversity (H')") +
theme_bw() +
theme(panel.grid.major = element_blank()) +
theme(panel.grid.minor = element_blank()) +
theme(panel.border = element_blank()) +
theme(axis.line = element_line(colour="black")) +
theme(axis.title = element_text(size=22)) +
theme(axis.ticks = element_line()) +
scale_x_continuous(breaks = seq(0,40,by=5)) +
geom_rect(aes(xmin=0, xmax=0.6, ymin=-Inf, ymax=Inf), alpha=0.01, fill="coral4") +
geom_rect(aes(xmin=0.6, xmax=1, ymin=-Inf, ymax=Inf), alpha=0.01, fill="gold") +
geom_rect(aes(xmin=1, xmax=5, ymin=-Inf, ymax=Inf), alpha=0.01, fill="darkred") +
geom_rect(aes(xmin=5, xmax=10, ymin=-Inf, ymax=Inf), alpha=0.01, fill="chocolate") +
geom_rect(aes(xmin=10, xmax=40, ymin=-Inf, ymax=Inf), alpha=0.01, fill="orangered") +
geom_point(data = df, mapping = aes(x = triodia_low, y = Div)) +
geom_ribbon(aes(ymin = lwr, ymax = upr), alpha = 0.4) +
geom_line()
Most of the ggplot code is your's, but now that we have full control, we can put the data layers in the foreground by leaving those layers until the end.
Note that I'm not convinced this is a great plot. The fitted function you are showing is conditional upon the other covariates in the data set. Here, and as with voxel::plotGAMM(), we're predicting from the model and hence we have to supply something for the other covariates. Following voxel::plotGAMM and mgcv::vis.gam, we fix the other covariates not shown at
the value of the data observation closest to the median (for continuous variables), or
the modal category (for factor parametric terms)
So, the resulting figure is the fit conditional upon those values. In particular it is for the spinsandplain level of VegTypeNew. As such it is a little misleading.

Plot text/labels centered on a dodged bar plot

I can't figure out how to display labels centered on each dodged bar in a barplot in ggplot2.
I know that I can dodge the bars using position = "dodge" and I know that in order for the labels to show up centered on each bar I need to add position = position_dodge(width = 1) in the geom_text() or geom_label() command.
But for some reason it doesn't work (see Figure below). I also added my data and code.
df <- structure(list(Measure = structure(c(2L, 2L, 2L, 2L, 2L, 2L,
2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c("1988",
"2017"), class = "factor"), Province = structure(c(1L, 2L, 3L,
4L, 5L, 6L, 7L, 8L, 9L, 10L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L,
9L, 10L), .Label = c("BC", "AB", "SK", "MB", "ON", "QC", "NB",
"PE", "NS", "NL"), class = "factor"), Value = c(363L, 61L, NA,
69L, NA, NA, 127L, 12L, 92L, 18L, 178L, 29L, 41L, 92L, 284L,
1019L, 267L, 27L, 77L, 22L)), .Names = c("Measure", "Province",
"Value"), row.names = 41:60, class = "data.frame")
ggplot(df, aes(x=Province, y=Value)) + geom_bar(aes(fill=Measure), position="dodge",
stat="identity") + geom_label(aes(label=Value), position = position_dodge(width=1))
I just realized (thanks to #aelwan answer) that the only thing I had to do is adding group=Measure in the aes() function, i.e.
ggplot(df, aes(x=Province, y=Value, group=Measure)) +
geom_bar(aes(fill=Measure),position="dodge", stat="identity") +
geom_label(aes(label=Value),position = position_dodge(width=1))
That gives:
Try this
ggplot(df, aes(x=Province, y=Value, group = Measure)) +
geom_col(aes(fill=Measure),
position ="dodge", width = 0.4)+
geom_text(aes(label= Value,
group = Measure
),vjust= 0, position = position_dodge(0.4) , color="black" )
This is a late answer, but the geom_text is not perfectly centered over the bars. One way to fix this is by also specifying the width of the bars position=position_dodge(width = 1).
geom_bar(aes(fill=Measure),position=position_dodge(width = 1), stat="identity")

Manually order x-axis labels within each facet in ggplot

I am trying to manually reorder the x-axis labels within each facet.
The data are as follows:
df = structure(list(block = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L,
2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L,
4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 5L, 5L), .Label = c("1",
"2", "3", "4", "5"), class = "factor"), item = structure(c(14L,
15L, 28L, 29L, 30L, 31L, 32L, 15L, 16L, 17L, 18L, 19L, 20L, 21L,
15L, 22L, 23L, 24L, 25L, 26L, 27L, 1L, 2L, 3L, 4L, 5L, 6L, 7L,
1L, 8L, 9L, 10L, 11L, 12L, 13L), .Label = c("p00e00d00", "p00e00d11",
"p00e00d12", "p00e00d13", "p00e00d21", "p00e00d22", "p00e00d23",
"p00e11d00", "p00e12d00", "p00e13d00", "p00e21d00", "p00e22d00",
"p00e23d00", "p01e00d00", "p11e00d00", "p11e00d11", "p11e00d12",
"p11e00d13", "p11e00d21", "p11e00d22", "p11e00d23", "p11e11d00",
"p11e12d00", "p11e13d00", "p11e21d00", "p11e22d00", "p11e23d00",
"p12e00d00", "p13e00d00", "p14e00d00", "p21e00d00", "p22e00d00"
), class = "factor"), response = structure(c(2L, 2L, 2L, 2L,
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("2",
"1"), class = "factor"), n = c(345L, 511L, 583L, 613L, 612L,
222L, 142L, 531L, 546L, 589L, 636L, 478L, 364L, 313L, 502L, 533L,
587L, 603L, 385L, 298L, 263L, 518L, 546L, 563L, 593L, 435L, 351L,
310L, 478L, 579L, 629L, 646L, 357L, 307L, 230L), freq = c(0.408284023668639,
0.604733727810651, 0.689940828402367, 0.725443786982249, 0.724260355029586,
0.262721893491124, 0.168047337278107, 0.628402366863905, 0.646153846153846,
0.697041420118343, 0.752662721893491, 0.565680473372781, 0.430769230769231,
0.370414201183432, 0.594082840236686, 0.630769230769231, 0.694674556213018,
0.713609467455621, 0.455621301775148, 0.352662721893491, 0.311242603550296,
0.61301775147929, 0.646153846153846, 0.666272189349112, 0.701775147928994,
0.514792899408284, 0.415384615384615, 0.366863905325444, 0.565680473372781,
0.685207100591716, 0.744378698224852, 0.764497041420118, 0.422485207100592,
0.363313609467456, 0.272189349112426)), class = c("tbl_df", "tbl",
"data.frame"), row.names = c(NA, -35L), .Names = c("block", "item",
"response", "n", "freq"))
There are five blocks, each block contains 7 items, and some items have the same names across blocks. I can therefore facet by block as follows:
df %>%
ggplot(aes(x = item, y = freq)) +
geom_bar(stat = "identity", position = "dodge", color = "black") +
facet_grid(.~block, scales = "free") +
coord_cartesian(ylim = c(0, 1), expand = F) + # need to add expanse = F to prevent zooming away
scale_y_continuous(labels = scales::percent) +
theme(axis.text.x = element_text(angle=45, hjust=1, vjust=1))
I also have vectors which states for each block the order that items should appear in. For example:
block_3_order = c("p11e13d00","p11e12d00", "p11e11d00", "p11e00d00", "p11e21d00", "p11e22d00","p11e23d00")
)
block_4_order = c("p00e00d13", "p00e00d12", "p00e00d11", "p00e00d00", "p00e00d21","p00e00d22","p00e00d23")
)
I tried to reorder the "item" factor, but to get the desired effect I would need to split the dataframe into subsets representing blocks. Otherwise I am having trouble grasping how you can integrate the ordering of factors with the ggplot treatment of item as a single factor across facets.
Any help is greatly appreciated.
To get a different custom axis order in each facet, you can create each "facet" as a separate plot and then lay them out together as if they were a single faceted plot.
library(tidyverse)
#devtools::install_github("baptiste/egg")
library(egg)
library(gridExtra)
library(grid)
theme_set(theme_bw())
First, create the custom orderings. The ones that are NULL will just be sorted alphabetically in the final plot.
b.order = list(b1 = NULL,
b2 = NULL,
b3 = c("p11e13d00","p11e12d00", "p11e11d00", "p11e00d00", "p11e21d00", "p11e22d00","p11e23d00"),
b4 = c("p00e00d13", "p00e00d12", "p00e00d11", "p00e00d00", "p00e00d21","p00e00d22","p00e00d23"),
b5 = NULL)
Create a list of plots, one for each block. We do this by splitting df by block. To get the custom ordering, we use factor to set the custom order based on the list b.order.
plist = map2(split(df, df$block), b.order,
~ .x %>% group_by(block) %>%
mutate(item = factor(item, levels=if(is.null(.y)) sort(unique(item)) else .y)) %>%
ggplot(aes(x = item, y = freq)) +
geom_bar(stat = "identity", position = "dodge", color = "black") +
facet_grid(.~block, scales = "free") +
coord_cartesian(ylim = c(0, 1), expand = F) + # need to add expanse = F to prevent zooming away
scale_y_continuous(labels = scales::percent) +
theme(axis.text.x = element_text(angle=45, hjust=1, vjust=1),
plot.margin=margin(b=-5)) +
labs(x=""))
Remove y-axis labels, title, and ticks from all but the left-most plot:
plist[2:length(plist)] = plist[2:length(plist)] %>%
map(~ .x + theme(axis.text.y=element_blank(),
axis.title.y=element_blank(),
axis.ticks.y=element_blank()))
Arrange the plots. We use ggarrange from the egg package in order to ensure that the plot panels all have the same horizontal width. We also need to add the Item label beneath the plot. However, ggarrange prints the plot to the output device, even inside arrangeGrob. So we create the object p, clear the device and then redraw the final plot.
p = arrangeGrob(ggarrange(plots=plist, ncol=length(plist)),
textGrob("Item"), heights=c(20,1))
grid.newpage()
grid.draw(p)

Resources