Spaces:
Sleeping
Sleeping
import plotly.graph_objects as go | |
import plotly.express as px | |
import numpy as np | |
def plot_3D_invfitness(trait, fitness, resident, range, color="RdBu"): | |
X, Y = np.meshgrid(trait, trait) | |
f_projection = (np.min(fitness) - 2) * np.ones(fitness.shape) | |
axis = dict( | |
showbackground=True, | |
backgroundcolor="rgb(230, 230,230)", | |
showgrid=False, | |
zeroline=False, | |
showline=False, | |
) | |
layout = go.Layout( | |
autosize=False, | |
width=600, | |
height=500, | |
scene=dict( | |
xaxis=dict(axis), | |
yaxis=dict(axis), | |
zaxis=dict(axis, range=range), | |
aspectratio=dict(x=1, y=1, z=1), | |
xaxis_title="Resident trait", | |
yaxis_title="Mutant trait", | |
zaxis_title="Invasion fitness", | |
), | |
) | |
x_projection = resident * np.ones(fitness.shape) | |
fitness_surface = go.Surface(x=X, y=Y, z=fitness, colorscale=color) | |
PIP = go.Surface( | |
x=X, | |
y=Y, | |
z=f_projection, | |
surfacecolor=(fitness > 0), | |
colorscale="Greens", | |
showlegend=False, | |
showscale=False, | |
) | |
slice = go.Surface( | |
x=x_projection, | |
y=Y, | |
z=(fitness * 1e5), | |
surfacecolor=x_projection, | |
colorscale="Greys", | |
opacity=0.5, | |
showlegend=False, | |
showscale=False, | |
) | |
fig = go.Figure( | |
data=[ | |
fitness_surface, | |
PIP, | |
slice, | |
], | |
layout=layout, | |
) | |
return fig | |
def plot_invasionfitness(zm, zlist, fitness_func, pars, range): | |
inv_fitness = fitness_func(zm, zlist, pars) | |
fig = px.line( | |
x=zlist, y=inv_fitness, labels={ | |
"x": "Mutant trait value (z)", "y": "Invasion fitness"} | |
) | |
fig.add_vline(x=zm, line_dash="dashdot") | |
fig.add_hline(y=0, line_dash="dash") | |
fig.update_layout( | |
title="Interactive invasion process", | |
xaxis=dict(range=[0, zlist[-1]], autorange=False), | |
yaxis=dict(range=range, autorange=False), autosize=False, | |
width=450, | |
height=400 | |
) | |
return fig | |
def make_interactive_video(z_start, z_end, step, zlist, fitness_func, pars, range): | |
inv_vid = [] | |
for z_val in np.arange(z_start, z_end, step): | |
inv_vid.append(fitness_func(z_val, zlist, pars)) | |
vid = go.Figure( | |
data=[ | |
go.Line(x=zlist, y=fitness_func( | |
z_start, zlist, pars), name="invasion fitness"), | |
go.Line( | |
x=zlist, | |
y=np.zeros(len(zlist)), | |
line=dict(color="black", width=1, dash="dash"), | |
name="Invasion threshold", | |
), | |
go.Scatter( | |
x=[z_start] * 10, | |
y=np.linspace(-2, 2, 10), | |
mode="lines", | |
line=dict(color="black", dash="dashdot"), | |
name="Resident trait value", | |
), | |
], | |
layout=go.Layout( | |
title="Invasion process video", autosize=False, | |
width=550, | |
height=500, | |
xaxis=dict(range=[0, zlist[-1]], autorange=False), | |
yaxis=dict(range=range, autorange=False), | |
xaxis_title="Mutant trait value", | |
updatemenus=[ | |
dict(type="buttons", buttons=[ | |
dict(label="Play", method="animate", args=[None, {"frame": {"duration": 500, "redraw": False}, | |
"fromcurrent": True, "transition": {"duration": 300, | |
"easing": "quadratic-in-out"}}]), | |
dict(label="Pause", method="animate", args=[[None], {"frame": {"duration": 0, "redraw": False}, | |
"mode": "immediate", | |
"transition": {"duration": 0}}])]), | |
], | |
), | |
frames=[ | |
go.Frame( | |
data=[ | |
go.Line(x=zlist, y=i), | |
go.Line( | |
x=zlist, | |
y=np.zeros(len(zlist)), | |
line=dict(color="black", dash="dash"), | |
), | |
go.Scatter( | |
x=[z_val] * 10, | |
y=np.linspace(-2, 2, 10), | |
line=dict(color="black", dash="dashdot"), | |
mode="lines", | |
), | |
] | |
) | |
for i, z_val in zip(inv_vid, np.arange(z_start, z_end, step)) | |
], | |
) | |
return vid | |
def plot_PIP(zlist, fitness_func, pars): | |
X, Y = np.meshgrid(zlist, zlist) | |
inv_fitness3D = fitness_func(X, Y, pars) | |
fig = go.Figure( | |
data=go.Contour( | |
x=zlist, | |
y=zlist, | |
z=inv_fitness3D, | |
colorscale="PRGn", | |
showscale=False, | |
contours=dict( | |
start=-20, | |
end=0, | |
size=10, | |
), | |
) | |
) | |
fig.update_layout( | |
autosize=False, | |
width=400, | |
height=500, | |
xaxis_title="Resident trait", | |
yaxis_title="Mutant trait", | |
) | |
return fig | |