Reputation: 63
So I'm trying to write a code that simulates a predator and prey situation where it starts off with a low population of predators and high population of prey. Over time the predator population grows while the prey population shrinks until the prey population is too little to sustain the predator population. The predator population dies off and then the prey population is able to repopulate. The simulation is supposed to stop whenever one of the two populations reach 0, in this case the predator population will and plot two populations over time of the simulation until it stopped. This is my code so far:
import matplotlib.pyplot as plt
def simulate(initialPred, initialPrey, preyGrowth, predationRate, predShrink, predFedBirthRate):
preyCounts = []
predatorCounts = []
predatorI = initialPred
preyI = initialPrey
predator = predatorI
prey = preyI
while predator > 0 and prey > 0:
predator = predatorI * (1 - predShrink + predFedBirthRate * preyI)
prey = preyI * (1 + preyGrowth - predationRate * predatorI)
predatorCounts.append(predator)
preyCounts.append(prey)
predatorI = predator
preyI = prey
plt.plot(predatorCounts, 'r', preyCounts, 'b')
plt.show()
return preyCounts, predatorCounts
simulate(50,1000,0.25,0.01,0.05,0.00002)
But it's supposed to come out like this:
Can someone help me please?
*Also aside from this whenever I put my plotting code outside of the function after the function line with values inside like this:
simulate(50,1000,0.25,0.01,0.05,0.00002)
plt.plot(predatorCounts, 'r', preyCounts, 'b')
plt.show()
It doesn't plot the values from the function and says predatorCounts
and preyCounts
are undefined.
Upvotes: 0
Views: 192
Reputation: 19855
If I initialize your plot data with the starting populations and use int()
truncation for the populations, I get the plot you say you're supposed to see:
import matplotlib.pyplot as plt
def simulate(initialPred, initialPrey, preyGrowth, predationRate, predShrink, predFedBirthRate):
preyCounts = [initialPrey]
predatorCounts = [initialPred]
predator = initialPred
prey = initialPrey
while predator > 0 and prey > 0:
predatorScaleFactor = 1.0 - predShrink + predFedBirthRate * prey
preyScaleFactor = 1.0 + preyGrowth - predationRate * predator
predator = int(predator * predatorScaleFactor)
prey = int(prey * preyScaleFactor)
predatorCounts.append(predator)
preyCounts.append(prey)
plt.plot(predatorCounts, 'r', preyCounts, 'b')
plt.show()
return preyCounts, predatorCounts
simulate(50, 1000, 0.25, 0.01, 0.05, 0.00002)
Upvotes: 1
Reputation: 23783
So you looked at your process/calcs and it seems correct but you look at your result and it's funny. One thing you notice when you print the counts...
print predatorI, preyI
is that there are fractions of predators and prey which, in the real world, doesn't make sense. You are trying to simulate the real world. All your rate parameters are probably based on whole things, not fractional things. So you decide that there can't be any fractional beings in your simulation and you only deal with whole beings (ints) after the population growth calculations ...
Your function returns the count vectors. If you want to move the plotting statements outside of the function you need to assign the function's return value(s) to a name and then use them for plotting.
prey, predator, = simulate(50,1000,0.25,0.01,0.05,0.00002)
plt.plot(predator, 'r', prey, 'b')
plt.show()
Here are some things to read from the docs concerning names, scope, namespaces https://docs.python.org/3/tutorial/classes.html#a-word-about-names-and-objects https://docs.python.org/3/reference/executionmodel.html#naming-and-binding
You might need to read them periodically as you use the language more.
Upvotes: 1