lpnguyen commited on
Commit
6808a71
1 Parent(s): 7239cf1

Create tools.py

Browse files
Files changed (1) hide show
  1. tools.py +168 -0
tools.py ADDED
@@ -0,0 +1,168 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import plotly.graph_objects as go
2
+ import plotly.express as px
3
+ import numpy as np
4
+
5
+ ef plot_3D_invfitness(trait, fitness, resident, range, color="RdBu"):
6
+ X, Y = np.meshgrid(trait, trait)
7
+ f_projection = (np.min(fitness) - 0.5) * np.ones(fitness.shape)
8
+ axis = dict(
9
+ showbackground=True,
10
+ backgroundcolor="rgb(230, 230,230)",
11
+ showgrid=False,
12
+ zeroline=False,
13
+ showline=False,
14
+ )
15
+
16
+ layout = go.Layout(
17
+ autosize=False,
18
+ width=600,
19
+ height=500,
20
+ scene=dict(
21
+ xaxis=dict(axis),
22
+ yaxis=dict(axis),
23
+ zaxis=dict(axis, range=range),
24
+ aspectratio=dict(x=1, y=1, z=1),
25
+ xaxis_title="Resident trait",
26
+ yaxis_title="Mutant trait",
27
+ zaxis_title="Invasion fitness",
28
+ ),
29
+ )
30
+ x_projection = resident * np.ones(fitness.shape)
31
+ fitness_surface = go.Surface(x=X, y=Y, z=fitness, colorscale=color)
32
+ PIP = go.Surface(
33
+ x=X,
34
+ y=Y,
35
+ z=f_projection,
36
+ surfacecolor=(fitness > 0),
37
+ colorscale="Greens",
38
+ showlegend=False,
39
+ showscale=False,
40
+ )
41
+ slice = go.Surface(
42
+ x=x_projection,
43
+ y=Y,
44
+ z=(fitness * 5),
45
+ surfacecolor=x_projection,
46
+ colorscale="Greys",
47
+ opacity=0.5,
48
+ showlegend=False,
49
+ showscale=False,
50
+ )
51
+ fig = go.Figure(
52
+ data=[
53
+ fitness_surface,
54
+ PIP,
55
+ slice,
56
+ ],
57
+ layout=layout,
58
+ )
59
+ return fig
60
+
61
+
62
+ def plot_invasionfitness(zm, zlist, fitness_func, pars, range):
63
+ inv_fitness = fitness_func(zm, zlist, pars)
64
+
65
+ fig = px.line(
66
+ x=zlist, y=inv_fitness, labels={
67
+ "x": "Mutant trait value (z)", "y": "Invasion fitness"}
68
+ )
69
+ fig.add_vline(x=zm, line_dash="dashdot")
70
+ fig.add_hline(y=0, line_dash="dash")
71
+ fig.update_layout(
72
+ title="Interactive invasion process",
73
+ xaxis=dict(range=[0, zlist[-1]], autorange=False),
74
+ yaxis=dict(range=range, autorange=False), autosize=False,
75
+ width=450,
76
+ height=400
77
+ )
78
+ return fig
79
+
80
+
81
+ def make_interactive_video(z_start, z_end, step, zlist, fitness_func, pars, range):
82
+ inv_vid = []
83
+ for z_val in np.arange(z_start, z_end, step):
84
+ inv_vid.append(fitness_func(z_val, zlist, pars))
85
+ vid = go.Figure(
86
+ data=[
87
+ go.Line(x=zlist, y=fitness_func(
88
+ z_start, zlist, pars), name="invasion fitness"),
89
+ go.Line(
90
+ x=zlist,
91
+ y=np.zeros(len(zlist)),
92
+ line=dict(color="black", width=1, dash="dash"),
93
+ name="Invasion threshold",
94
+ ),
95
+ go.Scatter(
96
+ x=[z_start] * 10,
97
+ y=np.linspace(-2, 2, 10),
98
+ mode="lines",
99
+ line=dict(color="black", dash="dashdot"),
100
+ name="Resident trait value",
101
+ ),
102
+ ],
103
+ layout=go.Layout(
104
+ title="Invasion process video", autosize=False,
105
+ width=550,
106
+ height=500,
107
+ xaxis=dict(range=[0, zlist[-1]], autorange=False),
108
+ yaxis=dict(range=range, autorange=False),
109
+ xaxis_title="Mutant trait value",
110
+ updatemenus=[
111
+ dict(type="buttons", buttons=[
112
+ dict(label="Play", method="animate", args=[None, {"frame": {"duration": 500, "redraw": False},
113
+ "fromcurrent": True, "transition": {"duration": 300,
114
+ "easing": "quadratic-in-out"}}]),
115
+ dict(label="Pause", method="animate", args=[[None], {"frame": {"duration": 0, "redraw": False},
116
+ "mode": "immediate",
117
+ "transition": {"duration": 0}}])]),
118
+
119
+ ],
120
+ ),
121
+ frames=[
122
+ go.Frame(
123
+ data=[
124
+ go.Line(x=zlist, y=i),
125
+ go.Line(
126
+ x=zlist,
127
+ y=np.zeros(len(zlist)),
128
+ line=dict(color="black", dash="dash"),
129
+ ),
130
+ go.Scatter(
131
+ x=[z_val] * 10,
132
+ y=np.linspace(-2, 2, 10),
133
+ line=dict(color="black", dash="dashdot"),
134
+ mode="lines",
135
+ ),
136
+ ]
137
+ )
138
+ for i, z_val in zip(inv_vid, np.arange(z_start, z_end, step))
139
+ ],
140
+ )
141
+ return vid
142
+
143
+
144
+ def plot_PIP(zlist, fitness_func, pars):
145
+ X, Y = np.meshgrid(zlist, zlist)
146
+ inv_fitness3D = fitness_func(X, Y, pars)
147
+ fig = go.Figure(
148
+ data=go.Contour(
149
+ x=zlist,
150
+ y=zlist,
151
+ z=inv_fitness3D,
152
+ colorscale="PRGn",
153
+ showscale=False,
154
+ contours=dict(
155
+ start=-20,
156
+ end=0,
157
+ size=10,
158
+ ),
159
+ )
160
+ )
161
+ fig.update_layout(
162
+ autosize=False,
163
+ width=400,
164
+ height=500,
165
+ xaxis_title="Resident trait",
166
+ yaxis_title="Mutant trait",
167
+ )
168
+ return fig