01_Analysis_Dataset1.R 64 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746
  1. ##' Data Analysis of Electroantennogram Data from two different Stonefly Ecotypes
  2. ##' (full-winged and wing-reduced)
  3. ##'
  4. ##' Main R routine to reproduce the Fig 1, Fig 2, and Fig S1 from the manuscript
  5. ##' entitled 'Rapid evolution of olfactory degradation in recently flightless
  6. ##' insects'.
  7. ##'
  8. ##
  9. # load R packages
  10. library(dplyr)
  11. library(tidyr)
  12. library(ggplot2)
  13. library(tibble)
  14. library(ggbeeswarm)
  15. library(scales)
  16. library(arm)
  17. library(blmeco)
  18. library(lemon)
  19. library(ggpubr)
  20. library(grid)
  21. library(gridExtra)
  22. library(magick)
  23. library(cowplot)
  24. library(grImport)
  25. library(pdftools)
  26. library(multitaper)
  27. # clean up environment
  28. rm(list=ls())
  29. # set working directory
  30. setwd(dirname(rstudioapi::getActiveDocumentContext()$path))
  31. # load function to calculate various response dynamic measures
  32. source("./functions/responseDynamics.R")
  33. source('./functions/utils.R')
  34. fig_path <- "../Figures"
  35. ### colors for stoneflies ###
  36. fw_l <- "#787878" ## full-winged: grey
  37. wr_l <- "#00CC00" ## wing-reduced: green
  38. ## load the sub plots for Fig. 1
  39. Fig1A <- magick::image_read_pdf('../Pictures/Fig1A.pdf')
  40. Fig1A <- ggplot() +
  41. theme_bw() +
  42. theme(panel.border = element_blank()) +
  43. draw_image(Fig1A)
  44. Fig1B <- magick::image_read_pdf('../Pictures/Fig1B.pdf')
  45. Fig1B <- ggplot() +
  46. theme_bw() +
  47. theme(panel.border = element_blank()) +
  48. draw_image(Fig1B)
  49. # number of simulation draws from posterior distribution
  50. nsim <- 10000
  51. # aspect ratio (as y/x) for trace plots
  52. ar <- 2/3
  53. ## Read data set
  54. data2 <- read.csv('../Datasets/Dataset1.csv', stringsAsFactors = FALSE)
  55. # create median filtered mean traces (only for non-10Hz stimulations)
  56. med <- as.data.frame(t(apply(X = data2[data2$PulseDuration != 50, paste0("t", 1:5000)],
  57. MARGIN = 1,
  58. FUN = runmed, k = 11)))
  59. data2[data2$PulseDuration != 50, paste0("t", 1:5000)] <- med
  60. ### automatically exclude alive Antennae that are not responding to 2-HeptanonTest ######
  61. heptTest <- data2 %>%
  62. filter(Odor=="2HeptanoneTest", AntennaState=="alive")
  63. par(mfrow=c(4,4))
  64. analyze <- vector("logical", 0)
  65. heptTest$keep <- NA
  66. for(i in 1:nrow(heptTest)) {
  67. # in which ms is the signal higher than 2 x sd during 2 to 5 sec win of trace
  68. num <- which(heptTest[i, paste0("t", 250:1200)] > 2 * sd(heptTest[i, paste0("t", 2000:5000)]))
  69. result <- rle(diff(num))
  70. ## above threshold for at least 50 ms in a row?
  71. an <- any(result$lengths >= 50 & result$values==1)
  72. heptTest[i, "keep"] <- an
  73. analyze <- c(analyze, an)
  74. }
  75. ID_keep <- unique(heptTest$ID_new[heptTest$keep])
  76. ID_keep <- c(ID_keep, unique(data2[data2$Group=="PID", "ID_new"]))
  77. data2 <- data2[data2$ID_new %in% ID_keep, ]
  78. data2 <- droplevels(data2)
  79. ## Correct for amplification
  80. ## Note: 1 unit for different groups has different voltage ranges
  81. ## PID - 30 V
  82. ## Bee - 10 mV
  83. ## Fenestrata - 1 mV
  84. multiply_voltage <- 1/data2$Amplification
  85. data2[, paste0("t", 1:5000)] <- data2[, paste0("t", 1:5000)] * multiply_voltage # in Volt
  86. data2[data2$Group != "PID", paste0("t", 1:5000)] <- data2[data2$Group != "PID", paste0("t", 1:5000)] * 1000 # in millivolt
  87. ## Convert some columns to a factor
  88. data2$ID_new <- as.factor(data2$ID_new)
  89. data2$Winged <- factor(data2$Winged, levels = c("full-winged", "wing-reduced", "none"))
  90. data2$Location <- as.character(data2$Location)
  91. data2$Location[data2$Group=="PID"] <- "PID"
  92. data2$Location[data2$Species=="Honeybee"] <- "Bee"
  93. # reorder the factor levels of column Odor and adjust the names
  94. data2$Odor <- factor(data2$Odor, levels = c("Blank", "2Heptanone", "1Octanol",
  95. "PropionicAcid", "2Butanone", "Stonefly", "2HeptanoneTest"),
  96. labels = c("Blank","2-heptanone", "1-octanol",
  97. "Propionic acid", "2-butanone", "Stonefly", "2-heptanone (2nd)"))
  98. data2$Group <- factor(data2$Group, levels = c("Burns",
  99. "BlackJack", "Whisky", "SixMile",
  100. "Lug", "Bee", "PID"),
  101. labels = c("Mt Burns", "Black Jacks", "Whiskey", "Six Mile", "Lug", "Bee", "PID"))
  102. data2 <- data2 %>%
  103. filter(AntennaState == "alive" | Group == "PID")
  104. data2$NewGroup <- paste(data2$Group, data2$Winged)
  105. data2$NewGroup <- as.factor(data2$NewGroup)
  106. data2 <- droplevels(data2)
  107. new_colnames <- c("Timeto10Max",
  108. "Timeto90Max",
  109. "TimetoMax",
  110. "TimeFromMaxto90",
  111. "TimeFromMaxto10",
  112. "Time10to90Max",
  113. "Time90to10Max",
  114. "Timeto10Min",
  115. "Timeto90Min",
  116. "TimetoMin",
  117. "TimeFromMinto90",
  118. "TimeFromMinto10",
  119. "Time10to90Min",
  120. "Time90to10Min",
  121. "MeanMax",
  122. "MeanMin")
  123. y1 <- as.data.frame(t(apply(data2[,paste0("t", 201:5000)], 1, responseDynamics, from=0.1, to=0.9)))
  124. colnames(y1) <- new_colnames
  125. data2 <- cbind(as.data.frame(data2), y1)
  126. data2 <- data2 %>%
  127. mutate(Timeto10 = ifelse(Odor == "Propionic acid" |
  128. Odor == "Stonefly", Timeto10Min, Timeto10Max),
  129. Time10to90 = ifelse(Odor == "Propionic acid" |
  130. Odor == "Stonefly", Time10to90Min, Time10to90Max),
  131. Time90to10 = ifelse(Odor == "Propionic acid" |
  132. Odor == "Stonefly", Time10to90Min, Time90to10Max))
  133. data2$max <- apply(data2[,paste0("t", 251:1200)], 1, max)
  134. data2$min <- apply(data2[,paste0("t", 251:1200)], 1, min)
  135. data2 <- data2 %>%
  136. mutate(mima = ifelse(Odor == "Propionic acid" |
  137. Odor == "Stonefly", min, max))
  138. data2 <- data2 %>%
  139. mutate(Mean = ifelse(Odor == "Propionic acid" |
  140. Odor == "Stonefly", MeanMin, MeanMax))
  141. data2 <- data2 %>%
  142. mutate(TimeBackTo10 = ifelse(Odor == "Propionic acid" |
  143. Odor == "Stonefly", TimeFromMinto10, TimeFromMaxto10))
  144. data2 %>%
  145. filter(Odor=="2-heptanone" | Odor=="2-heptanone (2nd)", PulseDuration==300) %>%
  146. group_by(Winged, ID_new, AntennaState) %>%
  147. summarise(ratio = mima[Odor=="2-heptanone (2nd)"] / mima[Odor=="2-heptanone"]) %>%
  148. group_by(Winged, AntennaState) %>%
  149. summarise(mean=mean(ratio), sd=sd(ratio), median=median(ratio), n=n())
  150. #######################################
  151. ### How big is the sample size for the different groups?
  152. data2 %>%
  153. group_by(Location, Group, Winged, ID_new) %>%
  154. summarise(n=n()) %>%
  155. group_by(Location, Group, Winged) %>%
  156. summarise(n=n())
  157. tst <- data2
  158. tst <- droplevels(tst)
  159. table(tst$Config, tst$Group, tst$Winged)
  160. locations <- c("Mt Burns", "Black Jacks", "Whiskey", "Six Mile", "Lug")
  161. odors <- c("2-heptanone", "1-octanol", "2-butanone", "2-heptanone (2nd)")
  162. ############## Statistics #############
  163. ## Bayesian Statistics ###
  164. creeks <- locations
  165. plot_bayes_mima <- function(data, groups) {
  166. ################################################################################
  167. data1 <- data2
  168. odors <- c("2-heptanone", "1-octanol", "2-butanone")
  169. df <- as.data.frame(matrix(NA, ncol=7, nrow = 0))
  170. newDf <- as.data.frame(matrix(NA, ncol=3, nrow = 0))
  171. newDf_all <- as.data.frame(matrix(NA, ncol=3, nrow = 0))
  172. for (odor in odors) {
  173. if (odor == '2-heptanone') {
  174. data <- data1 %>% filter(Odor %in% c('2-heptanone (2nd)', '2-heptanone'))
  175. } else {
  176. data <- data1 %>% filter(Odor == odor)
  177. }
  178. data <- data %>% filter(Group %in% groups, PulseDuration != 50)
  179. data$PulseDuration <- as.character(data$PulseDuration)
  180. data$PulseDuration <- ifelse(data$PulseDuration == 300 & data$Odor == '2-heptanone (2nd)',
  181. '300\n (2nd)', data$PulseDuration)
  182. data$Odor <- as.character(data$Odor)
  183. data$Odor <- ifelse(data$Odor == '2-heptanone (2nd)', '2-heptanone', data$Odor)
  184. data$Location <- factor(data$Location)
  185. data$PulseDuration <- factor(data$PulseDuration, levels = c('15', '30', '150', '300', '300\n (2nd)'))
  186. data <- droplevels(data)
  187. for (cc in seq_along(groups)) {
  188. subdata <- data %>% filter(Group == groups[cc])
  189. subdata$PulseDuration <- as.factor(subdata$PulseDuration)
  190. subdata <- droplevels(subdata)
  191. min_mean <- min(subdata$Mean)
  192. if (min_mean < 0) {
  193. subdata$adj_Mean <- subdata$Mean + abs(min_mean) + 0.01
  194. } else {
  195. subdata$adj_Mean <- subdata$Mean
  196. }
  197. subdata$log2 <- log2(subdata$adj_Mean)
  198. if (nrow(subdata) == 0)
  199. next
  200. if (length(unique(subdata$PulseDuration)) == 1) {
  201. m1 <- lm(log2 ~ Winged, data=subdata)
  202. } else {
  203. if (unique(subdata$Winged == 'none')) {
  204. m1 <- lmer(log2 ~ PulseDuration + (1 | ID_new), data=subdata, REML = FALSE)
  205. } else {
  206. m1 <- lmer(log2 ~ Winged * PulseDuration + (1 | ID_new), data=subdata, REML = FALSE)
  207. }
  208. }
  209. par(mfrow=c(2,2))
  210. if (length(unique(subdata$PulseDuration)) != 1) {
  211. scatter.smooth(fitted(m1), resid(m1))
  212. abline(h=0, lty=2)
  213. title("Tukey-Anscombe Plot") # residuals vs. fitted
  214. qqnorm(resid(m1), main="normal QQ-plot, residuals") # qq of residuals
  215. qqline(resid(m1))
  216. scatter.smooth(fitted(m1), sqrt(abs(resid(m1)))) # res. var vs. fitted
  217. qqnorm(ranef(m1)$ID_new[,1], main="normal QQ-plot, random effects")
  218. qqline(ranef(m1)$ID_new[,1]) # qq of random effects
  219. } else {
  220. plot(m1)
  221. }
  222. summary(m1)
  223. if (length(unique(subdata$PulseDuration)) == 1) {
  224. tmp <- unique(paste( subdata$PulseDuration, subdata$Winged, subdata$Odor, sep = '_'))
  225. tmp <- as.data.frame(matrix(unlist(strsplit(tmp, split = '_')), ncol=3, byrow = TRUE))
  226. tmp <- tmp[order(as.numeric(as.character(tmp$V1)), tmp$V2, tmp$V3), ]
  227. colnames(tmp) <- c('PulseDuration', 'Winged', 'Odor')
  228. tmp$PulseDuration <- factor(tmp$PulseDuration)
  229. tmp$PulseDuration <- factor(tmp$PulseDuration,
  230. levels = levels(tmp$PulseDuration)[order(as.numeric(as.character(levels(tmp$PulseDuration))))])
  231. tmp$Winged <- factor(tmp$Winged, levels = c('full-winged', 'wing-reduced'))
  232. tmp$Odor <- factor(tmp$Odor, levels = c('2-heptanone', '1-octanol', '2-butanone'))
  233. newdat <- tmp
  234. bsim <- sim(m1, n.sim=nsim)
  235. fitmat <- matrix(ncol=nsim, nrow=nrow(newdat))
  236. Xmat <- model.matrix( ~ Winged, data=newdat)
  237. for(i in 1:nsim) fitmat[,i] <- Xmat %*% bsim@coef[i,] #fitted values
  238. tmp <- t(apply(fitmat, 1, quantile, prob=c(0.025, 0.5, 0.975)))
  239. if (min_mean < 0) {
  240. tmp <- 2^(tmp) - abs(min_mean) - 0.01
  241. } else {
  242. tmp <- 2^(tmp)
  243. }
  244. tst <- cbind(newdat, tmp, 'Group' = groups[cc])
  245. df <- rbind(df, tst)
  246. for (oo in levels(newdat$Odor)) {
  247. datt <- newdat[newdat$Odor == oo, ]
  248. for (pp in unique(datt$PulseDuration)) {
  249. dat <- fitmat[which(newdat$PulseDuration == pp & newdat$Odor == oo), ]
  250. star2 <- sum(dat[1, ] > dat[2, ]) / nsim
  251. newDf <- rbind(newDf,
  252. data.frame('Group' = groups[cc],
  253. 'Odor' = oo,
  254. 'Diff' = star2,
  255. 'PulseDuration' = pp))
  256. }
  257. }
  258. } else {
  259. if (unique(subdata$Winged == 'none')) {
  260. #######################
  261. tmp <- unique(paste(subdata$PulseDuration, subdata$Winged, subdata$Odor, sep = '_'))
  262. tmp <- as.data.frame(matrix(unlist(strsplit(tmp, split = '_')), ncol=3, byrow = TRUE))
  263. tmp <- tmp[order(as.numeric(as.character(tmp$V1)), tmp$V2, tmp$V3), ]
  264. colnames(tmp) <- c('PulseDuration', 'Winged', 'Odor')
  265. tmp$PulseDuration <- factor(tmp$PulseDuration)
  266. tmp$PulseDuration <- factor(tmp$PulseDuration,
  267. levels = levels(tmp$PulseDuration)[order(as.numeric(as.character(levels(tmp$PulseDuration))))])
  268. tmp$Winged <- factor(tmp$Winged, levels = c('full-winged', 'wing-reduced', 'none'))
  269. tmp$Odor <- factor(tmp$Odor, levels = c('2-heptanone', '1-octanol', '2-butanone'))
  270. newdat <- tmp
  271. bsim <- sim(m1, n.sim=nsim)
  272. fitmat <- matrix(ncol=nsim, nrow=nrow(newdat))
  273. Xmat <- model.matrix( ~ PulseDuration, data=newdat)
  274. for(i in 1:nsim) fitmat[,i] <- Xmat %*% bsim@fixef[i,] #fitted values
  275. names(Xmat)
  276. length(newdat$Odor)
  277. tmp <- t(apply(fitmat, 1, quantile, prob=c(0.025, 0.5, 0.975)))
  278. if (min_mean < 0) {
  279. tmp <- 2^(tmp) - abs(min_mean) - 0.01
  280. } else {
  281. tmp <- 2^(tmp)
  282. }
  283. tst <- cbind(newdat, tmp, 'Group' = groups[cc])
  284. df <- rbind(df, tst)
  285. for (oo in levels(newdat$Odor)) {
  286. datt <- newdat[newdat$Odor == oo, ]
  287. for (pp in unique(datt$PulseDuration)) {
  288. dat <- fitmat[which(newdat$PulseDuration == pp & newdat$Odor == oo), ]
  289. newDf <- rbind(newDf,
  290. data.frame('Group' = groups[cc],
  291. 'Odor' = oo,
  292. 'Diff' = 0.5,
  293. 'PulseDuration' = pp))
  294. }
  295. }
  296. #######################
  297. } else {
  298. tmp <- unique(paste( subdata$PulseDuration, subdata$Winged, subdata$Odor, sep = '_'))
  299. tmp <- as.data.frame(matrix(unlist(strsplit(tmp, split = '_')), ncol=3, byrow = TRUE))
  300. tmp <- tmp[order(as.numeric(as.character(tmp$V1)), tmp$V2, tmp$V3), ]
  301. colnames(tmp) <- c('PulseDuration', 'Winged', 'Odor')
  302. tmp$PulseDuration <- factor(tmp$PulseDuration)
  303. tmp$PulseDuration <- factor(tmp$PulseDuration,
  304. levels = levels(tmp$PulseDuration)[order(as.numeric(as.character(levels(tmp$PulseDuration))))])
  305. tmp$Winged <- factor(tmp$Winged, levels = c('full-winged', 'wing-reduced'))
  306. tmp$Odor <- factor(tmp$Odor, levels = c('2-heptanone', '1-octanol', '2-butanone'))
  307. newdat <- tmp
  308. bsim <- sim(m1, n.sim=nsim)
  309. fitmat <- matrix(ncol=nsim, nrow=nrow(newdat))
  310. Xmat <- model.matrix( ~ Winged * PulseDuration, data=newdat)
  311. for(i in 1:nsim) fitmat[,i] <- Xmat %*% bsim@fixef[i,] #fitted values
  312. tmp <- t(apply(fitmat, 1, quantile, prob=c(0.025, 0.5, 0.975)))
  313. if (min_mean < 0) {
  314. tmp <- 2^(tmp) - abs(min_mean) - 0.01
  315. } else {
  316. tmp <- 2^(tmp)
  317. }
  318. tst <- cbind(newdat, tmp, 'Group' = groups[cc])
  319. df <- rbind(df, tst)
  320. for (oo in levels(newdat$Odor)) {
  321. datt <- newdat[newdat$Odor == oo, ]
  322. for (pp in unique(datt$PulseDuration)) {
  323. dat <- fitmat[which(newdat$PulseDuration == pp & newdat$Odor == oo), ]
  324. star2 <- sum(dat[1, ] > dat[2, ]) / nsim
  325. newDf <- rbind(newDf,
  326. data.frame('Group' = groups[cc],
  327. 'Odor' = oo,
  328. 'Diff' = star2,
  329. 'PulseDuration' = pp))
  330. }
  331. }
  332. }
  333. }
  334. }
  335. }
  336. colnames(df)[4:6] <- c("lower", "fitted", "upper")
  337. newDf
  338. newDf$Star1 <- newDf$Diff >= 0.95 | newDf$Diff <= 0.05
  339. newDf$Star2 <- newDf$Diff >= 0.99 | newDf$Diff <= 0.01
  340. newDf$Star <- ''
  341. newDf$Star[newDf$Star1 == TRUE] <- '*'
  342. newDf$Star[newDf$Star2 == TRUE] <- '**'
  343. df$Group
  344. newDf$Winged <- 'star'
  345. col <- c(fw_l, wr_l, "blue")
  346. plotdata <- data1 %>%
  347. filter(Odor %in% c("2-heptanone", "2-heptanone (2nd)"),
  348. PulseDuration != 50)
  349. plotdata$PulseDuration <- as.character(plotdata$PulseDuration)
  350. plotdata$PulseDuration[plotdata$Odor == "2-heptanone (2nd)"] <- '300\n (2nd)'
  351. plotdata$Odor[plotdata$Odor == "2-heptanone (2nd)"] <- "2-heptanone"
  352. plotdata$PulseDuration <- factor(plotdata$PulseDuration, levels = c(15, 30, 150, 300, "300\n (2nd)"))
  353. plotdf <- df %>%
  354. filter(Odor %in% c("2-heptanone", "2-heptanone (2nd)"))
  355. plotdf$PulseDuration <- as.character(plotdf$PulseDuration)
  356. plotdf$PulseDuration[plotdf$Odor == "2-heptanone (2nd)"] <- '300\n (2nd)'
  357. plotdf$Odor[plotdf$Odor == "2-heptanone (2nd)"] <- "2-heptanone"
  358. plotdf$PulseDuration <- factor(plotdf$PulseDuration, levels = c(15, 30, 150, 300, "300\n (2nd)"))
  359. newDf_plot <- newDf %>%
  360. filter(Odor %in% c("2-heptanone", "2-heptanone (2nd)"))
  361. newDf_plot$PulseDuration <- as.character(newDf_plot$PulseDuration)
  362. newDf_plot$PulseDuration[newDf_plot$Odor == "2-heptanone (2nd)"] <- '300\n (2nd)'
  363. newDf_plot$Odor[newDf_plot$Odor == "2-heptanone (2nd)"] <- "2-heptanone"
  364. newDf_plot$PulseDuration <- factor(newDf_plot$PulseDuration, levels = c(15, 30, 150, 300, "300\n (2nd)"))
  365. fen <- ggplot(plotdata %>% filter(Group %in% creeks), aes(PulseDuration, Mean, color=Winged)) +
  366. facet_grid(Odor ~ Group) +
  367. geom_beeswarm(dodge.width = 0.5, pch = 1) +
  368. geom_errorbar(data=plotdf %>% filter(Group %in% creeks), aes(ymin=lower, ymax=upper, y=NULL),
  369. color="black", width=0.5, position = position_dodge2(padding = 1, width=0.1)) +
  370. stat_summary(data=newDf_plot %>% filter(Group %in% creeks),
  371. aes(x=as.factor(PulseDuration), y=0.15, label = Star),
  372. geom = 'text', fun = max, color="black",
  373. size = 8) +
  374. geom_beeswarm(data=plotdf %>% filter(Group %in% creeks), aes(y = fitted, group = Winged),
  375. pch = '_', dodge.width = 0.5, color = 'black', size=3) +
  376. scale_color_manual(aesthetics = c("colour", "fill"), values = col) +
  377. theme_bw() +
  378. theme(legend.position = "none",
  379. panel.grid.major = element_blank(),
  380. panel.grid.minor = element_blank(),
  381. axis.line = element_line(colour = "black"),
  382. axis.title = element_blank(),
  383. strip.background = element_rect(colour="NA", fill="NA"),
  384. strip.text = element_blank(),
  385. panel.border = element_blank(),
  386. text = element_text(size=16),
  387. axis.text = element_text(colour="black"))
  388. fen
  389. bee <- ggplot(plotdata %>% filter(Group %in% 'Bee'), aes(PulseDuration, Mean, color=Winged)) +
  390. facet_grid(Odor ~ Group) +
  391. geom_beeswarm(dodge.width = 0.5, pch = 1) +
  392. geom_errorbar(data=plotdf %>% filter(Group %in% 'Bee'), aes(ymin=lower, ymax=upper, y=NULL), color="black",
  393. width=0, position = position_dodge2(padding = 1, width=0.1)) +
  394. scale_color_manual(aesthetics = c("colour", "fill"), values = 'blue') +
  395. theme_bw() +
  396. geom_beeswarm(data=plotdf %>% filter(Group %in% 'Bee'), aes(y=fitted, group=Winged),
  397. pch = '_', color = 'black', groupOnX = TRUE, size=3) +
  398. theme(legend.position = "none",
  399. panel.grid.major = element_blank(),
  400. panel.grid.minor = element_blank(),
  401. axis.line = element_line(colour = "black"),
  402. axis.title=element_blank(),
  403. strip.background = element_rect(colour="NA", fill="NA"),
  404. strip.text = element_blank(),
  405. panel.border = element_blank(),
  406. text = element_text(size=16),
  407. axis.text=element_text(colour="black"))
  408. bee
  409. pid <- ggplot(plotdata %>% filter(Group %in% 'PID'), aes(PulseDuration, Mean, color=Winged)) +
  410. facet_grid(Odor ~ Group) +
  411. geom_beeswarm(dodge.width = 0.5, pch = 1) +
  412. geom_errorbar(data=plotdf %>% filter(Group %in% 'PID'), aes(ymin=lower, ymax=upper, y=NULL),
  413. color="black", width=0, position = position_dodge2(padding = 1, width=0.1)) +
  414. scale_color_manual(aesthetics = c("colour", "fill"), values = 'blue') +
  415. theme_bw() +
  416. geom_beeswarm(data=plotdf %>% filter(Group %in% 'PID'), aes(y=fitted, group=Winged),
  417. pch = '_', dodge.width = 0.5, color = 'black', groupOnX = TRUE, size=3) +
  418. theme(legend.position = "none",
  419. panel.grid.major = element_blank(),
  420. panel.grid.minor = element_blank(),
  421. axis.line = element_line(colour = "black"),
  422. axis.title=element_blank(),
  423. plot.tag = element_text(size = 14, hjust = 0.5, vjust = 0.5),
  424. plot.tag.position = c(0.02, 1 - 0.03),
  425. strip.background = element_rect(colour="NA", fill="NA"),
  426. strip.text = element_blank(),
  427. panel.border = element_blank(),
  428. text = element_text(size=16),
  429. axis.text=element_text(colour="black"))
  430. pid
  431. l <- list('Diffs' = newDf, 'Mean_crI' = df, 'fen' = fen, 'bee' = bee, 'pid' = pid)
  432. return(l)
  433. }
  434. ### Figure S1 #####
  435. Fly_mean <- plot_bayes_mima(data = data2, groups = c(creeks, 'Bee', 'PID'))
  436. FigS1B <- egg::ggarrange(Fly_mean$fen, Fly_mean$bee, Fly_mean$pid, clip = FALSE,
  437. labels = c('', '', expression(x ~ 10^3)), label.args = list(vjust=0),
  438. nrow = 1, ncol=3, widths = c(5, 1, 1), heights = c(6), debug = FALSE)
  439. y.grob <- textGrob(paste("Response strength (mV)"),
  440. gp=gpar(fontsize=18), rot=90)
  441. x.grob <- textGrob("Pulse duration (ms)",
  442. gp=gpar(fontsize=18))
  443. #add to plot
  444. FigS1B <- grid.arrange(arrangeGrob(FigS1B, left = y.grob, bottom = x.grob))
  445. plot_winged_all <- function(data, odors, creeks, Diffs) {
  446. data <- data2
  447. data <- data %>%
  448. filter(Group %in% c(creeks, "Bee", "PID")) %>%
  449. filter(PulseDuration == 300) %>%
  450. filter(Odor %in% odors)
  451. data <- droplevels(data)
  452. data$Odor <- factor(data$Odor, levels = levels(data$Odor),
  453. labels = c("2-heptanone", "1-octanol", "2-butanone", "2-heptanone\n (2nd)"))
  454. # calculate the mean over all odor-pulseduration configurations
  455. d_mean <- data %>%
  456. group_by(Group, Winged, Odor, PulseDuration) %>%
  457. summarise_at(.funs = mean, .vars=paste0("t", 1:5000))
  458. # calculate the standard error over all odor-pulseduration configurations
  459. d_se <- data %>%
  460. group_by(Group, Winged, Odor, PulseDuration) %>%
  461. summarise_at(.funs = se, .vars=paste0("t", 1:5000))
  462. # calculate sample size (n) over all odor-pulseduration configurations
  463. d_n <- data %>%
  464. group_by(Group, Winged, Odor, PulseDuration) %>%
  465. summarise(N=n()) %>%
  466. group_by(Group, Winged) %>%
  467. summarise(N=unique(N))
  468. d_max <- d_mean %>%
  469. group_by(Group, Odor, PulseDuration) %>%
  470. summarise(Max=max(t400))
  471. # create d_all and add the sample size
  472. d_all <- d_mean
  473. data_se <- gather(d_se, time, se, t1:t5000, factor_key=TRUE)
  474. d_all$PulseDuration <- factor(d_all$PulseDuration, levels = c(300))
  475. d_all$PulseDur <- factor(d_all$PulseDuration, levels = c(300),
  476. labels = c("300 ms"))
  477. data_long <- gather(d_all, time, Voltage, t1:t5000, factor_key=TRUE)
  478. data_long$time <- (as.numeric(gsub("t", "", data_long$time)) - 200)/1000
  479. data_long$SE <- data_se$se
  480. data_long$high <- data_long$Voltage + data_long$SE
  481. data_long$low <- data_long$Voltage - data_long$SE
  482. tmp <- expand.grid(creeks, c("FW", "WR"), stringsAsFactors = FALSE)
  483. tmp <- tmp[order(tmp$Var1), ]
  484. tmp <- paste0(tmp$Var2, ", ", tmp$Var1)
  485. tmp <- c(tmp, "Bee", "PID")
  486. data_long$NewGroup <- factor(paste(data_long$Winged, data_long$Group),
  487. labels = tmp)
  488. col <- c(fw_l, wr_l, "blue")
  489. print(d_n)
  490. geom.text.size <- 5.2
  491. data_long$Winged <- factor(data_long$Winged,
  492. levels = levels(data_long$Winged),
  493. labels = c("Full-winged", "Wing-reduced", "none"))
  494. data_segm1 <- data.frame(y=0, yend=0.1, x=Inf, xend=Inf,
  495. PulseDuration= c(300),
  496. Group="Lug",
  497. Odor=c("2-heptanone\n (2nd)"))
  498. label1 <- data.frame(x=Inf, y=0.05,
  499. text=c("0.1 mV"),
  500. PulseDuration= c(300),
  501. Group="Lug",
  502. Odor=c("2-heptanone\n (2nd)"))
  503. fw_text <- data.frame(x = 1, y = 0.07,
  504. text=c("full-winged"),
  505. PulseDuration= c(300),
  506. Group="Mt Burns",
  507. Odor=c("2-heptanone"))
  508. wr_text <- data.frame(x = 1, y = 0.1,
  509. text=c("wing-reduced"),
  510. PulseDuration= c(300),
  511. Group="Mt Burns",
  512. Odor=c("2-heptanone"))
  513. Diffs$Odor <- as.character(Diffs$Odor)
  514. Diffs$Odor[Diffs$PulseDuration == '300\n (2nd)'] <- '2-heptanone\n (2nd)'
  515. Diffs$Odor <- factor(Diffs$Odor)
  516. Diffs$Odor <- factor(Diffs$Odor, levels = c('2-heptanone', '1-octanol', '2-butanone', '2-heptanone\n (2nd)'))
  517. Diffs$PulseDuration[Diffs$PulseDuration == '300\n (2nd)'] <- '300'
  518. Diffs <- droplevels(Diffs)
  519. Diffs <- merge(Diffs, d_max, by = c('Group', 'Odor', 'PulseDuration'))
  520. ## plotting mean and se
  521. Fen <- ggplot(data_long %>% filter(Group %in% creeks), aes(x=time, y=Voltage)) +
  522. facet_grid(Odor ~ Group, switch = "y") +
  523. geom_rect(mapping=aes(xmin=0, xmax=as.numeric(as.character(PulseDuration))/1000,
  524. ymin=-Inf, ymax=Inf),
  525. fill="grey90", alpha=1) +
  526. scale_color_manual(aesthetics = c("colour", "fill"), values = col) +
  527. geom_hline(mapping = aes(yintercept = 0), color="black", size=0.3, linetype="dotted") +
  528. geom_ribbon(aes(ymin=Voltage + SE, ymax=Voltage - SE, fill=Winged),
  529. color=NA, alpha=0.3) +
  530. geom_line(aes(colour = Winged)) +
  531. theme_bw() +
  532. theme(legend.position = "none",
  533. panel.grid.major = element_blank(),
  534. panel.grid.minor = element_blank(),
  535. axis.line = element_blank(),
  536. axis.title = element_blank(),
  537. plot.margin = unit(c(5.5, 5.5, 5.5, 5.5), "points"),
  538. strip.background = element_rect(colour="NA", fill="NA"),
  539. panel.border = element_blank(),
  540. text = element_text(size=18),
  541. axis.ticks = element_blank(),
  542. aspect.ratio = ar * 4,
  543. strip.text.y.left = element_text(angle = 0, size = 16),
  544. strip.text.x = element_text(size = 16),
  545. axis.text=element_blank()) +
  546. geom_segment(data=data_segm1,
  547. aes(x=x, y=y, yend=yend, xend=xend)) +
  548. geom_text(data = label1, aes(x=x, y=y, label=text), size=geom.text.size, hjust=1.1) +
  549. geom_text(data = wr_text, aes(x=x, y=y, label=text), size=4, hjust=0, color=wr_l) +
  550. geom_text(data = fw_text, aes(x=x, y=y, label=text), size=4, hjust=0, color=fw_l) +
  551. geom_text(data = Diffs, aes(x=0.4, y=Max + 0.025, label=Star), size=geom.text.size, hjust=0.5) +
  552. coord_cartesian(expand = TRUE,
  553. clip = 'off')
  554. Fen
  555. data_segm1 <- data.frame(y=0, yend=1, x=Inf, xend=Inf,
  556. PulseDuration= c(300),
  557. Group="Bee",
  558. Odor=c("2-heptanone\n (2nd)"))
  559. label1 <- data.frame(x=Inf, y=0.5,
  560. text=c("1 mV"),
  561. PulseDuration= c(300),
  562. Group="Bee",
  563. Odor=c("2-heptanone\n (2nd)"))
  564. seg <- data.frame(x=4.5, y = -0.35,
  565. text=c(""),
  566. PulseDuration= c(300),
  567. Group="Bee",
  568. Odor=c("2-heptanone\n (2nd)"))
  569. B <- ggplot(data_long %>% filter(Group %in% "Bee"), aes(x=time, y=Voltage)) +
  570. facet_grid(Odor ~ Group, switch = "y") +
  571. geom_rect(mapping=aes(xmin=0, xmax=as.numeric(as.character(PulseDuration))/1000,
  572. ymin=-Inf, ymax=Inf),
  573. fill="grey90", alpha=1) +
  574. scale_color_manual(aesthetics = c("colour", "fill"), values = "Blue") +
  575. geom_hline(mapping = aes(yintercept = 0), color="black", size=0.3, linetype="dotted") +
  576. geom_ribbon(aes(ymin=Voltage + SE, ymax=Voltage - SE, fill=Winged),
  577. color=NA, alpha=0.3) +
  578. geom_line(aes(colour = Winged)) +
  579. theme_bw() +
  580. theme(legend.position = "none",
  581. panel.grid.major = element_blank(),
  582. panel.grid.minor = element_blank(),
  583. axis.line = element_blank(),
  584. axis.title = element_blank(),
  585. plot.margin = unit(c(5.5, 5.5, 5.5, 5.5), "points"),
  586. strip.background = element_rect(colour="NA", fill="NA"),
  587. panel.border = element_blank(),
  588. text = element_text(size=18),
  589. axis.ticks = element_blank(),
  590. aspect.ratio = ar * 4,
  591. strip.text.y.left = element_blank(),
  592. strip.text.x = element_text(size = 16),
  593. axis.text=element_blank()) +
  594. geom_blank(data = seg, mapping = aes(x=x, y=y), inherit.aes = FALSE) +
  595. geom_segment(data=data_segm1,
  596. aes(x=x, y=y, yend=yend, xend=xend)) +
  597. geom_text(data = label1, aes(x=x, y=y, label=text), size=geom.text.size, hjust=1.1) +
  598. coord_cartesian(expand = TRUE,
  599. clip = 'off')
  600. data_segm1 <- data.frame(y=0, yend=c(3, 0.05, 3), x=Inf, xend=Inf,
  601. PulseDuration= c(300),
  602. Group="PID",
  603. Odor=c("2-heptanone\n (2nd)", "1-octanol", "2-heptanone"))
  604. label1 <- data.frame(x=Inf, y=c(1.5, 0.04, 1.5),
  605. text=c("3 V", "0.05 V", "3 V"),
  606. PulseDuration= c(300),
  607. Group="PID",
  608. Odor=c("2-heptanone\n (2nd)", "1-octanol","2-heptanone"))
  609. data_segm2 <- data.frame(x=3.5, xend=4.5, y=-0.3, yend=-0.3,
  610. PulseDuration= c(300),
  611. Group="PID",
  612. Odor=c("2-heptanone\n (2nd)"))
  613. label2 <- data.frame(x=4, y=-0.2,
  614. text=c("1 s"),
  615. PulseDuration= c(300),
  616. Group="PID",
  617. Odor=c("2-heptanone\n (2nd)"))
  618. seg <- data.frame(x=4.5, y = -0.35,
  619. text=c(""),
  620. PulseDuration= c(300),
  621. Group="PID",
  622. Odor=c("2-butanone"))
  623. P <- ggplot(data_long %>% filter(Group %in% "PID"), aes(x=time, y=Voltage)) +
  624. facet_grid(Odor ~ Group, switch = "y", scales = 'free_y') +
  625. geom_rect(mapping=aes(xmin=0, xmax=as.numeric(as.character(PulseDuration))/1000,
  626. ymin=-Inf, ymax=Inf),
  627. fill="grey90", alpha=1) +
  628. scale_color_manual(aesthetics = c("colour", "fill"), values = "Blue") +
  629. geom_hline(mapping = aes(yintercept = 0), color="black", size=0.3, linetype="dotted") +
  630. geom_ribbon(aes(ymin=Voltage + SE, ymax=Voltage - SE, fill=Winged),
  631. color=NA, alpha=0.3) +
  632. geom_line(aes(colour = Winged)) +
  633. theme_bw() +
  634. theme(legend.position = "none",
  635. panel.grid.major = element_blank(),
  636. panel.grid.minor = element_blank(),
  637. axis.line = element_blank(),
  638. axis.title = element_blank(),
  639. plot.margin = unit(c(5.5, 5.5, 5.5, 5.5), "points"),
  640. strip.background = element_rect(colour="NA", fill="NA"),
  641. panel.border = element_blank(),
  642. text = element_text(size=18),
  643. axis.ticks = element_blank(),
  644. aspect.ratio = ar * 4,
  645. strip.text.y.left = element_blank(),
  646. strip.text.x = element_text(size = 16),
  647. axis.text=element_blank()) +
  648. geom_blank(data = seg, mapping = aes(x=x, y=y), inherit.aes = FALSE) +
  649. geom_segment(data=data_segm1,
  650. aes(x=x, y=y, yend=yend, xend=xend)) +
  651. geom_text(data = label1, aes(x=x, y=y, label=text), size=geom.text.size, hjust=1.1) +
  652. geom_segment(data=data_segm2,
  653. aes(x=x, y=y, yend=yend, xend=xend)) +
  654. geom_text(data = label2, aes(x=x, y=y, label=text), size=geom.text.size, vjust=1.3) +
  655. coord_cartesian(expand = TRUE,
  656. clip = 'off')
  657. P
  658. cowplot::plot_grid(Fen, B, P, nrow = 1, align = "h")
  659. list1 <- list("traceW"=Fen,
  660. "traceB"=B,
  661. "traceP"=P)
  662. }
  663. traces300 <- plot_winged_all(data = data2,
  664. odors = odors,
  665. creeks = locations,
  666. Diffs = Fly_mean$Diffs %>% filter(Group %in% creeks,
  667. PulseDuration %in% c('300', '300\n (2nd)')))
  668. Fig1C <- egg::ggarrange(traces300$traceW, traces300$traceB, traces300$traceP,
  669. heights = 5, nrow = 1, ncol=3, widths = c(5, 1, 1), debug = FALSE)
  670. ########################
  671. data <- data2
  672. data <- data %>%
  673. filter(Group %in% c(creeks, "Bee", "PID")) %>%
  674. filter(Odor %in% c("2-heptanone"), !Frequency %in% 10, !PulseDuration %in% 300)
  675. data <- droplevels(data)
  676. data$Odor <- factor(data$Odor, levels = levels(data$Odor),
  677. labels = c("2-heptanone"))
  678. # calculate the mean over all odor-pulseduration configurations
  679. d_mean <- data %>%
  680. group_by(Group, Winged, Odor, PulseDuration) %>%
  681. summarise_at(.funs = median, .vars=paste0("t", 1:5000))
  682. # calculate sample size (n) over all odor-pulseduration configurations
  683. d_n <- data %>%
  684. group_by(Group, Winged, Odor, PulseDuration) %>%
  685. summarise(N=n()) %>%
  686. group_by(Group, Winged) %>%
  687. summarise(N=unique(N))
  688. d_max <- d_mean %>%
  689. group_by(Group, Odor, PulseDuration) %>%
  690. summarise(Max=max(t400))
  691. # create d_all and add the sample size
  692. d_all <- d_mean
  693. d_all$PulseDuration <- factor(d_all$PulseDuration, levels = c('15', '30', '150'))
  694. d_all$PulseDur <- factor(d_all$PulseDuration)
  695. data_long <- gather(d_all, time, Voltage, t1:t5000, factor_key=TRUE)
  696. data_long$time <- (as.numeric(gsub("t", "", data_long$time)) - 200)/1000
  697. print(d_n)
  698. geom.text.size <- 5.2
  699. data_long$Winged <- factor(data_long$Winged,
  700. levels = levels(data_long$Winged),
  701. labels = c("Full-winged", "Wing-reduced", "none"))
  702. data_segm1 <- data.frame(y=c(0, 0), yend=c(0.1, 0), x=c(Inf, 2), xend=c(Inf, 3),
  703. PulseDuration = factor(150, levels = c(15, 30, 150)),
  704. Group=factor(c("Lug", 'Mt Burns'), levels = creeks),
  705. Odor=c("2-heptanone"))
  706. label1 <- data.frame(x=c(Inf, 3), y=c(0.05, 0.02),
  707. text=c("0.1 mV", '1 s'),
  708. PulseDuration= factor(150, levels = c(15, 30, 150)),
  709. Group=factor(c("Lug", 'Mt Burns'), levels = creeks),
  710. Odor=c("2-heptanone"))
  711. fw_text <- data.frame(x = 0, y = 0.02,
  712. text=c("full-winged"),
  713. PulseDuration= factor(15, levels = c(15, 30, 150)),
  714. Group=factor("Mt Burns", levels = creeks),
  715. Odor=c("2-heptanone"))
  716. wr_text <- data.frame(x = 0, y = 0.05,
  717. text=c("wing-reduced"),
  718. PulseDuration = factor(15, levels = c(15, 30, 150)),
  719. Group=factor("Mt Burns", levels = creeks),
  720. Odor=c("2-heptanone"))
  721. pulseDur_text <- data.frame(x = 0.25, y = 0.1,
  722. text=c("15 ms", "30 ms", "150 ms"),
  723. PulseDuration = factor(c("15", "30", "150"), levels = c("15", "30", "150")),
  724. Group=factor("Black Jacks", levels = creeks),
  725. Odor=c("2-heptanone"))
  726. data_long$Group <- factor(data_long$Group, levels = c(creeks, 'Bee', 'PID'))
  727. col <- c(fw_l, wr_l)
  728. Fen <- ggplot(data_long %>% filter(Group %in% creeks), aes(x=time, y=Voltage)) +
  729. facet_grid(PulseDuration ~ Group, switch = "y") +
  730. geom_rect(mapping=aes(xmin=0, xmax=as.numeric(as.character(PulseDuration))/1000,
  731. ymin=-Inf, ymax=Inf),
  732. fill="grey90", alpha=1) +
  733. scale_color_manual(aesthetics = c("colour", "fill"), values = col) +
  734. geom_hline(mapping = aes(yintercept = 0), color="black", size=0.3, linetype="dotted") +
  735. geom_line(aes(colour = Winged)) +
  736. theme_bw() +
  737. labs(y = ' ') +
  738. theme(legend.position = "none",
  739. panel.grid.major = element_blank(),
  740. panel.grid.minor = element_blank(),
  741. axis.line = element_blank(),
  742. axis.ticks = element_blank(),
  743. axis.title.x = element_blank(),
  744. panel.border = element_blank(),
  745. plot.margin = unit(c(5.5, 5.5, 5.5, 5.5), "points"),
  746. strip.background = element_rect(colour="NA", fill="NA"),
  747. text = element_text(size=18),
  748. aspect.ratio = ar * 3,
  749. strip.text.y.left = element_blank(),
  750. strip.text.x = element_text(size = 20),
  751. axis.text=element_blank()) +
  752. geom_segment(data=data_segm1,
  753. aes(x=x, y=y, yend=yend, xend=xend)) +
  754. geom_text(data = label1, aes(x=x, y=y, label=text), size=geom.text.size, hjust=1.1) +
  755. geom_text(data = wr_text, aes(x=x, y=y, label=text), size=6, hjust=0, color=wr_l) +
  756. geom_text(data = fw_text, aes(x=x, y=y, label=text), size=6, hjust=0, color=fw_l) +
  757. geom_text(data = pulseDur_text, aes(x=x, y=y, label=text), size=5, hjust=0, color='black') +
  758. # geom_text(data = Diffs, aes(x=0.4, y=Max + 0.025, label=Star), size=geom.text.size, hjust=0.5) +
  759. coord_cartesian(expand = TRUE,
  760. clip = 'off')
  761. Fen
  762. col <- c('blue')
  763. data_segm1 <- data.frame(y=0, yend=1, x=Inf, xend=Inf,
  764. PulseDuration = factor(150, levels = c(15, 30, 150)),
  765. Group=factor("Bee"),
  766. Odor=c("2-heptanone"))
  767. label1 <- data.frame(x=Inf, y=0.5,
  768. text=c("1 mV"),
  769. PulseDuration= factor(150, levels = c(15, 30, 150)),
  770. Group=factor("Bee"),
  771. Odor=c("2-heptanone"))
  772. Bee <- ggplot(data_long %>% filter(Group %in% 'Bee'), aes(x=time, y=Voltage)) +
  773. facet_grid(PulseDuration ~ Group, switch = "y") +
  774. geom_rect(mapping=aes(xmin=0, xmax=as.numeric(as.character(PulseDuration))/1000,
  775. ymin=-Inf, ymax=Inf),
  776. fill="grey90", alpha=1) +
  777. scale_color_manual(aesthetics = c("colour", "fill"), values = col) +
  778. geom_hline(mapping = aes(yintercept = 0), color="black", size=0.3, linetype="dotted") +
  779. geom_line(aes(colour = Winged)) +
  780. theme_bw() +
  781. theme(legend.position = "none",
  782. panel.grid.major = element_blank(),
  783. panel.grid.minor = element_blank(),
  784. axis.line = element_blank(),
  785. axis.title = element_blank(),
  786. plot.margin = unit(c(5.5, 5.5, 5.5, 5.5), "points"),
  787. strip.background = element_rect(colour="NA", fill="NA"),
  788. panel.border = element_blank(),
  789. text = element_text(size=18),
  790. axis.ticks = element_blank(),
  791. aspect.ratio = ar * 3,
  792. strip.text.y = element_blank(),
  793. strip.text.x = element_text(size = 20),
  794. axis.text=element_blank()) +
  795. geom_segment(data=data_segm1,
  796. aes(x=x, y=y, yend=yend, xend=xend)) +
  797. geom_text(data = label1, aes(x=x, y=y, label=text), size=geom.text.size, hjust=1.1) +
  798. # geom_text(data = Diffs, aes(x=0.4, y=Max + 0.025, label=Star), size=geom.text.size, hjust=0.5) +
  799. coord_cartesian(expand = TRUE,
  800. clip = 'off')
  801. Bee
  802. data_segm1 <- data.frame(y=0, yend=3, x=Inf, xend=Inf,
  803. PulseDuration = factor(150, levels = c(15, 30, 150)),
  804. Group=factor("PID"),
  805. Odor=c("2-heptanone"))
  806. label1 <- data.frame(x=Inf, y=1.5,
  807. text=c("3 V"),
  808. PulseDuration= factor(150, levels = c(15, 30, 150)),
  809. Group=factor("PID"),
  810. Odor=c("2-heptanone"))
  811. PID <- ggplot(data_long %>% filter(Group %in% 'PID'), aes(x=time, y=Voltage)) +
  812. facet_grid(PulseDuration ~ Group, switch = "y") +
  813. geom_rect(mapping=aes(xmin=0, xmax=as.numeric(as.character(PulseDuration))/1000,
  814. ymin=-Inf, ymax=Inf),
  815. fill="grey90", alpha=1) +
  816. scale_color_manual(aesthetics = c("colour", "fill"), values = col) +
  817. geom_hline(mapping = aes(yintercept = 0), color="black", size=0.3, linetype="dotted") +
  818. geom_line(aes(colour = Winged)) +
  819. theme_bw() +
  820. theme(legend.position = "none",
  821. panel.grid.major = element_blank(),
  822. panel.grid.minor = element_blank(),
  823. axis.line = element_blank(),
  824. axis.title = element_blank(),
  825. plot.margin = unit(c(5.5, 5.5, 5.5, 5.5), "points"),
  826. strip.background = element_rect(colour="NA", fill="NA"),
  827. panel.border = element_blank(),
  828. text = element_text(size=18),
  829. axis.ticks = element_blank(),
  830. aspect.ratio = ar * 3,
  831. strip.text.y = element_blank(),
  832. strip.text.x = element_text(size = 20),
  833. axis.text=element_blank()) +
  834. geom_segment(data=data_segm1,
  835. aes(x=x, y=y, yend=yend, xend=xend)) +
  836. geom_text(data = label1, aes(x=x, y=y, label=text), size=geom.text.size, hjust=1.1) +
  837. # geom_text(data = Diffs, aes(x=0.4, y=Max + 0.025, label=Star), size=geom.text.size, hjust=0.5) +
  838. coord_cartesian(expand = TRUE,
  839. clip = 'off')
  840. PID
  841. FigS1A <- egg::ggarrange(Fen, Bee, PID,
  842. heights = 5, nrow = 1, ncol=3, widths = c(5, 1, 1), debug = FALSE)
  843. ########################
  844. #### Function to plot parameters for Response Dynamic:
  845. plot_bayes_time <- function(data, creeks, yvalue, ylab) {
  846. data <- data2
  847. data <- data %>%
  848. filter(PulseDuration==300, Group %in% creeks, Odor %in% odors)
  849. df <- as.data.frame(matrix(NA, ncol=7, nrow = 0))
  850. df_diff <- as.data.frame(matrix(NA, ncol=8, nrow = 0))
  851. ##########################################################################
  852. for (cc in seq_along(creeks)) {
  853. subdata <- data %>%
  854. filter(Group == creeks[cc])
  855. subdata$PulseDuration <- as.factor(subdata$PulseDuration)
  856. subdata <- droplevels(subdata)
  857. m1 <- lm(log2(get(yvalue)) ~ Winged * Odor, data = subdata)
  858. par(mfrow=c(2,2))
  859. plot(m1)
  860. summary(m1)
  861. subdata$Odor
  862. newdat <- expand.grid(Winged = factor(c("full-winged","wing-reduced")),
  863. PulseDuration = factor(levels(subdata$PulseDuration), levels = levels(subdata$PulseDuration)),
  864. Odor = factor(levels(subdata$Odor), levels = odors))
  865. bsim <- sim(m1, n.sim=nsim)
  866. fitmat <- matrix(ncol=nsim, nrow=nrow(newdat))
  867. Xmat <- model.matrix( ~ Winged * Odor, data=newdat)
  868. for(i in 1:nsim) fitmat[,i] <- Xmat %*% bsim@coef[i,] #fitted values
  869. tmp <- t(apply(fitmat, 1, quantile, prob=c(0.025, 0.5, 0.975)))
  870. tst <- cbind(newdat, tmp, 'Group' = creeks[cc])
  871. df <- rbind(df, tst)
  872. for (oo in odors) {
  873. dat <- fitmat[which(newdat$PulseDuration == 300 & newdat$Odor == oo), ]
  874. star2 <- sum(dat[1, ] > dat[2, ]) / nsim
  875. df_diff <- rbind(df_diff,
  876. data.frame('Group' = creeks[cc],
  877. 'Odor' = oo,
  878. 'Diff' = star2))
  879. }
  880. }
  881. df_diff
  882. df_diff$Star1 <- df_diff$Diff >= 0.95 | df_diff$Diff <= 0.05
  883. df_diff$Star2 <- df_diff$Diff >= 0.99 | df_diff$Diff <= 0.01
  884. colnames(df)[4:6] <- c('lower', 'fitted', 'upper')
  885. df$lower <- 2^(df$lower)
  886. df$fitted <- 2^(df$fitted)
  887. df$upper <- 2^(df$upper)
  888. subdf <- df %>%
  889. group_by(Group, Odor) %>%
  890. summarise(max=max(fitted))
  891. sub_data2 <- data %>%
  892. filter(Group!="Fenestrata-Bee",
  893. Group!="Bee",
  894. Odor!="Blank",
  895. Odor!="Propionic acid",
  896. Odor!="Stonefly")
  897. sub_data2 <- droplevels(sub_data2)
  898. df <- droplevels(df)
  899. df_diff <- droplevels(df_diff)
  900. sub_data2$PulseDuration <- factor(sub_data2$PulseDuration,
  901. levels = c(300))
  902. df$PulseDuration <- factor(df$PulseDuration,
  903. levels = c(300))
  904. df$NewGroup <- as.factor(paste(df$Winged, df$Group))
  905. df_diff$NewGroup <- as.factor(paste(df_diff$Winged, df_diff$Group))
  906. col <- c(fw_l, wr_l)
  907. col <- c(col[1], "black", col[2])
  908. df_diff$Star[df_diff$Star1 == TRUE] <- "*"
  909. df_diff$Star[df_diff$Star1 == FALSE] <- " "
  910. df_diff$Star[df_diff$Star2 == TRUE] <- "**"
  911. stars <- df_diff$Star
  912. df_diff$NewGroup <- "star"
  913. print(df_diff)
  914. df_diff$Winged <- "star"
  915. df$Odor <- factor(df$Odor, levels = odors)
  916. df_diff$Odor <- factor(df_diff$Odor, levels = odors)
  917. sub_data2$Odor <- factor(sub_data2$Odor, levels = odors)
  918. MAX <- sub_data2 %>%
  919. group_by(Odor, Group) %>%
  920. summarise(max = max(get(yvalue), na.rm = TRUE))
  921. df_diff <- merge(df_diff, MAX, by=c('Odor', 'Group'))
  922. p <- ggplot(df, aes(x=Group, y=fitted, color=Winged)) +
  923. geom_hline(aes(yintercept=0), color="black", size=0.3, linetype="dotted") +
  924. scale_color_manual(aesthetics = c("colour", "fill"), values = col) +
  925. scale_y_continuous(breaks = pretty_breaks(n=2), expand = expansion(mult = c(0.05, .1))) +
  926. facet_grid(Odor ~ Group, scales = "free") +
  927. geom_beeswarm(sub_data2, dodge.width = 0.8, mapping=aes(x=Group, y=get(yvalue)), cex=1, shape=21) +
  928. geom_point(aes(group=NewGroup), position = position_dodge(0.8), shape="_", cex=4, color="black") +
  929. geom_errorbar(aes(ymin=lower, ymax=upper, group=Winged),
  930. color="black", width=0, position=position_dodge(0.8), size=0.5) +
  931. theme_bw() +
  932. ylab(ylab) +
  933. xlab(" ") +
  934. scale_x_discrete(labels=c("", "")) +
  935. geom_text(data=df_diff, aes(x=Group, y = max * 0.9, label=Star), size = 7) +
  936. theme(legend.position = "none",
  937. panel.grid.major = element_blank(),
  938. panel.grid.minor = element_blank(),
  939. axis.line.x = element_blank(),
  940. axis.line.y = element_line(colour = "black"),
  941. axis.title.x=element_blank(),
  942. axis.ticks.x=element_blank(),
  943. strip.text.x = element_text(size = 16),
  944. strip.background = element_rect(colour="NA", fill="NA"),
  945. strip.text.y = element_text(size = 16, angle = 0, hjust = 0),
  946. panel.border = element_blank(),
  947. text = element_text(size=18),
  948. axis.text=element_text(colour="black"))
  949. print(p)
  950. return(p)
  951. }
  952. ####### Figure 2 ##########################
  953. Fig2A <- plot_bayes_time(data = data2, yvalue = "Timeto10", ylab = "Response onset (ms)", creeks = creeks)
  954. Fig2B <- plot_bayes_time(data2, "TimeBackTo10", "Response offset (ms)", creeks = creeks)
  955. ################## 10 Hz Stimulations ###########
  956. on_times <- seq(0, 2.9, by = 0.1)
  957. off_times <- seq(0.05, 3, by=0.1)
  958. times_tst_on <- expand.grid(levels(data2$Odor), "on"=on_times)
  959. times_tst_off <- expand.grid(levels(data2$Odor), "off"=off_times)
  960. Times <- data.frame("Odor"=times_tst_on$Var1, "on"=times_tst_on$on, "off"=times_tst_off$off)
  961. Times <- Times[!(Times$Odor=="Blank"), ]
  962. plot_freq <- function(data, group, times) {
  963. data <- data %>%
  964. filter(PulseDuration == 50,
  965. Odor == "2-heptanone")
  966. data <- droplevels(data)
  967. d_mean <- data %>%
  968. filter(Group %in% group) %>%
  969. group_by(Group, Winged, Odor, PulseDuration) %>%
  970. summarise_at(.funs = median, .vars=paste0("t", 1:5000))
  971. # calculate the standard error
  972. d_se <- data %>%
  973. filter(Group %in% group) %>%
  974. group_by(Group, Winged, Odor, PulseDuration) %>%
  975. summarise_at(.funs = se, .vars=paste0("t", 1:5000))
  976. # calculate sample size (n)
  977. d_n <- data %>%
  978. filter(Group %in% group) %>%
  979. group_by(Group, Winged, Odor, PulseDuration) %>%
  980. summarise(N=n()) %>%
  981. group_by(Group, Winged) %>%
  982. summarise(N=unique(N))
  983. d_n <- unite(d_n, col = "Winged", sep = " (n = ")
  984. d_n$t <- ")"
  985. d_n <- unite(d_n, col = "Winged", sep = "")
  986. d_all <- d_mean
  987. data_se <- gather(d_se, time, se, t1:t5000, factor_key=TRUE)
  988. d_all$Odor <- factor(d_all$Odor)
  989. times <- times[times$Odor == "2-heptanone", ]
  990. data_long <- gather(d_all, time, Voltage, t1:t5000, factor_key=TRUE)
  991. data_long$time <- (as.numeric(gsub("t", "", data_long$time)) - 200)/1000
  992. data_long$SE <- data_se$se
  993. data_long$PulseDuration <- factor(data_long$PulseDuration, levels = c("50"), labels = c("10 Hz"))
  994. col <- c("grey", "#00DC00")
  995. data_segm1 <- data.frame(y=c(0, -0.02), yend=c(0.05, -0.02), x=c(Inf, 1), xend=c(Inf, 2),
  996. PulseDuration = factor(150, levels = c(15, 30, 150)),
  997. Group=factor(c("Six Mile", 'Mt Burns')),
  998. Odor=c("2-heptanone"))
  999. label1 <- data.frame(x=c(Inf, 2), y=c(0.035, -0.035),
  1000. text=c("0.05 mV", '1 s'),
  1001. PulseDuration= factor(150, levels = c(15, 30, 150)),
  1002. Group=factor(c("Six Mile", 'Mt Burns')),
  1003. Odor=c("2-heptanone"))
  1004. ## For Lug, we stimultaed with a different stimulus protocol were the stimulation
  1005. ## with several pulses in a specific frequency was not 10 Hz and the total length
  1006. ## o f stimulation was less than 3 seconds. We exclude these data here.
  1007. dat <- data_long %>% filter(Group == creeks, Group != 'Lug')
  1008. dat$Group <- factor(dat$Group, levels = c(creeks))
  1009. W <- ggplot(dat, aes(x=time, y=Voltage)) +
  1010. geom_rect(data=times, inherit.aes=FALSE, fill = "grey95",
  1011. aes(xmin=on, xmax=off, ymin=-Inf, ymax=Inf)) +
  1012. # geom_ribbon(aes(ymin=Voltage + SE, ymax=Voltage - SE, fill=Winged), color=NA, alpha=0.3) +
  1013. geom_hline(mapping = aes(yintercept = 0), color="black", size=0.3, linetype="dotted") +
  1014. geom_line(aes(colour = Winged)) +
  1015. scale_color_manual(aesthetics = c("colour", "fill"), values = col) +
  1016. facet_grid(. ~ Group, scales = "free_y", drop = FALSE) +
  1017. scale_y_continuous(breaks = pretty_breaks(n = 3)) +
  1018. theme_bw() +
  1019. labs(y = " ") +
  1020. guides(fill = 'none') +
  1021. geom_segment(data=data_segm1,
  1022. aes(x=x, y=y, yend=yend, xend=xend)) +
  1023. geom_text(data = label1, aes(x=x, y=y, label=text), size=geom.text.size, hjust=1.1) +
  1024. coord_cartesian(xlim =c(0, 3.5)) +
  1025. theme(panel.grid.major = element_blank(),
  1026. panel.grid.minor = element_blank(),
  1027. legend.position = "none",
  1028. strip.background = element_rect(colour="NA", fill="NA"),
  1029. strip.text.y = element_blank(),
  1030. legend.title = element_blank(),
  1031. axis.line = element_blank(),
  1032. axis.ticks = element_blank(),
  1033. axis.title.x = element_blank(),
  1034. axis.title.y = element_text(size = 35),
  1035. panel.border = element_blank(),
  1036. axis.text=element_blank(),
  1037. strip.text = element_blank(),
  1038. text = element_text(size=18))
  1039. W
  1040. col <- c("blue")
  1041. data_segm1 <- data.frame(y=0, yend=1, x=Inf, xend=Inf,
  1042. PulseDuration = factor(150, levels = c(15, 30, 150)),
  1043. Group=factor("Bee"),
  1044. Odor=c("2-heptanone"))
  1045. label1 <- data.frame(x=Inf, y=0.5,
  1046. text=c("1 mV"),
  1047. PulseDuration= factor(150, levels = c(15, 30, 150)),
  1048. Group=factor("Bee"),
  1049. Odor=c("2-heptanone"))
  1050. B <- ggplot(data_long[data_long$Group %in% 'Bee', ], aes(x=time, y=Voltage)) +
  1051. geom_rect(data=times, inherit.aes=FALSE, fill = "grey95",
  1052. aes(xmin=on, xmax=off, ymin=-Inf,ymax=Inf)) +
  1053. # geom_ribbon(aes(ymin=Voltage + SE, ymax=Voltage - SE, fill=Winged), color=NA, alpha=0.3) +
  1054. geom_hline(mapping = aes(yintercept = 0), color="black", size=0.3, linetype="dotted") +
  1055. geom_line(aes(colour = Winged)) +
  1056. scale_color_manual(aesthetics = c("colour", "fill"), values = col) +
  1057. facet_grid(Odor ~ Group, scales = "free_y") +
  1058. scale_y_continuous(breaks = pretty_breaks(n = 3)) +
  1059. theme_bw() +
  1060. coord_cartesian(xlim =c(0, 3.5)) +
  1061. # guides(fill = 'none') +
  1062. geom_segment(data=data_segm1,
  1063. aes(x=x, y=y, yend=yend, xend=xend)) +
  1064. geom_text(data = label1, aes(x=x, y=y, label=text), size=geom.text.size, hjust=1.1) +
  1065. theme(panel.grid.major = element_blank(),
  1066. panel.grid.minor = element_blank(),
  1067. legend.position = "none",
  1068. strip.background = element_rect(colour="NA", fill="NA"),
  1069. panel.border = element_blank(),
  1070. legend.title = element_blank(),
  1071. axis.line = element_blank(),
  1072. strip.text = element_blank(),
  1073. axis.text=element_blank(),
  1074. axis.ticks = element_blank(),
  1075. axis.title = element_blank(),
  1076. text = element_blank())
  1077. B
  1078. data_segm1 <- data.frame(y=0, yend=1, x=3, xend=3,
  1079. PulseDuration = factor(150, levels = c(15, 30, 150)),
  1080. Group=factor("PID"),
  1081. Odor=c("2-heptanone"))
  1082. label1 <- data.frame(x=3, y=0.5,
  1083. text=c("1 V"),
  1084. PulseDuration= factor(150, levels = c(15, 30, 150)),
  1085. Group=factor("PID"),
  1086. Odor=c("2-heptanone"))
  1087. P <- ggplot(data_long[data_long$Group %in% 'PID', ], aes(x=time, y=Voltage)) +
  1088. geom_rect(data = times, inherit.aes = FALSE, fill = "grey95",
  1089. aes(xmin = on, xmax=off, ymin = -Inf, ymax = Inf)) +
  1090. # geom_ribbon(aes(ymin=Voltage + SE, ymax=Voltage - SE, fill=Winged), color=NA, alpha=0.3) +
  1091. geom_hline(mapping = aes(yintercept = 0), color="black", size=0.3, linetype="dotted") +
  1092. geom_line(aes(colour = Winged)) +
  1093. scale_color_manual(aesthetics = c("colour", "fill"), values = col) +
  1094. facet_grid(Odor ~ Group, scales = "free_y") +
  1095. scale_y_continuous(breaks = pretty_breaks(n = 3)) +
  1096. theme_bw() +
  1097. coord_cartesian(xlim =c(0, 3.5)) +
  1098. geom_segment(data=data_segm1,
  1099. aes(x=x, y=y, yend=yend, xend=xend)) +
  1100. geom_text(data = label1, aes(x=x, y=y, label=text), size=geom.text.size, hjust=1.1) +
  1101. # guides(fill = 'none') +
  1102. theme(panel.grid.major = element_blank(),
  1103. panel.grid.minor = element_blank(),
  1104. legend.position = "none",
  1105. strip.background = element_rect(colour="NA", fill="NA"),
  1106. panel.border = element_blank(),
  1107. legend.title = element_blank(),
  1108. axis.ticks = element_blank(),
  1109. axis.text=element_blank(),
  1110. axis.line = element_blank(),
  1111. axis.title = element_blank(),
  1112. strip.text = element_blank(),
  1113. text = element_blank())
  1114. P
  1115. list(W = W, B = B, P = P)
  1116. }
  1117. FigS1C_new <- plot_freq(data2, c(creeks, 'Bee', 'PID'), Times)
  1118. ## Power spectrum density analysis ####
  1119. ## whole frequency band mean over groups of individuals ##
  1120. ## Freq = 10 for individual ID ##
  1121. spec <- data.frame(x=as.numeric(NULL), y=as.numeric(NULL), sd=as.numeric(NULL), se=as.numeric(NULL),
  1122. Odor=as.character(NULL), Winged=as.character(NULL),
  1123. Group=as.character(NULL), TimeWindow=as.character(NULL))
  1124. spec_ind <- data.frame(y=as.numeric(NULL),
  1125. yMean=as.numeric(NULL),
  1126. xMean=as.numeric(NULL),
  1127. zMean=as.numeric(NULL),
  1128. yMax=as.numeric(NULL),
  1129. xMax=as.numeric(NULL),
  1130. zMax=as.numeric(NULL),
  1131. id=as.numeric(NULL),
  1132. Odor=as.character(NULL), Winged=as.character(NULL),
  1133. Group=as.character(NULL), TimeWindow=as.character(NULL))
  1134. winged <- as.vector(t(unique(data2[, "Winged"])))
  1135. for(k in 1:length(winged)){
  1136. group <- as.vector(t(unique(data2[data2$Winged==winged[k], "Group"])))
  1137. for (l in 1:length(group)) {
  1138. odors <- as.vector(t(unique(data2[data2$Winged==winged[k] & data2$Group==group[l], "Odor"])))
  1139. for (i in 1:length(odors)){
  1140. Hept <- data2 %>%
  1141. filter(Odor==odors[i], Winged==winged[k], Group==group[l], (AntennaState=="alive" | is.na(AntennaState)))
  1142. ### full length of 3 seconds ####
  1143. spect <- apply(Hept[,paste0("t", 601:3600)],
  1144. MARGIN = 1,
  1145. FUN=function(x) spec.mtm(ts(x, frequency = 1000), taper = "sine", plot=F))
  1146. spec <- rbind(spec, data.frame(x=spect[[1]]$freq[1:329],
  1147. y=rowMeans(sapply(spect, '[[', 4))[1:329],
  1148. sd=apply((sapply(spect, '[[', 4)),1, sd)[1:329],
  1149. se=apply((sapply(spect, '[[', 4)),1, se)[1:329],
  1150. Odor=odors[i],
  1151. Winged=winged[k],
  1152. Group=group[l],
  1153. TimeWindow="T0-3"))
  1154. # select frequencies between 9.5 and 10.5 and calculate the mean values
  1155. sel_row_10 <- which(spect[[1]]$freq > 9 & spect[[1]]$freq < 11)
  1156. sel_row_pre10 <- which(spect[[1]]$freq > 8 & spect[[1]]$freq < 9)
  1157. sel_row_post10 <- which(spect[[1]]$freq > 11 & spect[[1]]$freq < 12)
  1158. spec_ind <- rbind(spec_ind, data.frame(y=colSums(sapply(spect, '[[', 4)[sel_row_10,]),
  1159. yMean=colMeans(sapply(spect, '[[', 4)[sel_row_10,]),
  1160. xMean=colMeans(sapply(spect, '[[', 4)[sel_row_pre10,]),
  1161. zMean=colMeans(sapply(spect, '[[', 4)[sel_row_post10,]),
  1162. yMax=apply(sapply(spect, '[[', 4)[sel_row_10,], 2, max),
  1163. xMax=apply(sapply(spect, '[[', 4)[sel_row_pre10,], 2, min),
  1164. zMax=apply(sapply(spect, '[[', 4)[sel_row_post10,], 2, min),
  1165. id=as.character(Hept$ID_new),
  1166. Odor=odors[i],
  1167. Winged=winged[k],
  1168. Group=group[l],
  1169. TimeWindow="T0-3"))
  1170. }
  1171. }
  1172. }
  1173. spec_sel <- spec %>%
  1174. filter(Odor!="Blank", Odor!="Stonefly", Odor!="Propionic acid", TimeWindow=="T0-3")
  1175. spec_sel <- droplevels(spec_sel)
  1176. spec_sel$Odor <- factor(spec_sel$Odor, levels = c("2-heptanone",
  1177. "1-octanol",
  1178. "2-butanone"))
  1179. col <- c("#FF00FF", "#00DC00")
  1180. plot_freq <- function(data) {
  1181. data <- data %>%
  1182. filter(Odor=="2-heptanone")
  1183. col <- c(fw_l, wr_l, "black")
  1184. data$TimeWindow <- factor(data$TimeWindow, levels = levels(data$TimeWindow),
  1185. labels = "")
  1186. odors <- data.frame("Odor"=levels(data$Odor))
  1187. ## For Lug, we stimultaed with a different stimulus protocol were the stimulation
  1188. ## with several pulses in a specific frequency was not 10 Hz and the total length
  1189. ## o f stimulation was less than 3 seconds. We exclude these data here.
  1190. dat <- data %>% filter(Group %in% creeks & Group != 'Lug')
  1191. dat$Group <- factor(dat$Group, levels = c(creeks))
  1192. W <- ggplot(dat,
  1193. aes(x=x, y=log10(y))) +
  1194. geom_rect(mapping=aes(xmin=9.5, xmax=10.5,
  1195. ymin=-Inf, ymax=Inf),
  1196. fill="grey90", alpha=1) +
  1197. geom_ribbon(aes(ymin=log10(y + se), ymax=log10(y - se), fill=Winged),
  1198. color=NA, alpha=0.3) +
  1199. geom_line(aes(colour = Winged)) +
  1200. facet_grid(. ~ Group, drop = FALSE) +
  1201. scale_color_manual(aesthetics = c("colour", "fill"), values = col) +
  1202. theme_bw() +
  1203. scale_y_continuous(breaks = pretty_breaks(n=3)) +
  1204. theme(panel.grid.major = element_blank(),
  1205. panel.grid.minor = element_blank(),
  1206. legend.position = "none",
  1207. text = element_text(size=18),
  1208. axis.title = element_blank(),
  1209. axis.line = element_line(colour = "black"),
  1210. strip.background = element_rect(colour="NA", fill="NA"),
  1211. strip.text = element_blank(),
  1212. panel.border = element_blank(),
  1213. axis.text=element_text(colour="black"))
  1214. W
  1215. B <- ggplot(data %>% filter(Group %in% c("Bee")),
  1216. aes(x=x, y=log10(y))) +
  1217. geom_rect(mapping=aes(xmin=9.5, xmax=10.5,
  1218. ymin=-Inf, ymax=Inf),
  1219. fill="grey90", alpha=1) +
  1220. geom_ribbon(aes(ymin=log10(y + se), ymax=log10(y - se), fill=Winged),
  1221. color=NA, alpha=0.3) +
  1222. geom_line(aes(colour = Winged)) +
  1223. facet_grid(. ~ Group) +
  1224. scale_color_manual(aesthetics = c("colour", "fill"), values = "blue") +
  1225. theme_bw() +
  1226. scale_y_continuous(breaks = pretty_breaks(n=3)) +
  1227. theme(panel.grid.major = element_blank(),
  1228. panel.grid.minor = element_blank(),
  1229. legend.position = "none",
  1230. text = element_text(size=18),
  1231. axis.title = element_blank(),
  1232. axis.line = element_line(colour = "black"),
  1233. strip.background = element_rect(colour="NA", fill="NA"),
  1234. strip.text = element_blank(),
  1235. panel.border = element_blank(),
  1236. axis.text=element_text(colour="black"))
  1237. B
  1238. P <- ggplot(data %>% filter(Group %in% c("PID")),
  1239. aes(x=x, y=log10(y))) +
  1240. geom_rect(mapping=aes(xmin=9.5, xmax=10.5,
  1241. ymin=-Inf, ymax=Inf),
  1242. fill="grey90", alpha=1) +
  1243. geom_ribbon(aes(ymin=log10(y + se), ymax=log10(y - se), fill=Winged),
  1244. color=NA, alpha=0.3) +
  1245. geom_line(aes(colour = Winged)) +
  1246. facet_grid(. ~ Group) +
  1247. scale_color_manual(aesthetics = c("colour", "fill"), values = "blue") +
  1248. theme_bw() +
  1249. scale_y_continuous(breaks = pretty_breaks(n=3)) +
  1250. theme(panel.grid.major = element_blank(),
  1251. panel.grid.minor = element_blank(),
  1252. legend.position = "none",
  1253. axis.title = element_blank(),
  1254. text = element_text(size=18),
  1255. axis.line = element_line(colour = "black"),
  1256. strip.background = element_rect(colour="NA", fill="NA"),
  1257. strip.text = element_blank(),
  1258. panel.border = element_blank(),
  1259. axis.text=element_text(colour="black"))
  1260. P
  1261. list1 <- list("traceW"=W,
  1262. "traceB"=B,
  1263. "traceP"=P)
  1264. return(list1)
  1265. }
  1266. p5 <- plot_freq(data = spec_sel); p5
  1267. #create common x and y labels
  1268. FigS1D <- egg::ggarrange(p5$traceW, p5$traceB, p5$traceP,
  1269. bottom = textGrob("Frequency (Hz)", gp = gpar(fontsize=16), vjust = 0.5),
  1270. left = textGrob(expression(paste("Power (", mV^2/Hz, ") [log10]")),
  1271. gp = gpar(fontsize=18), vjust = 0.5, rot = 90),
  1272. ncol = 3, nrow=1,
  1273. label.args = list(gp=gpar(fontface="bold", fontsize=18), hjust=0, vjust=1),
  1274. widths = c(5,1,1),
  1275. debug = FALSE)
  1276. FigS1D
  1277. FigS1C <- egg::ggarrange(FigS1C_new$W, FigS1C_new$B, FigS1C_new$P,
  1278. ncol = 3, nrow=1, heights = 1,
  1279. widths = c(5, 1, 1),
  1280. debug = FALSE)
  1281. FigS1C
  1282. Fig1AB <- cowplot::plot_grid(Fig1A, Fig1B,
  1283. align = "hv", axis = "trbl",
  1284. labels = c("A", "B"),
  1285. rel_widths = c(1.2, 1.5),
  1286. nrow = 1, label_size = 18)
  1287. ### Fig. 1
  1288. cowplot::plot_grid(Fig1AB, Fig1C, nrow = 2, rel_heights = c(1, 1.3),
  1289. labels = c("", "C"), label_size = 18)
  1290. ggsave("Figure1.pdf", path = fig_path, width = 12, height = 10)
  1291. ### Fig. 2
  1292. cowplot::plot_grid(Fig2A, Fig2B, nrow = 2,
  1293. labels = LETTERS[1:2], label_size = 18)
  1294. ggsave("Figure2.pdf", path = fig_path, width = 9, height = 12)
  1295. ### Fig. S1
  1296. cowplot::plot_grid(FigS1A, FigS1B, NULL, FigS1C, FigS1D, nrow = 5, rel_heights = c(1.2, 1, 0.05, 0.3, 0.8),
  1297. labels = c('A', 'B', '', 'C', 'D'), label_size = 18)
  1298. ggsave("FigureS1.pdf", path = fig_path, width = 14, height = 14)