You need to ensure that your data is imported in the correct format first. R cannot have nested headings in data frames the way your Excel data does. The following data frame reproduces your Excel data in an R friendly format:
df <- data.frame(meters = c(0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 
20, 22, 24, 26, 28, 30), `castle barnacles` = c(0, 0, 0, 0, 0, 
3, 0, 39, 25, 39, 50, 19, 36, 25, 31, 0), `diamond barnacles` = c(6, 
14, 28, 53, 39, 44, 56, 0, 0, 0, 0, 19, 22, 11, 42, 0), `toothed wrack` = c(94, 
25, 53, 14, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), `bladder wrack` = c(0, 
28, 6, 22, 19, 42, 19, 36, 56, 39, 28, 17, 31, 14, 3, 0), check.names = FALSE)
Now the object df looks like this:
df
#>    meters castle barnacles diamond barnacles toothed wrack bladder wrack
#> 1       0                0                 6            94             0
#> 2       2                0                14            25            28
#> 3       4                0                28            53             6
#> 4       6                0                53            14            22
#> 5       8                0                39             6            19
#> 6      10                3                44             0            42
#> 7      12                0                56             0            19
#> 8      14               39                 0             0            36
#> 9      16               25                 0             0            56
#> 10     18               39                 0             0            39
#> 11     20               50                 0             0            28
#> 12     22               19                19             0            17
#> 13     24               36                22             0            31
#> 14     26               25                11             0            14
#> 15     28               31                42             0             3
#> 16     30                0                 0             0             0
To plot it using ggplot, it would be best to pivot into long format using pivot_longer from the tidyr package, and then "uncount" it using uncount, also from the tidyr package. Both the ggplot2 and tidyr package are loaded when you do library(tidyverse)
df %>%
  pivot_longer(-meters, names_to = 'Species', values_to = 'Count') %>%
  uncount(Count) %>%
  ggplot(aes(x = meters, y = Species, color = Species)) +
  geom_violin(aes(fill = after_scale(alpha(color, 0.6))),
              width = 1.8, position = 'identity', trim = FALSE) +
  scale_color_brewer(palette = 'Set1', guide = 'none') +
  theme_minimal(base_size = 16) +
  labs(x = 'Meters from shore', title = 'Species distribution', y = NULL) +
  coord_cartesian(xlim = c(0, 30), expand = FALSE) +
  theme(plot.title.position = 'plot')

Since your numbers are percentages and you wish to show relative abundance at each distance from the shore, an alternative approach might be a smoothed area plot:
df %>%
  summarize(across(-meters, ~ spline(meters, .x, n = 1000)$y)) %>%
  mutate(meters = seq(0, 30, length = 1000)) %>%
  pivot_longer(-meters, names_to = 'Species', values_to = 'Count') %>%
  mutate(Count = ifelse(Count < 0, 0, Count)) %>%
  ggplot(aes(x = meters, y = Count, colour = Species)) +
  geom_area(aes(fill = after_scale(alpha(colour, 0.5))), position = 'fill') +
  scale_colour_brewer(palette = 'Set1') +
  scale_y_continuous(labels = scales::percent) +
  theme_minimal(base_size = 16) +
  labs(x = 'Meters from shore', title = 'Species distribution', y = NULL) +
  coord_cartesian(xlim = c(0, 30), expand = FALSE) +
  theme(plot.title.position = 'plot',
        legend.position = 'bottom')

Created on 2023-07-10 with reprex v2.0.2