# Import modules
import time
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from IPython.display import clear_output
76 Weed population model
Weed herbicide resistance is one of the most pressing problems of modern agriculture. Weeds can spread across fields and cause substantial competition for limiting resources with crops. Stochastic weed population models are excellent tools in understanding and managing the spread of resistant weed species in agricultural and natural ecosystems. These models simulate the random processes that affect weed dispersal, germination, and survival, offering insights into how weed populations might evolve over time under different environmental conditions and management strategies. By incorporating randomness, models can more accurately reflect the inherent variability in biological systems.
In this exercise we will implement a simple two-dimensional model to simulate the population dynamics of a population of a resistant weed. The model simulates the germination of plants and dispersal of seeds over a specified area and time frame. It tracks the location of each seed and whether it has germinated or not, allowing for the visualization of the spatial distribution and growth over time that reveal hotspots of resistant weeds in the soil seed bank. The model will have the following assumptions:
Weeds will be annual plants. This means that after producing offspring, germinated weeds are removed from the simulation. The success of the population rests entirely on the ability of the seeds of the resistant weeds to grow and generate their own offspring.
Self-pollinating weeds.
Annual herbicide application. This means that every year non-resistant plants will be killed by herbicide applications. Because of this assumption, non-resistant weeds don’t need to be included in the simulation at all.
# Model parameters
= 25 # number of years
years = 5 # viable seeds per plant
seeds_per_plant = 0.05 # fraction of seeds that germinate
germination_rate = 5 # initial resistant seeds
seed_bank = 50 # dispersion distance from parent plant
dispersion_distance = 1000 # meters
x_max = 1000 # meters y_max
# Random seed for reproducibility
3)
np.random.seed(
# Define initial seed bank
= np.random.random(seed_bank) * x_max # Random X coordinates
x = np.random.random(seed_bank) * y_max # Random Y coordinates
y = np.zeros(seed_bank, dtype=bool)
germinated
# Create figure to visualize initial seeds
=(6,6))
plt.figure(figsizef'Iteration: 0')
plt.title(=1, marker='.', color='grey', label='Seed bank')
plt.scatter(x, y, s'X coordinate (m)')
plt.xlabel('Y coordinate (m)')
plt.ylabel(-10, x_max+10])
plt.xlim([-10, y_max+10])
plt.ylim([450,950,f"Resistant weeds in seed bank: {seed_bank}")
plt.text(='upper right', bbox_to_anchor=(1.4,1))
plt.legend(loc plt.show()
# Random seed for reproducibility
1)
np.random.seed(
for t in range(years):
=True)
clear_output(wait=(6,6))
plt.figure(figsizef'Year: {t+1}')
plt.title('X coordinate (m)')
plt.xlabel('Y coordinate (m)')
plt.ylabel(-100, x_max+100])
plt.xlim([-100, y_max+100])
plt.ylim([
# Plot entire seed bank
=1, marker='.', color='grey', label='Seed bank')
plt.scatter(x, y, s
# Select seeds that germinate into plants
= x.shape[0] # Get updated number of seeds in the soil bank
seed_bank = int(np.minimum(np.ceil(seed_bank * germination_rate), 100))
N_germinated = np.random.choice(range(seed_bank), N_germinated, replace=False)
idx_germinated = True
germinated[idx_germinated]
plt.scatter(x[idx_germinated], y[idx_germinated], ='.', color='red', label='Germinated')
marker
# Generate new seeds for resistant plants one plant at the time
= np.array([])
x_new = np.array([])
y_new = np.array([], dtype=bool)
germinated_new
for k in idx_germinated:
# Generate coordinates for all new seeds for current plant
= x[k] + dispersion_distance * np.random.randn(seeds_per_plant)
x_new_plant = y[k] + dispersion_distance * np.random.randn(seeds_per_plant)
y_new_plant = np.zeros(seeds_per_plant, dtype=bool)
germinated_new_plant
# Append new seeds to array storing all new seeds
= np.concatenate( (x_new, x_new_plant) )
x_new = np.concatenate( (y_new, y_new_plant) )
y_new = np.concatenate( (germinated_new, germinated_new_plant) )
germinated_new
# Remove germinated seeds from seed bank
= np.delete(x, idx_germinated)
x = np.delete(y, idx_germinated)
y = np.delete(germinated, idx_germinated)
germinated
# Append new seeds to seed bank
= np.concatenate( (x, x_new) )
x = np.concatenate( (y, y_new) )
y = np.concatenate( (germinated, germinated_new) )
germinated # Render figure
0,1050,f"Resistant weeds in seed bank: {seed_bank}")
plt.text(='upper right', bbox_to_anchor=(1.4,1))
plt.legend(loc
plt.show()
0.5) time.sleep(
References
Holst, N., Rasmussen, I.A. and Bastiaans, L., 2007. Field weed population dynamics: a review of model approaches and applications. Weed Research, 47(1), pp.1-14.
Trucco, F., Jeschke, M.R., Rayburn, A.L. and Tranel, P.J., 2005. Amaranthus hybridus can be pollinated frequently by A. tuberculatus under field conditions. Heredity, 94(1), pp.64-70.