Nonlinear systems

In [1]:
X, Y, P, S, F = var('X Y P S F')
palette = [(215/255, 0/255, 132/255), (255/255, 1/255, 73/255), (255/255, 121/255, 1/255), (255/255, 210/255, 0/255)]
cool_palette = [(0/255, 150/255, 173/255), (0/255, 200/255, 146/255)]
grid_gray = (2/3, 2/3, 2/3)
def rectangle(a, b): return line([(a[0], a[1]), (b[0], a[1]), (b[0], b[1]), (a[0], b[1]), (a[0], a[1])], color = grid_gray)

Predator-prey population model

Phase portrait

In [14]:
predator_prey_model = (Y - Y*P, -P + Y*P)
predator_prey_labels = ['$Y$ (yeast)', '$P$ (Paramecia)']
predator_prey_phase = plot_vector_field(predator_prey_model, (Y, -1, 2), (P, -1, 2), aspect_ratio = 1, axes_labels = predator_prey_labels)
predator_prey_phase
Out[14]:

Regions to zoom in on

In [35]:
predator_prey_phase + rectangle((-0.5, -0.5), (0.5, 0.5)) + rectangle((-0.1, -0.1), (0.1, 0.1)) + rectangle((1-0.5, 1-0.5), (1+0.5, 1+0.5)) + rectangle((1-0.1, 1-0.1), (1+0.1, 1+0.1))
Out[35]:

Zooming in on $(0, 0)$

In [25]:
plot_vector_field(predator_prey_model, (Y, -0.5, 0.5), (P, -0.5, 0.5), aspect_ratio = 1, axes_labels = predator_prey_labels)
Out[25]:
In [26]:
predator_prey_low_axes = line([(0, -0.1), (0, 0.1)], thickness=3, color = cool_palette[1], zorder = 0) + line([(-0.1, 0), (0.1, 0)], thickness=3, color = cool_palette[0], zorder = 0)
predator_prey_low_axes + plot_vector_field(predator_prey_model, (Y, -0.1, 0.1), (P, -0.1, 0.1), aspect_ratio = 1, axes_labels = predator_prey_labels)
Out[26]:

Zooming in on $(1,1)$

In [30]:
plot_vector_field(predator_prey_model, (Y, 1 - 0.5, 1 + 0.5), (P, 1 - 0.5, 1 + 0.5), aspect_ratio = 1, axes_labels = predator_prey_labels)
Out[30]:
In [32]:
plot_vector_field(predator_prey_model, (Y, 1 - 0.1, 1 + 0.1), (P, 1 - 0.1, 1 + 0.1), aspect_ratio = 1, axes_labels = predator_prey_labels)
Out[32]:

Epidemic model

Phase portrait

In [32]:
epidemic_model = (-3*S*F, 3*S*F - 2*F)
epidemic_labels = ['$S$ (susceptible)', '$F$ (infected)']
epidemic_phase = plot_vector_field(epidemic_model, (S, -1, 2), (F, -1, 2), aspect_ratio = 1, axes_labels = epidemic_labels)
epidemic_phase
Out[32]:

Regions to zoom in on

In [36]:
epidemic_phase + rectangle((1-0.1, -0.1), (1+0.1, 0.1))
Out[36]:

Zooming in on $(1,0)$

In [42]:
epidemic_mid_axes = line([(1-0.1, 0.1/3), (1+0.1, -0.1/3)], thickness=3, color = cool_palette[1], zorder = 0) + line([(1-0.1, 0), (1+0.1, 0)], thickness=3, color = cool_palette[0], zorder = 0)
epidemic_mid_axes + plot_vector_field(epidemic_model, (S, 1 - 0.1, 1 + 0.1), (F, -0.1, 0.1), aspect_ratio = 1, axes_labels = epidemic_labels)
Out[42]:

Zooming in on $(2,0)$

In [42]:
epidemic_far_axes = line([(2-0.1, 0.1*2/3), (2+0.1, -0.1*2/3)], thickness=3, color = cool_palette[1], zorder = 0) + line([(2-0.1, 0), (2+0.1, 0)], thickness=3, color = cool_palette[0], zorder = 0)
epidemic_far_axes + plot_vector_field(epidemic_model, (S, 2 - 0.1, 2 + 0.1), (F, -0.1, 0.1), aspect_ratio = 1, axes_labels = epidemic_labels)
Out[42]:

Ecological competition models

Stable coexistence

In [3]:
stable_coexist_model = (X*(1 - X - 2/3*Y), Y*(1 - Y - 1/2*X))
coexist_labels = ['$X$', '$Y$']
stable_coexist_stream = streamline_plot(stable_coexist_model, (X, 0, 2), (Y, 0, 2), aspect_ratio = 1, color = 'black', density = 2, axes_labels = coexist_labels)
stable_coexist_nullclines = line([(1, 0), (0, 3/2)], thickness=3, color = palette[2], zorder = 0) + line([(0, 1), (2, 0)], thickness=3, color = palette[0], zorder = 0)
stable_coexist_stream + stable_coexist_nullclines
Out[3]:

Unstable coexistence

In [4]:
unstable_coexist_model = (X*(1 - X - 3/2*Y), Y*(1 - Y - 2*X))
unstable_coexist_stream = streamline_plot(unstable_coexist_model, (X, 0, 2), (Y, 0, 2), aspect_ratio = 1, color = 'black', density = 2, axes_labels = coexist_labels)
unstable_coexist_nullclines = line([(1, 0), (0, 2/3)], thickness=3, color = palette[2], zorder = 0) + line([(0, 1), (1/2, 0)], thickness=3, color = palette[0], zorder = 0)
unstable_coexist_stream + unstable_coexist_nullclines
Out[4]:

Y outcompetes X

In [5]:
y_outcompetes_model = (X*(1 - X - 3/2*Y), Y*(1 - Y - 1/2*X))
y_outcompetes_stream = streamline_plot(y_outcompetes_model, (X, 0, 2), (Y, 0, 2), aspect_ratio = 1, color = 'black', density = 2, axes_labels = coexist_labels)
y_outcompetes_nullclines = line([(1, 0), (0, 2/3)], thickness=3, color = palette[2], zorder = 0) + line([(0, 1), (2, 0)], thickness=3, color = palette[0], zorder = 0)
y_outcompetes_stream + y_outcompetes_nullclines
Out[5]:

X outcompetes Y

In [6]:
x_outcompetes_model = (X*(1 - X - 2/3*Y), Y*(1 - Y - 2*X))
x_outcompetes_stream = streamline_plot(x_outcompetes_model, (X, 0, 2), (Y, 0, 2), aspect_ratio = 1, color = 'black', density = 2, axes_labels = coexist_labels)
x_outcompetes_nullclines = line([(1, 0), (0, 2/3)], thickness=3, color = palette[2], zorder = 0) + line([(0, 1), (2, 0)], thickness=3, color = palette[0], zorder = 0)
x_outcompetes_stream + x_outcompetes_nullclines
Out[6]: