Here is a way to use ggbreak to truncate your plot. I agree with @VinceGreg, using a line geom in conjunction with an axis gap is not recommended for reasons that will become apparent in the following examples.
I have modified your sample data to make both of the x/y axis variables numeric as this makes plotting easier, and I inverted and extended the y-axis to match your example plot.
First, using your defined breaks/limits:
library(dplyr)
library(ggplot2)
library(ggbreak)
TotalPhosphorus <- tibble(
Depth = (c(1 ,2, 3 , 1, 2, 3)),
Date = c('1/18/2021', '1/18/2021', '1/18/2021', '7/11/2021', '7/11/2021', '7/11/2021'),
DOY = c('18', '18', '18', '70', '70', '70'),
Season= c("winter", "winter", "winter", "summer", "summer", "summer"),
TotalP = c(20, 30, 400, 25, 30, 25)
)
TotalPhosphorus %>%
ggplot(aes(x = TotalP, y = Depth, colour = Season, group = Season)) +
geom_point() +
geom_path() +
scale_x_break(c(100, 390),
space = 0.2) +
scale_x_continuous(breaks = seq(0, 400, by = 50),
limits = c(0, 400)) +
scale_y_reverse(limits = c(8, 0)) +
labs(x = "Total Phosphorus ug/L",
y = "Depth (m)") +
theme_bw() +
theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1))

Note that the geom_path() ends up looking weird where it crosses the axis gap, and visually, I do not think it makes sense to plot a line this way. I am not an SME for this type of data so there may be a justification for using geom_path(), but graphically it seems aes(shape = Season) would be better choice.
Further, there are limitations to using ggbreak, including the inability to use coord_cartesian(clip = "off"). In other words, if you need to set limits = c(0, 400), the outlier point will get clipped at the edge of the plot panel. Also, I personally do not like the duplicated axis labels/ticks that ggbreak defaults to.
Another issue highlighted in the above plot relates to the size of the axis gap. Choosing axis gap values that fall between an axis break can result in no label/tick to identify where the panel after the break starts. You could set the break to match an axis break value e.g. acale_x_break(c(100, 350)), but this results in a disproportionate amount of plot 'real estate' being assigned to a single point.
To address these issues, here are some suggested workarounds:
- use shapes to represent points and omit lines
- increase
limits = to ensure points are not clipped
- create custom axis breaks and labels
- change the size of the breaks
The following uses options 1-3 and omits the top x-axis labels:
TotalPhosphorus %>%
ggplot(aes(x = TotalP, y = Depth, colour = Season, shape = Season)) +
geom_point(size = 2) +
scale_shape_manual(values = c(24, 19)) +
scale_x_break(c(100, 390),
space = 0.2) +
scale_x_continuous(breaks = c(seq(0, 100, 50), 390, 400),
limits = c(0, 402)) +
scale_y_reverse(limits = c(8, 0)) +
labs(x = "Total Phosphorus ug/L",
y = "Depth (m)") +
theme_bw() +
theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1),
axis.text.x.top = element_blank(),
axis.ticks.x.top = element_blank(),
axis.line.x.top = element_blank())

scale_x_continuous(): you specify only 0, 50 and 100 so there is no break around 400.coord_cartesian()act like a zoom, so there is no need to specify it neither. And since you mentionnedggbreak, I think that you can use it like this :ggbreak::scale_x_break(c(50, 380)). Personnaly, I think that you should avoid this representation, or at least avoid usinggeom_path(). (Remember to remove/ajustscale_x_continuous())