This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more details on using R Markdown see http://rmarkdown.rstudio.com.
When you click the Knit button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:
library(readxl)
library(car)
library(ggplot2)
library(ggpubr)
library(cowplot)
library(magick)
PairMatchingR_F77 <- read_excel("C:/Users/olivi/OneDrive/Desktop/manuscripts/In process/Pair Matching MS/PairMatchingR/PairMatchingFullSet_F77_R.xlsx")
PairMatchingR_F77$Call_Peak_Diff <- as.Date.numeric(PairMatchingR_F77$TotalPulseDiff_Corr)
cropped_gaussian_zero <- function(mean = 5, sd = 1, amp = 1, n = 200, crop_mult = 2.5) {
x_min <- mean - crop_mult * sd
x_max <- mean + crop_mult * sd
x <- seq(x_min, x_max, length.out = n)
y <- amp * dnorm(x, mean = mean, sd = sd)
y <- y - min(y) # y = 0 at ends
data.frame(x = x, y = y)
}
red_curve <- function(x_range = c(2, 8), func = function(x) 3*(1 - exp(-x/2)), n = 400) {
x <- seq(x_range[1], x_range[2], length.out = n)
y_raw <- func(x)
y <- y_raw - y_raw[1] # start at 0
data.frame(x = x, y = y)
}
rescale_to_max <- function(df, target_max) {
df$y <- df$y / max(df$y) * target_max
df
}
add_peak_annotation_gap <- function(p, df_blue, df_red, gap = 0.2, text_offset = 0.1) {
x_blue <- df_blue$x[which.max(df_blue$y)]
x_red <- df_red$x[which.max(df_red$y)]
y_blue <- max(df_blue$y)
y_red <- max(df_red$y)
p +
# Arrows: start above peak (y + gap), point just above peak (y + tiny offset)
annotate("segment", x = x_blue, xend = x_blue,
y = y_blue + gap, yend = y_blue + 0.04,
colour = "navy", arrow = arrow(length = unit(0.1, "inches")), size = 1.2) +
annotate("segment", x = x_red, xend = x_red,
y = y_red + gap, yend = y_red + 0.04,
colour = "olivedrab4", arrow = arrow(length = unit(0.1, "inches")), size = 1.2)
}
x_full <- c(2, 8)
closed_A <- cropped_gaussian_zero(mean = 5, sd = 1, amp = 8, crop_mult = 1)
open_A <- red_curve(x_full, function(x) 3 * (1 - exp(-x / 2)))
open_A <- rescale_to_max(open_A, max(closed_A$y))
closed_B <- cropped_gaussian_zero(mean = 5, sd = 2, amp = 8, crop_mult = 1) # wider
open_B <- red_curve(x_full, function(x) 3 * (1 - exp(-x / 2)))
open_B <- rescale_to_max(open_B, max(closed_B$y))
peak_A <- max(max(closed_A$y), max(open_A$y))
peak_B <- max(max(closed_B$y), max(open_B$y))
shift_B <- peak_A - peak_B
closed_B$y <- closed_B$y + shift_B
open_B$y <- open_B$y + shift_B
lower_amount <- 3
closed_A$y <- closed_A$y - lower_amount
open_A$y <- open_A$y - lower_amount
closed_B$y <- closed_B$y - lower_amount
open_B$y <- open_B$y - lower_amount
global_max <- max(max(closed_A$y), max(open_A$y), max(closed_B$y), max(open_B$y))
global_min <- min(min(closed_A$y), min(open_A$y), min(closed_B$y), min(open_B$y))
y_limits <- c(global_min, global_max + 0.3)
highselect <- ggplot() +
geom_line(data = open_A, aes(x, y), color = "olivedrab4", linewidth = 1.5, lineend = "round") +
geom_line(data = closed_A, aes(x, y), color = "navy", linewidth = 1.5, lineend = "round") +
labs(x = "male trait", y = "female response") +
coord_cartesian(ylim = y_limits) +
theme_classic(base_size = 18) +
theme(
panel.grid = element_blank(),
axis.title.y = element_text(size = 18, vjust = -0.3),
axis.text = element_blank(),
axis.ticks = element_blank(),
axis.title = element_text(size=18),
panel.border = element_blank(),
axis.line = element_line(color = "black", linewidth = 0.9),
plot.title = element_text(face = "bold"),
plot.margin = margin(10, 10, 10, 10)
) +
guides(x = guide_axis(cap = "both"), y = guide_axis(cap = "both"))
highselect <- add_peak_annotation_gap(highselect, closed_A, open_A)
lowselect <- ggplot() +
geom_line(data = open_B, aes(x, y), color = "olivedrab4", linewidth = 1.5, lineend = "round") +
geom_line(data = closed_B, aes(x, y), color = "navy", linewidth = 1.5, lineend = "round") +
labs(x = "male trait", y = "female response") +
coord_cartesian(ylim = y_limits) +
theme_classic(base_size = 18) +
theme(
panel.grid = element_blank(),
axis.title.y = element_text(size = 18, vjust = -0.3),
axis.text = element_blank(),
axis.ticks = element_blank(),
axis.title = element_text(size=18),
panel.border = element_blank(),
axis.line = element_line(color = "black", linewidth = 0.9),
plot.title = element_text(face = "bold"),
plot.margin = margin(10, 10, 10, 10)
) +
guides(x = guide_axis(cap = "both"), y = guide_axis(cap = "both"))
lowselect <- add_peak_annotation_gap(lowselect, closed_B, open_B)
fake_data <- data.frame(Variable_X = c(4, 22), Variable_Y = c(4, 22))
regression <- ggplot(fake_data, aes(x = Variable_X, y = Variable_Y)) +
geom_smooth(method = lm, se = FALSE, color = "darkslategrey", linewidth = 1.5, fill = "grey80", fullrange = FALSE) +
labs(
x = "effort",
y = "likelihood of obtaining\nthe preferred mate"
) +
# Truncate both lines dynamically using the theme's break markers
guides(x = guide_axis(cap = "both"), y = guide_axis(cap = "both")) +
# >>> FIX: Start the axis line at 3 (creating a gap at the corner) but run it to 27 <<<
scale_x_continuous(breaks = c(3, 25)) +
scale_y_continuous(breaks = c(3, 25)) +
theme_classic(base_size = 18) +
theme(
axis.text = element_blank(),
axis.title.y = element_text(size = 18, vjust = -0.3),
axis.ticks = element_blank(),
axis.line = element_line(color = "black", linewidth = 0.9)
) +
# Using expand = FALSE keeps the upper and right boundaries clean and flush
coord_equal(xlim = c(0, 27), ylim = c(0, 27), expand = FALSE)
regression <- regression +
scale_x_continuous(breaks = c(1.5, 25)) +
scale_y_continuous(breaks = c(1.5, 25))
amplexus <- ggdraw() + draw_image("C:/Users/olivi/OneDrive/Desktop/manuscripts/In process/Pair Matching MS/PairMatchingR/amplexus.jpg",
scale = 1.3, clip = "off")
selectivity <- ggplot(PairMatchingR_F77, aes(x=Inverse_SelectivityNoFlat, y=TotalPulseDiff_Corr)) +
geom_point(shape=20, size=4, color="darkorange3",show.legend = FALSE, alpha = 0.5) +
theme_classic(base_size = 18) +
geom_smooth(method=lm, fullrange=FALSE, se=TRUE, level=0.95,color="darkorange3",
linewidth=1.5, fill="darkorange3")+
xlab("selectivity") + scale_x_continuous(breaks=seq(-2,5,1),limits=c(-2,5)) +
ylab("signal-preference match") + scale_y_continuous(breaks=seq(-25,15,5), limits = c(-25,15)) +
geom_hline(yintercept = 0, linetype = "dashed", color = "black", linewidth=1) +
theme(
axis.text = element_text(size = 20),
axis.title.y = element_text(size = 18, vjust = -0.1)
) +
guides(x = guide_axis(cap = "both"), y = guide_axis(cap = "both"))
choosy <- ggplot(PairMatchingR_F77, aes(x=Choosiness, y=TotalPulseDiff_Corr)) +
geom_point(shape=20, size=4, color="dodgerblue4", show.legend = FALSE, alpha = 0.5) +
theme_classic(base_size = 18) +
geom_smooth(method=lm, fullrange=FALSE, se=TRUE, level=0.95, color="dodgerblue4",
linewidth=1.5, fill="dodgerblue4") +
xlab("choosiness (dB)") + scale_x_continuous(breaks=seq(0,27,3)) +
ylab("signal-preference match") + scale_y_continuous(breaks=seq(-25,15,5), limits = c(-25,15)) +
geom_hline(yintercept = 0, linetype = "dashed", color = "black", linewidth=1) +
theme(
axis.text = element_text(size = 20),
axis.title.y = element_text(size = 18, vjust = -0.15)
) +
guides(x = guide_axis(cap = "both"), y = guide_axis(cap = "both"))
combofig <- ggarrange(
highselect, lowselect, # Row 1 (The two curve panels)
regression, amplexus, # Row 2 (The regression line and frog photo)
selectivity, choosy, # Row 3 (The bottom scatter plots)
labels = c("A", "", "B", "C", "D", ""), # Labels the left column panels cleanly
ncol = 3,
nrow = 2,
heights = c(1, 1.2),
align = "v",
font.label = list(size = 25, color = "black", face = "bold"))
ggsave(filename = "combofig.tiff", dpi = 400, plot = combofig,
bg = "white",
device = "tiff",
width=35,
height=20,
units = "cm")