Size structure

PSD

PSD stands for “Proportional Stock Density”. It essentially means the proportion of fish of stock size that are of quality size or greater. This is a common metric used in fisheries management to assess the health of a fish stock and to make informed decisions about fishing regulations and conservation efforts.

To calculate PSD, you would typically use the following formula: \[ PSD = \left( \frac{\text{Number of fish} \geq \text{quality size}}{\text{Number of fish} \geq \text{stock size}} \right) \times 100 \]

The length at which a fish is considered to be of “quality size” can vary depending on the species, and we use Gabelhouse lengths. Gabelhouse lengths, developed in 1984, are standardized, minimum total lengths (in mm or inches) used to categorize fish populations into stock, quality, preferred, memorable, and trophy sizes for assessing fish population structure. These categories provide precise, universal metrics for measuring fisheries

Generally, Gabelhouse length categories are as follows: - Stock Length: The minimum length at which fish are considered part of the population. 20-26% of trophy size - Quality Length: The minimum length at which fish are considered of good eating quality. 26-40% of trophy size - Preferred Length: The minimum length at which fish are considered to be of preferred size for anglers. 40-60% of trophy size - Memorable Length: The minimum length at which fish are considered to be of memorable size for anglers. 60-80% of trophy size - Trophy Length: The minimum length at which fish are considered to be of trophy size for anglers. 80% or more of the maximum size

The PSD metric is important for fisheries management because it helps to determine the size structure of the fish population. A high PSD indicates that a large proportion of the fish are of quality size or greater, which can be a sign of a healthy fish stock. Conversely, a low PSD may indicate that the fish population is dominated by smaller, less desirable fish, which can be a sign of overfishing or poor habitat conditions.

We can also estimate an RSD if we want to know the proportion of fish that are of memorable size or larger. For RSD we use the following formula:

\[ RSD\text{-}X = \left( \frac{\text{Number of fish} \geq \text{size category X}}{\text{Number of fish} \geq \text{stock size}} \right) \times 100 \]

Question 1

In a healthy population, what do you think is the proportion of stock, quality, preferred, memorable, and trophy fish? Is it better to use PSD or to do a histogram of size distribution to understand the size structure of a population? Why?

Remember, these metrics use standardized length categories defined for each species (Stock, Quality, Preferred, Memorable, Trophy). Consult psdVal() in the FSA package.

library(FSA)
# Preview standard length categories for our four species
psdVal("Bluegill")
psdVal("Largemouth Bass")
psdVal("Walleye")
psdVal("Channel Catfish")

The Data

For this assignment you will work with electrofishing survey data collected from a reservoir in the Midwest. Four species were sampled: Bluegill, Largemouth Bass, Walleye, and Channel Catfish. Total lengths (mm) were recorded for each individual.

Load the electrofishing.csv file from Canvas and read into R in an object called fish_data. Then, use head() to look at the first few rows of the data.

Question 2

In a few words, describe the dataset.

Part 1 – Calculating PSD and RSD by Hand

Before using FSA functions, it is important to understand what those functions are computing. In this section you will calculate PSD and RSD manually for each species.

Step-by-step workflow (example: Bluegill)

Use psdVal() to look up the standard length thresholds, then use logical subsetting to count fish in each category.

Before you run this code!

Remember how we created a file with only one of the species (e.g., Monarchs) when we worked with the butterfly data? You will need to do the same thing here for each species.

You can use the same code as before, or also filter() from the dplyr package to create a new data frame for each species. For example, for Bluegill:

library(dplyr)
bluegill <- fish_data %>% filter(species == "Bluegill")

This is easier that the other way, but does requires a package (dplyr). You can also do

bluegill <- fish_data[fish_data$species == "Bluegill", ]

Which follows the logic of R more closely, but is a bit more cumbersome.

# Step 1: retrieve the breakpoints
bg_breaks <- psdVal("Bluegill")
bg_breaks   # Stock, Quality, Preferred, Memorable, Trophy
 substock     stock   quality preferred memorable    trophy 
        0        80       150       200       250       300 
# Step 2: filter to stock size and above
bg_stock <- bluegill %>% filter(tl_mm >= bg_breaks["stock"])
# Step 3: count fish >= quality
bg_quality <- bluegill %>% filter(tl_mm >= bg_breaks["quality"])
# Step 4: calculate PSD
PSD_bluegill <- (nrow(bg_quality) / nrow(bg_stock)) * 100
round(PSD_bluegill, 1)
[1] 38.2

✏️ Your Turn

Using the workflow above, complete the following for all four species.

For each species, calculate:

  • PSD (quality and above / stock and above)
  • RSD-P (preferred and above / stock and above)
  • RSD-M (memorable and above / stock and above) — where applicable

Fill in the table like the one below with your results (you can introduce tables in your qmd):

Species N (stock+) PSD RSD-P RSD-M
Bluegill
Largemouth Bass
Walleye
Channel Catfish
Question 3 (10 pts)

Complete the part 1 section

Part 2 – Calculating PSD and RSD with FSA

The FSA package provides psdCalc(), which automates the computations above and adds 95% confidence intervals using the binomial method.

Syntax

psdCalc(~tl_mm, data = your_data, species = "Species Name", what = "all")
  • ~tl_mm — formula referencing the length column
  • species — must match an entry in psdVal() exactly
  • what = "all" — returns PSD and all RSD values

Example – Bluegill

psdCalc(~tl_mm, data = bluegill, species = "Bluegill", what = "all")
        Estimate 95% LCI 95% UCI
PSD-Q         38      32      44
PSD-P         12       8      15
PSD S-Q       62      56      68
PSD Q-P       27      21      32
PSD P-M       12       8      15
Question 4 (5 pts)

Estimate PSD and RSD values for all four species using psdCalc(). Do the results match your manual calculations? If not, can you explain why?

Visualizing Size Structure

Visualizing the length-frequency distribution helps us understand where fish are concentrated across size categories and how the population is structured.

Histograms

A length-frequency histogram is one of the most common tools in fisheries science. We will add vertical lines for each PSD breakpoint to provide biological context.

Example – Bluegill

bg_breaks <- psdVal("Bluegill")


  ggplot(data=bluegill,aes(x = tl_mm)) +
  geom_histogram(binwidth = 15, fill = "steelblue", color = "white", alpha = 0.85) +
  geom_vline(xintercept = bg_breaks[c("stock", "quality", "preferred", "memorable")],
             linetype = "dashed", color = "firebrick", linewidth = 0.7) +
  annotate("text",
           x     = bg_breaks[c("stock", "quality", "preferred", "memorable")] + 4,
           y     = Inf,
           label = c("S", "Q", "P", "M"),
           vjust = 1.5, hjust = 0, color = "firebrick", fontface = "bold") +
  labs(title = "Bluegill Length-Frequency",
       x = "Total Length (mm)", y = "Count") +
  theme_classic()

Question 5 (5 pts)

Plot the histogram for all species. You can base your code on the one I provided for Bluegill, but make sure to adjust the breakpoints and labels for each species. Describe the size structure of each population based on your histograms.

Looking at the community

We can plot all size distributions using a density plot:

# Retrieve stock-size cutoffs for each species and filter accordingly

fish_data_stock <- fish_data %>%
  group_by(species) %>%
  ungroup()

ggplot(fish_data_stock, aes(x = tl_mm, fill = species, color = species)) +
  geom_density(alpha = 0.25, linewidth = 0.8) +
  labs(title  = "Size Structure Density – All Four Species (Stock Size and Above)",
       x      = "Total Length (mm)",
       y      = "Density",
       fill   = "Species",
       color  = "Species") +
  theme_classic() +
  theme(legend.position = "bottom")

Question 6 (1 pts)

Based on the density plot, are any of the species dominated by small fish or large fish?

Tic-Tac-Toe Plot

(Bluegill & Largemouth Bass)

The tic-tac-toe plot is a great way to use the PSD data. It visualizes whether the proportion of quality fish for a prey and predator species is the way we want it.

Essentially, you, as a manager choose some target PSD values for your two species, in this case Bluegill and Largemouth Bass.

The target PSD values depends on whether we want a pond with an abundance of panfish, one with balanced populations, or one with larger bass.

The following table shows the target PSD values for each of those scenarios:

Scenario Bluegill PSD Largemouth PSD
Panfish abundant 50-80 20-40
Balanced 20-60 40-70
Big Bass 10-50 50-80

We can then use the ticTacToe() function from the FSA package to visualize where our PSD values fall in relation to those targets.

We can plot the tic-tac-toe section for the “Panfish” scenario as follows:

tictactoe(predlab="Largemouth Bass", preylab="Bluegill PSD", predobj=c(20,40),preyobj=c(50,80))

When we want a pond dominated by Panfish, we want a lot of large bluegill, and not too many Largemouth Bass. So, we want our bluegill PSD to be high (50-80), and our bass PSD to be low (20-40). Essentially, we want our PSD values to fall right on the shaded area of the tic-tac-toe plot. If our PSD values fall outside of that area, then we are not meeting the target for that scenario. But! You can tell why

We can add our observed PSD values like this:

First, we need the values we observed:

psdCalc(~tl_mm, data = bluegill, species = "Bluegill", what = "all")
        Estimate 95% LCI 95% UCI
PSD-Q         38      32      44
PSD-P         12       8      15
PSD S-Q       62      56      68
PSD Q-P       27      21      32
PSD P-M       12       8      15

And we can see that the PSD for bluegill is 38, with a CI spanning from 32 to 44.

psdCalc(~tl_mm, data = bass, species = "Largemouth Bass", what = "all")
Warning: Some category sample size <20, some CI coverage may be
 lower than 95%.
        Estimate 95% LCI 95% UCI
PSD-Q         42      35      50
PSD-P         15      10      21
PSD-M          2       0       4
PSD S-Q       58      50      65
PSD Q-P       27      20      34
PSD P-M       14       8      19
PSD M-T        2       0       4

And we can see that the PSD for Largemouth Bass is 42, with a CI spanning from 35 to 50.

library(plotrix)
tictactoe(predlab="Largemouth Bass", preylab="Bluegill PSD", predobj=c(20,40),preyobj=c(50,80))

plotCI(38, 42, li=32, ui=44, err="x",pch=16,add=TRUE)
plotCI(38, 42, li=35, ui=50, err="y",pch=16,add=TRUE)

We are simply adding points and CI’s on top of the plot

Question 7 (5 pts)

If you are a manager that wants to create a pond dominated by panfish, do you think the current PSD values for Bluegill and Largemouth Bass are good? Why or why not? What do you need to do to meet the target PSD values for that scenario?

Question 8 (5 pts)

Plot a tic-tac-toe plot for the “Balanced” scenario. Add your observed PSD values for Bluegill and Largemouth Bass. Do you think the current PSD values are good for a balanced pond? Why or why not? What do you need to do to meet the target PSD values for that scenario?