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