piegy 1.0.0__py3-none-any.whl → 1.1.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- piegy/__version__.py +2 -0
- piegy/data_tools.py +4 -2
- piegy/figures.py +107 -91
- piegy/model.py +4 -10
- piegy/test_var.py +135 -77
- piegy/tools/figure_tools.py +51 -19
- piegy/videos.py +44 -66
- {piegy-1.0.0.dist-info → piegy-1.1.1.dist-info}/METADATA +9 -7
- piegy-1.1.1.dist-info/RECORD +16 -0
- {piegy-1.0.0.dist-info → piegy-1.1.1.dist-info}/WHEEL +1 -1
- piegy-1.0.0.dist-info/RECORD +0 -16
- {piegy-1.0.0.dist-info → piegy-1.1.1.dist-info}/licenses/LICENSE.txt +0 -0
- {piegy-1.0.0.dist-info → piegy-1.1.1.dist-info}/top_level.txt +0 -0
piegy/__version__.py
CHANGED
@@ -13,5 +13,7 @@ version history:
|
|
13
13
|
0.1.9: first round of full debugging
|
14
14
|
|
15
15
|
1.0.0: first version in PyPI
|
16
|
+
1.1.0: debugging. Updated a range of functions, in the following modules: figures, videos, test_var, model, figure_tools
|
17
|
+
1.1.1: minor debugging in model module.
|
16
18
|
|
17
19
|
'''
|
piegy/data_tools.py
CHANGED
@@ -118,12 +118,14 @@ def read_data(dirs):
|
|
118
118
|
|
119
119
|
# outputs
|
120
120
|
try:
|
121
|
-
sim.set_data(False, data[2][0],
|
121
|
+
sim.set_data(data_empty = False, max_record = data[2][0], compress_itv = data[2][1],
|
122
|
+
U = data[2][2], V = data[2][3], U_pi = data[2][4], V_pi = data[2][5])
|
122
123
|
except:
|
123
124
|
raise ValueError('Invalid simulation results saved in data')
|
124
125
|
|
125
126
|
return sim
|
126
|
-
|
127
|
+
|
128
|
+
|
127
129
|
|
128
130
|
|
129
131
|
|
piegy/figures.py
CHANGED
@@ -37,20 +37,20 @@ import matplotlib.pyplot as plt
|
|
37
37
|
import numpy as np
|
38
38
|
|
39
39
|
|
40
|
-
|
41
40
|
# curve type in plot
|
42
41
|
# used by UV_dyna, UV_std, and pi_dyna
|
43
42
|
CURVE_TYPE = '-'
|
44
43
|
|
45
44
|
|
46
45
|
|
47
|
-
def UV_heatmap(sim, U_color = 'Purples', V_color = 'Greens', start = 0.95, end = 1.0, annot = False, fmt = '.3g'):
|
46
|
+
def UV_heatmap(sim, ax_U = None, ax_V = None, U_color = 'Purples', V_color = 'Greens', start = 0.95, end = 1.0, annot = False, fmt = '.3g'):
|
48
47
|
'''
|
49
48
|
Makes two heatmaps for U, V average distribution over a time interval, respectively. Works best for 2D space.
|
50
49
|
1D works as well, but figures look bad.
|
51
50
|
|
52
51
|
Inputs:
|
53
52
|
sim: A model.simulation object.
|
53
|
+
ax_U, ax_V: matplotlib axes to plot on. New axes will be created if None is given.
|
54
54
|
U_color: Color for U's heatmap, uses matplotlib color maps.
|
55
55
|
V_color: Color for V's heatmap.
|
56
56
|
start: (0,1) float, where the interval should start from. Intended as a 'percentage'.
|
@@ -60,7 +60,7 @@ def UV_heatmap(sim, U_color = 'Purples', V_color = 'Greens', start = 0.95, end =
|
|
60
60
|
fmt: Number format for annotations. How many digits you want to keep. Please set annot = True first and then use fmt.
|
61
61
|
|
62
62
|
Returns:
|
63
|
-
|
63
|
+
ax_U, ax_V: matplotlib axes with heatmaps of U, V distribution plotted upon.
|
64
64
|
'''
|
65
65
|
|
66
66
|
start_index = int(start * sim.max_record)
|
@@ -77,20 +77,21 @@ def UV_heatmap(sim, U_color = 'Purples', V_color = 'Greens', start = 0.95, end =
|
|
77
77
|
V_title = figure_t.gen_title('V', start, end)
|
78
78
|
V_text = figure_t.gen_text(np.mean(V_ave), np.std(V_ave))
|
79
79
|
|
80
|
-
|
81
|
-
|
80
|
+
ax_U = figure_t.heatmap(U_ave, ax_U, U_color, annot, fmt, U_title, U_text)
|
81
|
+
ax_V = figure_t.heatmap(V_ave, ax_V, V_color, annot, fmt, V_title, V_text)
|
82
82
|
|
83
|
-
return
|
83
|
+
return ax_U, ax_V
|
84
84
|
|
85
85
|
|
86
86
|
|
87
|
-
def UV_bar(sim, U_color = 'purple', V_color = 'green', start = 0.95, end = 1.0):
|
87
|
+
def UV_bar(sim, ax_U = None, ax_V = None, U_color = 'purple', V_color = 'green', start = 0.95, end = 1.0):
|
88
88
|
'''
|
89
89
|
Makes two barplots for U, V average distribution over a time interval. Works best for 1D space.
|
90
90
|
2D works as well, but figures look bad.
|
91
91
|
|
92
92
|
Inputs:
|
93
93
|
sim: A model.simulation object.
|
94
|
+
ax_U, ax_V: matplotlib axes to plot on. New axes will be created if None is given.
|
94
95
|
U_color: Color of U's barplot. Uses Matplotlib colors.
|
95
96
|
See available colors at: https://matplotlib.org/stable/gallery/color/named_colors.html
|
96
97
|
V_color: Color of V's barplot. Uses Matplotlib colors.
|
@@ -98,7 +99,7 @@ def UV_bar(sim, U_color = 'purple', V_color = 'green', start = 0.95, end = 1.0):
|
|
98
99
|
end: (0,1) float. Where you want the interval to end.
|
99
100
|
|
100
101
|
Returns:
|
101
|
-
|
102
|
+
ax_U, ax_V: matplotlib axes with bar plots for U and V plotted upon.
|
102
103
|
'''
|
103
104
|
|
104
105
|
start_index = int(start * sim.max_record)
|
@@ -114,15 +115,15 @@ def UV_bar(sim, U_color = 'purple', V_color = 'green', start = 0.95, end = 1.0):
|
|
114
115
|
V_title = figure_t.gen_title('V', start, end)
|
115
116
|
V_text = figure_t.gen_text(np.mean(V_ave), np.std(V_ave))
|
116
117
|
|
117
|
-
|
118
|
-
|
118
|
+
ax_U = figure_t.bar(U_ave, ax = ax_U, color = U_color, xlabel = 'patches', ylabel = 'U', title = U_title, text = U_text)
|
119
|
+
ax_V = figure_t.bar(V_ave, ax = ax_V, color = V_color, xlabel = 'patches', ylabel = 'V', title = V_title, text = V_text)
|
119
120
|
|
120
|
-
return
|
121
|
+
return ax_U, ax_V
|
121
122
|
|
122
123
|
|
123
124
|
|
124
125
|
|
125
|
-
def UV_dyna(sim, interval = 20, grid = True):
|
126
|
+
def UV_dyna(sim, ax = None, interval = 20, grid = True):
|
126
127
|
'''
|
127
128
|
Plots how total U, V change overtime.
|
128
129
|
The curves are not directly based on every single data point.
|
@@ -132,13 +133,14 @@ def UV_dyna(sim, interval = 20, grid = True):
|
|
132
133
|
|
133
134
|
Inputs:
|
134
135
|
sim: A model.simulation object.
|
136
|
+
ax: matplotlib ax to plot on. New ax will be created if None is given.
|
135
137
|
interval: How many data points to take average over. Larger value makes curves smoother, but also loses local fluctuations.
|
136
138
|
NOTE: this interval doesn't overlap with sim.compress_itv.
|
137
139
|
e.g. you already took average over every 20 data points, then using interval <= 20 here has no smoothing effect.
|
138
140
|
grid: Whether to add grid lines to plot.
|
139
141
|
|
140
142
|
Returns:
|
141
|
-
|
143
|
+
ax: matplotlib ax, contains U's, V's, and sum of U & V population.
|
142
144
|
'''
|
143
145
|
|
144
146
|
# store the average values in lists
|
@@ -160,26 +162,29 @@ def UV_dyna(sim, interval = 20, grid = True):
|
|
160
162
|
#### plot ####
|
161
163
|
xaxis = np.linspace(0, sim.maxtime, len(U_curve))
|
162
164
|
|
163
|
-
|
165
|
+
if ax == None:
|
166
|
+
_, ax = plt.subplots()
|
164
167
|
ax.grid(grid)
|
165
168
|
ax.plot(xaxis, U_curve, CURVE_TYPE, label = 'U')
|
166
169
|
ax.plot(xaxis, V_curve, CURVE_TYPE, label = 'V')
|
167
170
|
ax.plot(xaxis, total_curve, CURVE_TYPE, label = 'total')
|
168
|
-
ax.
|
171
|
+
ax.set_xlabel('Time')
|
172
|
+
ax.set_ylabel('Population')
|
173
|
+
ax.set_title('Population U & V Over Time')
|
169
174
|
ax.legend()
|
170
175
|
|
171
|
-
return
|
176
|
+
return ax
|
172
177
|
|
173
178
|
|
174
179
|
|
175
180
|
|
176
|
-
def UV_hist(sim, U_color = 'purple', V_color = 'green', start = 0.95, end = 1.0):
|
181
|
+
def UV_hist(sim, ax_U = None, ax_V = None, U_color = 'purple', V_color = 'green', start = 0.95, end = 1.0):
|
177
182
|
'''
|
178
183
|
Makes density histograms for U, V's average distribution over an interval.
|
179
184
|
Sometimes it may not be shown in density plots due to matplotlib features.
|
180
185
|
|
181
186
|
Returns:
|
182
|
-
|
187
|
+
ax_U, ax_V: matplotlib axes with heatmaps of U, V population density plotted upon.
|
183
188
|
'''
|
184
189
|
|
185
190
|
start_index = int(start * sim.max_record)
|
@@ -190,30 +195,32 @@ def UV_hist(sim, U_color = 'purple', V_color = 'green', start = 0.95, end = 1.0)
|
|
190
195
|
|
191
196
|
#### plot ####
|
192
197
|
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
+
if ax_U == None:
|
199
|
+
_, ax_U = plt.subplots()
|
200
|
+
ax_U.set_xlabel('Population U')
|
201
|
+
ax_U.set_ylabel('Density')
|
202
|
+
ax_U.hist(U_ave, color = U_color, density = True)
|
203
|
+
ax_U.set_title(figure_t.gen_title('U Hist', start, end))
|
198
204
|
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
205
|
+
if ax_V == None:
|
206
|
+
_, ax_V = plt.subplots()
|
207
|
+
ax_V.set_xlabel('Population V')
|
208
|
+
ax_V.set_ylabel('Density')
|
209
|
+
ax_V.hist(V_ave, color = V_color, density = True)
|
210
|
+
ax_V.set_title(figure_t.gen_title('V Hist', start, end))
|
204
211
|
|
205
|
-
return
|
212
|
+
return ax_U, ax_V
|
206
213
|
|
207
214
|
|
208
215
|
|
209
216
|
|
210
|
-
def UV_std(sim, interval = 20, grid = True):
|
217
|
+
def UV_std(sim, ax = None, interval = 20, grid = True):
|
211
218
|
'''
|
212
219
|
Plots how standard deviation of U, V change over time.
|
213
220
|
Takes average over many small interval to smooth out local fluctuations.
|
214
221
|
|
215
222
|
Returns:
|
216
|
-
|
223
|
+
ax: matplotlib ax, contains U's and V's std curves.
|
217
224
|
'''
|
218
225
|
|
219
226
|
interval = figure_t.scale_interval(interval, sim.compress_itv)
|
@@ -232,15 +239,17 @@ def UV_std(sim, interval = 20, grid = True):
|
|
232
239
|
#### plot ####
|
233
240
|
xaxis = np.linspace(0, sim.maxtime, len(U_std))
|
234
241
|
|
235
|
-
|
242
|
+
if ax == None:
|
243
|
+
_, ax = plt.subplots()
|
236
244
|
ax.grid(grid)
|
237
245
|
ax.plot(xaxis, U_std, CURVE_TYPE, label = 'U std')
|
238
246
|
ax.plot(xaxis, V_std, CURVE_TYPE, label = 'V std')
|
239
247
|
ax.legend()
|
240
|
-
ax.set_xlabel('
|
241
|
-
ax.
|
242
|
-
|
243
|
-
|
248
|
+
ax.set_xlabel('Time')
|
249
|
+
ax.set_ylabel('Std Dev')
|
250
|
+
ax.set_title('Population Std-Dev Dynamics')
|
251
|
+
|
252
|
+
return ax
|
244
253
|
|
245
254
|
|
246
255
|
|
@@ -270,7 +279,7 @@ def UV_expected_val(sim):
|
|
270
279
|
|
271
280
|
|
272
281
|
|
273
|
-
def UV_expected(sim, U_color = 'Purples', V_color = 'Greens', annot = False, fmt = '.3g'):
|
282
|
+
def UV_expected(sim, ax_U = None, ax_V = None, U_color = 'Purples', V_color = 'Greens', annot = False, fmt = '.3g'):
|
274
283
|
'''
|
275
284
|
Calculate expected population distribution based on matrices, assuming no migration.
|
276
285
|
For the formulas, see stochastic_mode.expected_UV
|
@@ -279,8 +288,8 @@ def UV_expected(sim, U_color = 'Purples', V_color = 'Greens', annot = False, fmt
|
|
279
288
|
Note the colors are color maps.
|
280
289
|
|
281
290
|
Returns:
|
282
|
-
|
283
|
-
If 1D (N or M == 1), then
|
291
|
+
ax_U, ax_V: If 2D (N and M both > 1), then ax_U and ax_V are heatmaps.
|
292
|
+
If 1D (N or M == 1), then ax_U and ax_V are barplots.
|
284
293
|
'''
|
285
294
|
|
286
295
|
U_expected, V_expected = UV_expected_val(sim)
|
@@ -292,20 +301,20 @@ def UV_expected(sim, U_color = 'Purples', V_color = 'Greens', annot = False, fmt
|
|
292
301
|
|
293
302
|
if (sim.N != 1) and (sim.M != 1):
|
294
303
|
# 2D
|
295
|
-
|
296
|
-
|
304
|
+
ax_U = figure_t.heatmap(U_expected, ax_U, U_color, annot, fmt, title = 'Expected U', text = U_text)
|
305
|
+
ax_V = figure_t.heatmap(V_expected, ax_V, V_color, annot, fmt, title = 'Expected V', text = V_text)
|
297
306
|
|
298
307
|
else:
|
299
308
|
# 1D
|
300
|
-
|
301
|
-
|
309
|
+
ax_U = figure_t.bar(U_expected.flatten(), ax_U, color = U_color, xlabel = 'patches', ylabel = 'popu', title = 'Expected Population U', text = U_text)
|
310
|
+
ax_V = figure_t.bar(V_expected.flatten(), ax_V, color = V_color, xlabel = 'patches', ylabel = 'popu', title = 'Expected Population V', text = V_text)
|
302
311
|
|
303
|
-
return
|
312
|
+
return ax_U, ax_V
|
304
313
|
|
305
314
|
|
306
315
|
|
307
316
|
|
308
|
-
def pi_heatmap(sim, U_color = 'BuPu', V_color = 'YlGn', start = 0.95, end = 1.0, annot = False, fmt = '.3g'):
|
317
|
+
def pi_heatmap(sim, ax_U = None, ax_V = None, U_color = 'BuPu', V_color = 'YlGn', start = 0.95, end = 1.0, annot = False, fmt = '.3g'):
|
309
318
|
'''
|
310
319
|
Make heatmaps for payoff in a specified interval.
|
311
320
|
Works best for 2D. 1D works as well, but figures look bad.
|
@@ -314,7 +323,7 @@ def pi_heatmap(sim, U_color = 'BuPu', V_color = 'YlGn', start = 0.95, end = 1.0,
|
|
314
323
|
Note the colors are matplotlib color maps.
|
315
324
|
|
316
325
|
Returns:
|
317
|
-
|
326
|
+
ax_U, ax_V: Seaborn heatmaps, for U's & V's payoff distribution, respectively.
|
318
327
|
'''
|
319
328
|
|
320
329
|
start_index = int(sim.max_record * start)
|
@@ -323,26 +332,26 @@ def pi_heatmap(sim, U_color = 'BuPu', V_color = 'YlGn', start = 0.95, end = 1.0,
|
|
323
332
|
U_pi_ave = figure_t.ave_interval(sim.U_pi, start_index, end_index)
|
324
333
|
V_pi_ave = figure_t.ave_interval(sim.V_pi, start_index, end_index)
|
325
334
|
|
326
|
-
U_title = figure_t.gen_title('
|
335
|
+
U_title = figure_t.gen_title('Payoff ' + r'$p_U$', start, end)
|
327
336
|
U_text = figure_t.gen_text(np.mean(U_pi_ave), np.std(U_pi_ave))
|
328
|
-
V_title = figure_t.gen_title('
|
337
|
+
V_title = figure_t.gen_title('Payoff ' + r'$p_V$', start, end)
|
329
338
|
V_text = figure_t.gen_text(np.mean(V_pi_ave), np.std(V_pi_ave))
|
330
339
|
|
331
|
-
|
332
|
-
|
340
|
+
ax_U = figure_t.heatmap(U_pi_ave, ax_U, U_color, annot, fmt, U_title, U_text)
|
341
|
+
ax_V = figure_t.heatmap(V_pi_ave, ax_V, V_color, annot, fmt, V_title, V_text)
|
333
342
|
|
334
|
-
return
|
343
|
+
return ax_U, ax_V
|
335
344
|
|
336
345
|
|
337
346
|
|
338
347
|
|
339
|
-
def pi_bar(sim, U_color = 'violet', V_color = 'yellowgreen', start = 0.95, end = 1.0):
|
348
|
+
def pi_bar(sim, ax_U = None, ax_V = None, U_color = 'violet', V_color = 'yellowgreen', start = 0.95, end = 1.0):
|
340
349
|
'''
|
341
350
|
Make barplot for payoff in a specified interval.
|
342
351
|
Works best for 1D. 2D works as well, but figures look bad.
|
343
352
|
|
344
353
|
Returns:
|
345
|
-
|
354
|
+
ax_U, ax_V: matplotlib axes with barplots of U and V payoff distribution plotted upon.
|
346
355
|
'''
|
347
356
|
|
348
357
|
start_index = int(sim.max_record * start)
|
@@ -351,25 +360,25 @@ def pi_bar(sim, U_color = 'violet', V_color = 'yellowgreen', start = 0.95, end =
|
|
351
360
|
U_pi_ave = figure_t.ave_interval_1D(sim.U_pi, start_index, end_index)
|
352
361
|
V_pi_ave = figure_t.ave_interval_1D(sim.V_pi, start_index, end_index)
|
353
362
|
|
354
|
-
U_title = figure_t.gen_title('
|
363
|
+
U_title = figure_t.gen_title(r'$p_U$', start, end)
|
355
364
|
U_text = figure_t.gen_text(np.mean(U_pi_ave), np.std(U_pi_ave))
|
356
|
-
V_title = figure_t.gen_title('
|
365
|
+
V_title = figure_t.gen_title(r'$p_V$', start, end)
|
357
366
|
V_text = figure_t.gen_text(np.mean(V_pi_ave), np.std(V_pi_ave))
|
358
367
|
|
359
|
-
|
360
|
-
|
368
|
+
ax_U = figure_t.bar(U_pi_ave, ax_U, U_color, 'Patches', 'Payoff ' + r'$p_U$', U_title, U_text)
|
369
|
+
ax_V = figure_t.bar(V_pi_ave, ax_V, V_color, 'Patches', 'Payoff ' + r'$p_V$', V_title, V_text)
|
361
370
|
|
362
|
-
return
|
371
|
+
return ax_U, ax_V
|
363
372
|
|
364
373
|
|
365
374
|
|
366
375
|
|
367
|
-
def pi_dyna(sim, interval = 20, grid = True):
|
376
|
+
def pi_dyna(sim, ax = None, interval = 20, grid = True):
|
368
377
|
'''
|
369
378
|
Plot how payoffs change over time.
|
370
379
|
|
371
380
|
Returns:
|
372
|
-
|
381
|
+
ax: matplotlib ax of U's, V's, and sum of U & V payoff.
|
373
382
|
'''
|
374
383
|
|
375
384
|
U_curve = []
|
@@ -390,27 +399,30 @@ def pi_dyna(sim, interval = 20, grid = True):
|
|
390
399
|
#### plot ####
|
391
400
|
xaxis = np.linspace(0, sim.maxtime, len(U_curve))
|
392
401
|
|
393
|
-
|
402
|
+
if ax == None:
|
403
|
+
_, ax = plt.subplots()
|
394
404
|
ax.grid(grid)
|
395
|
-
ax.plot(xaxis, U_curve, CURVE_TYPE, label = '
|
396
|
-
ax.plot(xaxis, V_curve, CURVE_TYPE, label = '
|
405
|
+
ax.plot(xaxis, U_curve, CURVE_TYPE, label = r'$p_U$')
|
406
|
+
ax.plot(xaxis, V_curve, CURVE_TYPE, label = r'$p_V$')
|
397
407
|
ax.plot(xaxis, total_curve, CURVE_TYPE, label = 'total')
|
398
408
|
ax.set_xlim(0, sim.maxtime)
|
399
|
-
ax.
|
409
|
+
ax.set_xlabel('Time')
|
410
|
+
ax.set_ylabel('Payoff')
|
411
|
+
ax.set_title('Payoff ' + r'$p_U$' + ' & ' + r'$p_V$' + ' over time')
|
400
412
|
ax.legend()
|
401
413
|
|
402
|
-
return
|
414
|
+
return ax
|
403
415
|
|
404
416
|
|
405
417
|
|
406
418
|
|
407
|
-
def pi_hist(sim, U_color = 'violet', V_color = 'yellowgreen', start = 0.95, end = 1.0):
|
419
|
+
def pi_hist(sim, ax_U = None, ax_V = None, U_color = 'violet', V_color = 'yellowgreen', start = 0.95, end = 1.0):
|
408
420
|
'''
|
409
421
|
Makes deensity histograms of U's and V's payoffs in a sepcified interval.
|
410
422
|
Sometimes it may not be shown in density plots due to matplotlib features.
|
411
423
|
|
412
424
|
Returns:
|
413
|
-
|
425
|
+
ax_U, ax_V: histogram of U's and V's payoff.
|
414
426
|
'''
|
415
427
|
|
416
428
|
start_index = int(start * sim.max_record)
|
@@ -421,29 +433,31 @@ def pi_hist(sim, U_color = 'violet', V_color = 'yellowgreen', start = 0.95, end
|
|
421
433
|
|
422
434
|
#### plot ####
|
423
435
|
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
436
|
+
if ax_U == None:
|
437
|
+
_, ax_U = plt.subplots()
|
438
|
+
ax_U.set_xlabel('Payoff ' + r'$p_U$')
|
439
|
+
ax_U.set_ylabel('Density')
|
440
|
+
ax_U.hist(U_pi_ave, color = U_color, density = True)
|
441
|
+
ax_U.set_title(figure_t.gen_title('Payoff ' + r'$p_U$' + ' Hist', start, end))
|
429
442
|
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
443
|
+
if ax_V == None:
|
444
|
+
_, ax_V = plt.subplots()
|
445
|
+
ax_V.set_xlabel('Payoff ' + r'$p_V$')
|
446
|
+
ax_V.set_ylabel('Density')
|
447
|
+
ax_V.hist(V_pi_ave, color = V_color, density = True)
|
448
|
+
ax_V.set_title(figure_t.gen_title('Payoff ' + r'$p_V$' + ' Hist', start, end))
|
435
449
|
|
436
|
-
return
|
450
|
+
return ax_U, ax_V
|
437
451
|
|
438
452
|
|
439
453
|
|
440
454
|
|
441
|
-
def pi_std(sim, interval = 20, grid = True):
|
455
|
+
def pi_std(sim, ax = None, interval = 20, grid = True):
|
442
456
|
'''
|
443
457
|
Plots how standard deviation of payoff change over time.
|
444
458
|
|
445
459
|
Returns:
|
446
|
-
|
460
|
+
ax: matplotlib ax of the std of payoffs.
|
447
461
|
'''
|
448
462
|
|
449
463
|
|
@@ -463,26 +477,28 @@ def pi_std(sim, interval = 20, grid = True):
|
|
463
477
|
#### plot ####
|
464
478
|
xaxis = np.linspace(0, sim.maxtime, len(U_pi_std))
|
465
479
|
|
466
|
-
|
480
|
+
if ax == None:
|
481
|
+
_, ax = plt.subplots()
|
467
482
|
ax.grid(grid)
|
468
|
-
ax.plot(xaxis, U_pi_std, CURVE_TYPE, label = '
|
469
|
-
ax.plot(xaxis, V_pi_std, CURVE_TYPE, label = '
|
483
|
+
ax.plot(xaxis, U_pi_std, CURVE_TYPE, label = r'$p_U$' + ' std')
|
484
|
+
ax.plot(xaxis, V_pi_std, CURVE_TYPE, label = r'$p_V$' + ' std')
|
470
485
|
ax.legend()
|
471
|
-
ax.set_xlabel('
|
472
|
-
ax.
|
486
|
+
ax.set_xlabel('Time')
|
487
|
+
ax.set_ylabel('Std Dev')
|
488
|
+
ax.set_title('Payoff Std-Dev Dynamics')
|
473
489
|
|
474
|
-
return
|
490
|
+
return ax
|
475
491
|
|
476
492
|
|
477
493
|
|
478
494
|
|
479
|
-
def UV_pi(sim, U_color = 'violet', V_color = 'yellowgreen', alpha = 0.
|
495
|
+
def UV_pi(sim, ax_U = None, ax_V = None, U_color = 'violet', V_color = 'yellowgreen', alpha = 0.4, start = 0.95, end = 1.0):
|
480
496
|
'''
|
481
497
|
Make two scatter plots: x-axes are population and y-axes are payoff in a specified time interval.
|
482
498
|
Reveals relationship between population and payoff.
|
483
499
|
|
484
500
|
Returns:
|
485
|
-
|
501
|
+
ax_U, ax_V: matplotlib axes with U and V population-payoff scatter plots.
|
486
502
|
'''
|
487
503
|
|
488
504
|
start_index = int(start * sim.max_record)
|
@@ -495,9 +511,9 @@ def UV_pi(sim, U_color = 'violet', V_color = 'yellowgreen', alpha = 0.25, start
|
|
495
511
|
V_pi_ave = figure_t.ave_interval(sim.V_pi, start_index, end_index)
|
496
512
|
|
497
513
|
|
498
|
-
|
499
|
-
|
514
|
+
ax_U = figure_t.scatter(U_ave, U_pi_ave, ax_U, U_color, alpha, xlabel = 'U', ylabel = 'Payoff ' + r'$p_U$', title = 'U - ' + r'$p_U$')
|
515
|
+
ax_V = figure_t.scatter(V_ave, V_pi_ave, ax_V, V_color, alpha, xlabel = 'V', ylabel = 'Payoff ' + r'$p_V$', title = 'V - ' + r'$p_V$')
|
500
516
|
|
501
|
-
return
|
517
|
+
return ax_U, ax_V
|
502
518
|
|
503
519
|
|
piegy/model.py
CHANGED
@@ -41,9 +41,6 @@ PI_DTYPE = 'float64'
|
|
41
41
|
# data type for storing rates in single_test an single_init
|
42
42
|
RATES_DTYPE = 'float64'
|
43
43
|
|
44
|
-
# store e locally, slightly increases speed
|
45
|
-
MATH_E = math.e
|
46
|
-
|
47
44
|
|
48
45
|
class patch:
|
49
46
|
'''
|
@@ -176,8 +173,8 @@ class patch:
|
|
176
173
|
|
177
174
|
for i in range(4):
|
178
175
|
if self.nb[i] != None:
|
179
|
-
U_weight[i] = 1 + pow(
|
180
|
-
V_weight[i] = 1 + pow(
|
176
|
+
U_weight[i] = 1 + pow(math.e, self.w1 * self.nb[i].U_pi)
|
177
|
+
V_weight[i] = 1 + pow(math.e, self.w2 * self.nb[i].V_pi)
|
181
178
|
|
182
179
|
mu1_U = self.mu1 * self.U
|
183
180
|
mu2_V = self.mu2 * self.V
|
@@ -358,14 +355,11 @@ class simulation:
|
|
358
355
|
if print_pct <= 0:
|
359
356
|
raise ValueError('Please use an int > 0 for print_pct or None for not printing progress.')
|
360
357
|
|
361
|
-
|
362
|
-
raise TypeError('Please use an int as seed')
|
363
|
-
if seed < 0:
|
364
|
-
raise ValueError('Please use a non-negative int as seed.')
|
358
|
+
# seed is checked by number
|
365
359
|
|
366
360
|
|
367
361
|
def check_valid_data(self, data_empty, max_record, compress_itv, U, V, U_pi, V_pi):
|
368
|
-
# check whether a set of data is valid
|
362
|
+
# check whether a set of data is valid, used when reading a saved model
|
369
363
|
if type(data_empty) != bool:
|
370
364
|
raise TypeError('data_empty not a bool')
|
371
365
|
|
piegy/test_var.py
CHANGED
@@ -48,6 +48,10 @@ DOTTED_CURVE_TYPE = 'o-'
|
|
48
48
|
# map patch_var name to index in the patch class (in stochastic_model.py)
|
49
49
|
PATCH_VAR_DICT = {'mu1': 0, 'mu2': 1, 'w1': 2, 'w2': 3, 'kappa1': 4, 'kappa2': 5}
|
50
50
|
|
51
|
+
# display name (in latex)
|
52
|
+
PATCH_VAR_DISP = {'mu1': r'$\mu_U$', 'mu2': r'$\mu_V$', 'w1': r'$w_U$', 'w2': r'$w_V$',
|
53
|
+
'kappa1': r'$\kappa_U$', 'kappa2': r'$\kappa_V$'}
|
54
|
+
|
51
55
|
|
52
56
|
|
53
57
|
def test_var1(sim, var, values, dirs, compress_itv = None, predict_runtime = False):
|
@@ -144,7 +148,7 @@ def test_var2(sim, var1, var2, values1, values2, dirs, compress_itv = None, pred
|
|
144
148
|
|
145
149
|
|
146
150
|
|
147
|
-
def var_UV1(var, values, var_dirs, start = 0.95, end = 1.0, U_color = 'purple', V_color = 'green'):
|
151
|
+
def var_UV1(var, values, var_dirs, ax_U = None, ax_V = None, start = 0.95, end = 1.0, U_color = 'purple', V_color = 'green'):
|
148
152
|
'''
|
149
153
|
Plot function for test_var1, plot how var influences U, V population.
|
150
154
|
Make U, V - var curve in two figures, with y-axis being total population at the end of simulations, x-axis being var's values.
|
@@ -153,12 +157,13 @@ def var_UV1(var, values, var_dirs, start = 0.95, end = 1.0, U_color = 'purple',
|
|
153
157
|
- var: str, which variable was tested.
|
154
158
|
- values: 1D list or np.array, which values were tested.
|
155
159
|
- var_dirs: return value of test_var1, a 1D list of directories where all data are stored.
|
160
|
+
- ax_U, ax_V: matplotlib axes to plot on.
|
156
161
|
- start, end: floats, give an interval of time over which to take average and make plot.
|
157
162
|
For example, start = 0.95, end = 1.0 are to take average over the last 5% time of results;
|
158
163
|
essentially plots how var influences equilibrium population.
|
159
164
|
|
160
165
|
Returns:
|
161
|
-
-
|
166
|
+
- ax_U, ax_V: axes for U, V, respectively.
|
162
167
|
'''
|
163
168
|
|
164
169
|
# average value of U, V over the interval. One entry for one value of var
|
@@ -181,25 +186,28 @@ def var_UV1(var, values, var_dirs, start = 0.95, end = 1.0, U_color = 'purple',
|
|
181
186
|
V_ave.append(sum(figure_t.ave_interval_1D(simk.V, start_index, end_index)) / NM)
|
182
187
|
|
183
188
|
#### plot ####
|
189
|
+
if ax_U == None:
|
190
|
+
_, ax_U = plt.subplots()
|
191
|
+
if ax_V == None:
|
192
|
+
_, ax_V = plt.subplots()
|
193
|
+
var_disp = PATCH_VAR_DISP[var]
|
184
194
|
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
ax1.title.set_text(figure_t.gen_title(var + ' - U', start, end))
|
195
|
+
ax_U.set_xlabel(var_disp)
|
196
|
+
ax_U.set_ylabel(r'$U$')
|
197
|
+
ax_U.plot(values, U_ave, DOTTED_CURVE_TYPE, color = U_color)
|
198
|
+
ax_U.set_title(figure_t.gen_title(var_disp + r'$\,-\,U$', start, end))
|
190
199
|
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
ax2.title.set_text(figure_t.gen_title(var + ' - V', start, end))
|
200
|
+
ax_V.set_xlabel(var_disp)
|
201
|
+
ax_V.set_ylabel(r'$V$')
|
202
|
+
ax_V.plot(values, V_ave, DOTTED_CURVE_TYPE, color = V_color)
|
203
|
+
ax_V.set_title(figure_t.gen_title(var_disp + r'$\,-\,V$', start, end))
|
196
204
|
|
197
|
-
return
|
205
|
+
return ax_U, ax_V
|
198
206
|
|
199
207
|
|
200
208
|
|
201
209
|
|
202
|
-
def var_UV2(var1, var2, values1, values2, var_dirs, start = 0.95, end = 1.0, U_color = 'viridis', V_color = 'viridis', rgb_alpha = 1):
|
210
|
+
def var_UV2(var1, var2, values1, values2, var_dirs, ax_U = None, ax_V = None, var1_on_xaxis = True, start = 0.95, end = 1.0, U_color = 'viridis', V_color = 'viridis', rgb_alpha = 1):
|
203
211
|
'''
|
204
212
|
Plot function for test_var2, plot how two variables influence U, V population.
|
205
213
|
Make U, V - var1, var2 curves. y-axis is population, x-axis is var2's values,
|
@@ -211,6 +219,8 @@ def var_UV2(var1, var2, values1, values2, var_dirs, start = 0.95, end = 1.0, U_c
|
|
211
219
|
- values1: 1D list or np.array, values for var1.
|
212
220
|
- values2: 1D list or np.array, values for var2.
|
213
221
|
- var_dirs: return value of test_var2, a 2D list of directories where all data are stored.
|
222
|
+
- ax_U, ax_V: matplotlib axes to plot on.
|
223
|
+
- var1_on_xaxis: whether to put var1 on x-axis. Set to False if not.
|
214
224
|
- start, end: floats, give an interval of time over which to take average and make plot.
|
215
225
|
For example, start = 0.95, end = 1.0 plots the near-end population (equilibrium, if converged).
|
216
226
|
- color: str, what colors to use for different value of var1. Uses Matplotlib color maps.
|
@@ -218,7 +228,7 @@ def var_UV2(var1, var2, values1, values2, var_dirs, start = 0.95, end = 1.0, U_c
|
|
218
228
|
- rgb_alpha: the alpha value for color. Thr curves might have overlaps, recommend set a small alpha value if so.
|
219
229
|
|
220
230
|
Returns:
|
221
|
-
-
|
231
|
+
- ax_U, ax_V: axes for U, V, respectively.
|
222
232
|
'''
|
223
233
|
|
224
234
|
# average value of U, V over the interval. One entry for one values of var1, var2
|
@@ -240,38 +250,59 @@ def var_UV2(var1, var2, values1, values2, var_dirs, start = 0.95, end = 1.0, U_c
|
|
240
250
|
|
241
251
|
U_ave[k1].append(sum(figure_t.ave_interval_1D(simk.U, start_index, end_index)) / NM)
|
242
252
|
V_ave[k1].append(sum(figure_t.ave_interval_1D(simk.V, start_index, end_index)) / NM)
|
243
|
-
|
244
|
-
|
253
|
+
|
254
|
+
U_ave = np.array(U_ave)
|
255
|
+
V_ave = np.array(V_ave)
|
245
256
|
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
257
|
+
#### plot ####
|
258
|
+
if ax_U == None:
|
259
|
+
_, ax_U = plt.subplots()
|
260
|
+
if ax_V == None:
|
261
|
+
_, ax_V = plt.subplots()
|
250
262
|
|
251
|
-
|
252
|
-
|
253
|
-
color_k1 = cmap1(k1 / len(values1))[:3] + (rgb_alpha,)
|
254
|
-
ax1.plot(values2, U_ave[k1], DOTTED_CURVE_TYPE, label = label, color = color_k1)
|
255
|
-
ax1.title.set_text(figure_t.gen_title(var1 + '&' + var2 + ' - U', start, end))
|
256
|
-
ax1.legend(bbox_to_anchor = (1, 1))
|
263
|
+
var1_disp = PATCH_VAR_DISP[var1]
|
264
|
+
var2_disp = PATCH_VAR_DISP[var2]
|
257
265
|
|
258
|
-
fig2, ax2 = plt.subplots()
|
259
|
-
ax2.set_xlabel(var2)
|
260
|
-
ax2.set_ylabel('V')
|
261
|
-
cmap2 = plt.get_cmap(V_color)
|
262
266
|
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
267
|
+
cmap_U = plt.get_cmap(U_color)
|
268
|
+
if var1_on_xaxis:
|
269
|
+
for k in range(len(values2)):
|
270
|
+
label = var2_disp + '=' + str(values2[k])
|
271
|
+
color_k = cmap_U(k / len(values2))[:3] + (rgb_alpha,)
|
272
|
+
ax_U.plot(values1, U_ave[:, k], DOTTED_CURVE_TYPE, label = label, color = color_k)
|
273
|
+
ax_U.set_xlabel(var1_disp)
|
274
|
+
else:
|
275
|
+
for k in range(len(values1)):
|
276
|
+
label = var1_disp + '=' + str(values1[k])
|
277
|
+
color_k = cmap_U(k / len(values1))[:3] + (rgb_alpha,)
|
278
|
+
ax_U.plot(values2, U_ave[k], DOTTED_CURVE_TYPE, label = label, color = color_k)
|
279
|
+
ax_U.set_xlabel(var2_disp)
|
280
|
+
ax_U.set_ylabel(r'$U$')
|
281
|
+
ax_U.set_title(figure_t.gen_title(var1_disp + ',' + var2_disp + r'$\,-\,U$', start, end))
|
282
|
+
ax_U.legend()
|
269
283
|
|
270
|
-
|
284
|
+
cmap_V = plt.get_cmap(V_color)
|
285
|
+
if var1_on_xaxis:
|
286
|
+
for k in range(len(values2)):
|
287
|
+
label = var2_disp + '=' + str(values2[k])
|
288
|
+
color_k = cmap_V(k / len(values2))[:3] + (rgb_alpha,)
|
289
|
+
ax_V.plot(values1, V_ave[:, k], DOTTED_CURVE_TYPE, label = label, color = color_k)
|
290
|
+
ax_V.set_xlabel(var1_disp)
|
291
|
+
else:
|
292
|
+
for k in range(len(values1)):
|
293
|
+
label = var1_disp + '=' + str(values1[k])
|
294
|
+
color_k = cmap_V(k / len(values1))[:3] + (rgb_alpha,)
|
295
|
+
ax_V.plot(values2, V_ave[k], DOTTED_CURVE_TYPE, label = label, color = color_k)
|
296
|
+
ax_V.set_xlabel(var2_disp)
|
297
|
+
ax_V.set_ylabel(r'$V$')
|
298
|
+
ax_V.set_title(figure_t.gen_title(var1_disp + ',' + var2_disp + r'$\,-\,V$', start, end))
|
299
|
+
ax_V.legend()
|
300
|
+
|
301
|
+
return ax_U, ax_V
|
271
302
|
|
272
303
|
|
273
304
|
|
274
|
-
def var_pi1(var, values, var_dirs, start = 0.95, end = 1.0, U_color = 'violet', V_color = 'yellowgreen'):
|
305
|
+
def var_pi1(var, values, var_dirs, ax_U = None, ax_V = None, start = 0.95, end = 1.0, U_color = 'violet', V_color = 'yellowgreen'):
|
275
306
|
'''
|
276
307
|
Plot function for test_var1. Plot influence of var on U, V's payoff.
|
277
308
|
Make U_pi, V_pi - var curves. y-axis is payoff, x-axis is values of var.
|
@@ -280,10 +311,11 @@ def var_pi1(var, values, var_dirs, start = 0.95, end = 1.0, U_color = 'violet',
|
|
280
311
|
- var_dirs: return value of test_var1. A 1D list of directories where all data are stored.
|
281
312
|
- var: str, which variable as tested.
|
282
313
|
- values: 1D list or np.array, what values were used.
|
314
|
+
- ax_U, ax_V: matplotlib axes to plot on.
|
283
315
|
- start, end: floats, define an interval of time over which to calculate average payoff and make plots.
|
284
316
|
|
285
317
|
Returns:
|
286
|
-
-
|
318
|
+
- ax_U, ax_V: axes for U, V, respectively.
|
287
319
|
'''
|
288
320
|
|
289
321
|
# take average value of payoff over an interval of time
|
@@ -308,24 +340,28 @@ def var_pi1(var, values, var_dirs, start = 0.95, end = 1.0, U_color = 'violet',
|
|
308
340
|
del simk
|
309
341
|
|
310
342
|
#### plot ####
|
343
|
+
if ax_U == None:
|
344
|
+
_, ax_U = plt.subplots()
|
345
|
+
if ax_V == None:
|
346
|
+
_, ax_V = plt.subplots()
|
347
|
+
var_disp = PATCH_VAR_DISP[var]
|
311
348
|
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
ax1.title.set_text(figure_t.gen_title(var + ' - U_pi', start, end))
|
349
|
+
ax_U.set_xlabel(var_disp)
|
350
|
+
ax_U.set_ylabel(r'$\pi_U$')
|
351
|
+
ax_U.plot(values, U_ave, DOTTED_CURVE_TYPE, color = U_color)
|
352
|
+
ax_U.set_title(figure_t.gen_title(var_disp + r'$\,-\,\pi_U$', start, end))
|
317
353
|
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
354
|
+
ax_V.set_xlabel(var_disp)
|
355
|
+
ax_V.set_ylabel(r'$\pi_V$')
|
356
|
+
ax_V.plot(values, V_ave, DOTTED_CURVE_TYPE, color = V_color)
|
357
|
+
ax_V.set_title(figure_t.gen_title(var_disp + r'$\,-\,\pi_V$', start, end))
|
358
|
+
|
359
|
+
return ax_U, ax_V
|
323
360
|
|
324
|
-
return fig1, fig2
|
325
361
|
|
326
362
|
|
327
363
|
|
328
|
-
def var_pi2(var1, var2, values1, values2, var_dirs, start = 0.95, end = 1.0, U_color = 'viridis', V_color = 'viridis', rgb_alpha = 1):
|
364
|
+
def var_pi2(var1, var2, values1, values2, var_dirs, ax_U = None, ax_V = None, var1_on_xaxis = True, start = 0.95, end = 1.0, U_color = 'viridis', V_color = 'viridis', rgb_alpha = 1):
|
329
365
|
'''
|
330
366
|
Plot function for test_var2. Plot how var1 and var2 influence payoff.
|
331
367
|
Make U_pi, V_pi - var2 curves. y-axis is payoff, x-axis is values of var2,
|
@@ -335,12 +371,14 @@ def var_pi2(var1, var2, values1, values2, var_dirs, start = 0.95, end = 1.0, U_c
|
|
335
371
|
- var_dirs: return value of test_var2. A 2D list of directories where all data are stored.
|
336
372
|
- var1, var2: str, what variables were tested.
|
337
373
|
- values1, values2: 1D lists or np.array, what values were tested.
|
374
|
+
- ax_U, ax_V: matplotlib axes to plot on.
|
375
|
+
- var1_on_xaxis: whether to put var1 on x-axis. Set to False if not.
|
338
376
|
- start, end: floats, define a time inteval over which to make average and make plots.
|
339
377
|
- color: str, Matplotlib color maps.
|
340
378
|
- rgb_alpha: set alpha value for curves.
|
341
379
|
|
342
380
|
Returns:
|
343
|
-
-
|
381
|
+
- ax_U, ax_V: U, V's payoff figures, respectively.
|
344
382
|
'''
|
345
383
|
|
346
384
|
# take average value of payoff over an interval of time
|
@@ -364,34 +402,54 @@ def var_pi2(var1, var2, values1, values2, var_dirs, start = 0.95, end = 1.0, U_c
|
|
364
402
|
V_ave[k1].append(np.sum(figure_t.ave_interval(simk.V_pi, start_index, end_index)) / NM)
|
365
403
|
|
366
404
|
del simk # manually delete this large object
|
367
|
-
|
368
|
-
#### plot ####
|
369
|
-
|
370
|
-
fig1, ax1 = plt.subplots()
|
371
|
-
ax1.set_xlabel(var2)
|
372
|
-
ax1.set_ylabel('U_pi')
|
373
|
-
cmap1 = plt.get_cmap(U_color)
|
374
405
|
|
375
|
-
|
376
|
-
|
377
|
-
color_k1 = cmap1(k1 / len(values1))[:3] + (rgb_alpha,)
|
378
|
-
ax1.plot(values2, U_ave[k1], DOTTED_CURVE_TYPE, label = label, color = color_k1)
|
379
|
-
ax1.title.set_text(figure_t.gen_title(var1 + '&' + var2 + ' - U_pi', start, end))
|
380
|
-
ax1.legend(bbox_to_anchor = (1, 1))
|
406
|
+
U_ave = np.array(U_ave)
|
407
|
+
V_ave = np.array(V_ave)
|
381
408
|
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
409
|
+
#### plot ####
|
410
|
+
if ax_U == None:
|
411
|
+
_, ax_U = plt.subplots()
|
412
|
+
if ax_V == None:
|
413
|
+
_, ax_V = plt.subplots()
|
386
414
|
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
415
|
+
var1_disp = PATCH_VAR_DISP[var1]
|
416
|
+
var2_disp = PATCH_VAR_DISP[var2]
|
417
|
+
|
418
|
+
cmap_U = plt.get_cmap(U_color)
|
419
|
+
if var1_on_xaxis:
|
420
|
+
for k in range(len(values2)):
|
421
|
+
label = var2_disp + '=' + str(values2[k])
|
422
|
+
color_k = cmap_U(k / len(values2))[:3] + (rgb_alpha,)
|
423
|
+
ax_U.plot(values1, U_ave[:, k], DOTTED_CURVE_TYPE, label = label, color = color_k)
|
424
|
+
ax_U.set_xlabel(var1_disp)
|
425
|
+
else:
|
426
|
+
for k in range(len(values1)):
|
427
|
+
label = var1_disp + '=' + str(values1[k])
|
428
|
+
color_k = cmap_U(k / len(values1))[:3] + (rgb_alpha,)
|
429
|
+
ax_U.plot(values2, U_ave[k], DOTTED_CURVE_TYPE, label = label, color = color_k)
|
430
|
+
ax_U.set_xlabel(var2_disp)
|
431
|
+
ax_U.set_ylabel(r'$\pi_{V}$')
|
432
|
+
ax_U.set_title(figure_t.gen_title(var1_disp + ',' + var2_disp + r'$\,-\,\pi_U$', start, end))
|
433
|
+
ax_U.legend()
|
434
|
+
|
435
|
+
cmap_V = plt.get_cmap(V_color)
|
436
|
+
if var1_on_xaxis:
|
437
|
+
for k in range(len(values2)):
|
438
|
+
label = var2_disp + '=' + str(values2[k])
|
439
|
+
color_k = cmap_V(k / len(values2))[:3] + (rgb_alpha,)
|
440
|
+
ax_V.plot(values1, V_ave[:, k], DOTTED_CURVE_TYPE, label = label, color = color_k)
|
441
|
+
ax_V.set_xlabel(var1_disp)
|
442
|
+
else:
|
443
|
+
for k in range(len(values1)):
|
444
|
+
label = var1_disp + '=' + str(values1[k])
|
445
|
+
color_k = cmap_V(k / len(values1))[:3] + (rgb_alpha,)
|
446
|
+
ax_V.plot(values2, V_ave[k], DOTTED_CURVE_TYPE, label = label, color = color_k)
|
447
|
+
ax_V.set_xlabel(var2_disp)
|
448
|
+
ax_V.set_ylabel(r'$\pi_{U}$')
|
449
|
+
ax_V.set_title(figure_t.gen_title(var1_disp + ',' + var2_disp + r'$\,-\,\pi_V$', start, end))
|
450
|
+
ax_V.legend()
|
393
451
|
|
394
|
-
return
|
452
|
+
return ax_U, ax_V
|
395
453
|
|
396
454
|
|
397
455
|
|
piegy/tools/figure_tools.py
CHANGED
@@ -10,6 +10,7 @@ Functions:
|
|
10
10
|
- scale_interval: scale interval if sim's data was already reduced.
|
11
11
|
- ave_interval: Calculates average value of data over a time interval.
|
12
12
|
- ave_interval_1D: Return in a 1D format.
|
13
|
+
- config_mpl: Configure Matplotlib parameters in a nice format
|
13
14
|
'''
|
14
15
|
|
15
16
|
|
@@ -21,12 +22,13 @@ import seaborn as sns
|
|
21
22
|
# default value is [0.125, 0.11, 0.9, 0.88]
|
22
23
|
|
23
24
|
|
24
|
-
def heatmap(data, cmap = "Greens", annot = False, fmt = '.3g', title = None, text = None):
|
25
|
+
def heatmap(data, ax = None, cmap = "Greens", annot = False, fmt = '.3g', title = None, text = None):
|
25
26
|
'''
|
26
27
|
Helper function for making heatmaps.
|
27
28
|
|
28
29
|
Inputs:
|
29
30
|
data: 1D data for which you want to make a heatmap.
|
31
|
+
ax: matplotlib ax to plot on.
|
30
32
|
cmap: Color of heatmap. Uses matplotlib color maps
|
31
33
|
annot: Whether to show numbers of every block.
|
32
34
|
fmt: Number format for annotations. How many digits you want to keep.
|
@@ -37,23 +39,26 @@ def heatmap(data, cmap = "Greens", annot = False, fmt = '.3g', title = None, tex
|
|
37
39
|
fig: Seaborn heatmap.
|
38
40
|
'''
|
39
41
|
|
40
|
-
|
42
|
+
if ax == None:
|
43
|
+
_, ax = plt.subplots()
|
44
|
+
|
41
45
|
if text != None:
|
42
|
-
ax.text(0.
|
46
|
+
ax.text(0.66, 0.9, text, size = 10, linespacing = 1.5, transform = plt.gcf().transFigure)
|
43
47
|
|
44
|
-
ax = sns.heatmap(data, cmap = cmap, annot = annot, fmt = fmt)
|
45
|
-
ax.
|
48
|
+
ax = sns.heatmap(data, ax = ax, cmap = cmap, annot = annot, fmt = fmt)
|
49
|
+
ax.set_title(title)
|
46
50
|
|
47
|
-
return
|
51
|
+
return ax
|
48
52
|
|
49
53
|
|
50
54
|
|
51
|
-
def bar(data, color = "green", xlabel = None, ylabel = None, title = None, text = None):
|
55
|
+
def bar(data, ax = None, color = "green", xlabel = None, ylabel = None, title = None, text = None):
|
52
56
|
'''
|
53
57
|
Helper Function for making barplots.
|
54
58
|
|
55
59
|
Inputs:
|
56
60
|
data: 2D data to make barplot.
|
61
|
+
ax: matplotlib ax to plot on.
|
57
62
|
color: Uses Matplotlib colors.
|
58
63
|
xlabel, y_label:
|
59
64
|
Label for axes.
|
@@ -67,44 +72,48 @@ def bar(data, color = "green", xlabel = None, ylabel = None, title = None, text
|
|
67
72
|
N = np.array(data).size
|
68
73
|
xaxis = np.array([i for i in range(N)])
|
69
74
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
75
|
+
if ax == None:
|
76
|
+
if N > 60:
|
77
|
+
# make figure larger if has more data points
|
78
|
+
_, ax = plt.subplots(figsize = (min(N * 0.107, 6.4), 4.8))
|
79
|
+
else:
|
80
|
+
_, ax = plt.subplots()
|
74
81
|
|
75
82
|
if text != None:
|
76
|
-
ax.text(0.
|
83
|
+
ax.text(0.66, 0.9, text, size = 10, linespacing = 1.5, transform = plt.gcf().transFigure)
|
77
84
|
|
78
85
|
ax.bar(x = xaxis, height = data, color = color)
|
79
86
|
ax.set_xlabel(xlabel)
|
80
87
|
ax.set_ylabel(ylabel)
|
81
|
-
ax.
|
88
|
+
ax.set_title(title)
|
82
89
|
|
83
|
-
return
|
90
|
+
return ax
|
84
91
|
|
85
92
|
|
86
93
|
|
87
|
-
def scatter(X, Y, color = "orange", alpha = 0.25, xlabel = "x", ylabel = "y", title = None):
|
94
|
+
def scatter(X, Y, ax = None, color = "orange", alpha = 0.25, xlabel = "x", ylabel = "y", title = None):
|
88
95
|
'''
|
89
96
|
Helper function for makeing scatter plots.
|
90
97
|
|
91
98
|
Inputs:
|
92
99
|
X: x-coordinates of points.
|
93
100
|
Y: y-coordinates of points.
|
101
|
+
ax: matplotlib ax to plot on.
|
94
102
|
Note color is Matplotlib colors.
|
95
103
|
|
96
104
|
Returns:
|
97
105
|
fig: A Matplotlib scatter plot.
|
98
106
|
'''
|
99
107
|
|
100
|
-
|
108
|
+
if ax == None:
|
109
|
+
_, ax = plt.subplots(figsize = (7.2, 5.4))
|
101
110
|
ax.scatter(X, Y, color = color, alpha = alpha)
|
102
111
|
|
103
112
|
ax.set_xlabel(xlabel)
|
104
113
|
ax.set_ylabel(ylabel)
|
105
|
-
ax.
|
114
|
+
ax.set_title(title)
|
106
115
|
|
107
|
-
return
|
116
|
+
return ax
|
108
117
|
|
109
118
|
|
110
119
|
|
@@ -121,7 +130,7 @@ def gen_text(ave, std):
|
|
121
130
|
'''
|
122
131
|
Generate text about standard deviation info.
|
123
132
|
'''
|
124
|
-
text = "ave
|
133
|
+
text = "ave=" + str(round(ave, 2)) + ", std=" + str(round(std, 2))
|
125
134
|
return text
|
126
135
|
|
127
136
|
|
@@ -204,3 +213,26 @@ def scale_interval(interval, compress_itv):
|
|
204
213
|
return interval
|
205
214
|
|
206
215
|
|
216
|
+
|
217
|
+
def config_mpl(mpl):
|
218
|
+
'''
|
219
|
+
Configure Matplotlib figures
|
220
|
+
'''
|
221
|
+
mpl.rcParams['savefig.dpi'] = 300
|
222
|
+
|
223
|
+
mpl.rcParams['font.family'] = 'serif'
|
224
|
+
mpl.rcParams['font.serif'] = plt.rcParams['font.serif']
|
225
|
+
mpl.rcParams['lines.linewidth'] = 1.75
|
226
|
+
mpl.rcParams['font.size'] = 11
|
227
|
+
mpl.rcParams['axes.labelsize'] = 12
|
228
|
+
mpl.rcParams['xtick.major.size'] = 10
|
229
|
+
mpl.rcParams['ytick.major.size'] = 9
|
230
|
+
mpl.rcParams['xtick.minor.size'] = 4
|
231
|
+
mpl.rcParams['ytick.minor.size'] = 4
|
232
|
+
|
233
|
+
mpl.rcParams['xtick.major.width'] = 1.5
|
234
|
+
mpl.rcParams['ytick.major.width'] = 1.5
|
235
|
+
mpl.rcParams['xtick.minor.width'] = 1.5
|
236
|
+
mpl.rcParams['ytick.minor.width'] = 1.5
|
237
|
+
|
238
|
+
|
piegy/videos.py
CHANGED
@@ -11,22 +11,21 @@ Private Functions
|
|
11
11
|
- get_max_lim: Get the max lim (interval) over many lims, and then expand it a bit for better accommodation.
|
12
12
|
Essentially takes union of those intervals.
|
13
13
|
- video_lim: Find a large enough xlim and ylim for video.
|
14
|
-
-
|
15
|
-
|
14
|
+
- make_mp4: Put frames together into a mp4.
|
15
|
+
others not documented here.
|
16
16
|
|
17
17
|
'''
|
18
18
|
|
19
19
|
|
20
20
|
from . import figures
|
21
21
|
from .tools import file_tools as file_t
|
22
|
+
from .tools import figure_tools as figure_t
|
22
23
|
|
23
|
-
|
24
|
+
import matplotlib as mpl
|
24
25
|
import matplotlib.pyplot as plt
|
25
26
|
import numpy as np
|
26
27
|
import os
|
27
|
-
|
28
|
-
import re
|
29
|
-
from moviepy import VideoFileClip
|
28
|
+
from moviepy import ImageSequenceClip
|
30
29
|
|
31
30
|
|
32
31
|
# a list of supported figures
|
@@ -163,15 +162,15 @@ def frame_heatmap_lim(sim, func, frames):
|
|
163
162
|
V_list = []
|
164
163
|
|
165
164
|
for i in range(10):
|
166
|
-
|
165
|
+
fig_U, ax_U = plt.subplots()
|
166
|
+
fig_V, ax_V = plt.subplots()
|
167
|
+
ax_U, ax_V = func(sim, ax_U = ax_U, ax_V = ax_V, start = i / 10, end = (i / 10 + 1 / frames))
|
167
168
|
|
168
|
-
|
169
|
-
|
170
|
-
V_ax = V_fig.get_axes()[0]
|
171
|
-
V_list.append(V_ax.collections[0].get_clim())
|
169
|
+
U_list.append(ax_U.collections[0].get_clim())
|
170
|
+
V_list.append(ax_V.collections[0].get_clim())
|
172
171
|
|
173
|
-
plt.close(
|
174
|
-
plt.close(
|
172
|
+
plt.close(fig_U)
|
173
|
+
plt.close(fig_V)
|
175
174
|
|
176
175
|
U_clim = get_max_lim(U_list)
|
177
176
|
V_clim = get_max_lim(V_list)
|
@@ -180,49 +179,29 @@ def frame_heatmap_lim(sim, func, frames):
|
|
180
179
|
|
181
180
|
|
182
181
|
|
183
|
-
def sort_frames(images):
|
184
|
-
'''
|
185
|
-
Put frames in order.
|
186
|
-
|
187
|
-
Inputs:
|
188
|
-
images: A list of dirs (frame names)
|
189
|
-
'''
|
190
|
-
numeric_part, non_numeric_part = re.match(r'(\d+) (\D+)', images).groups()
|
191
|
-
return (int(numeric_part), non_numeric_part)
|
192
|
-
|
193
|
-
|
194
182
|
|
195
|
-
def make_mp4(
|
183
|
+
def make_mp4(video_dir, frame_dir, fps):
|
196
184
|
'''
|
197
|
-
|
198
|
-
|
185
|
+
Read .png from the frames folder and make into a mp4
|
199
186
|
Inputs:
|
200
|
-
|
201
|
-
frame_dirs: where to
|
202
|
-
|
203
|
-
video_name: name of the video.
|
187
|
+
video_dir: where to save the video
|
188
|
+
frame_dirs: where to read frames from
|
189
|
+
fps: frames per second
|
204
190
|
'''
|
205
191
|
|
206
|
-
|
207
|
-
|
208
|
-
|
192
|
+
frame_paths_incomplete = os.listdir(frame_dir)
|
193
|
+
frame_paths_incomplete.sort(key=lambda f: int(''.join(filter(str.isdigit, f))))
|
194
|
+
frame_paths = []
|
195
|
+
for path in frame_paths_incomplete:
|
196
|
+
if (path[-4:] == '.png') and ('frame' in path):
|
197
|
+
frame_paths.append(frame_dir + '/' + path)
|
198
|
+
clip = ImageSequenceClip(frame_paths, fps = fps)
|
199
|
+
clip.write_videofile(video_dir, logger = None)
|
209
200
|
|
210
|
-
image_list = []
|
211
|
-
for img in images:
|
212
|
-
img_path = os.path.join(frame_dirs, img)
|
213
|
-
image_list.append(imageio.imread(img_path))
|
214
|
-
gif_dirs = dirs + '/temp.gif'
|
215
|
-
imageio.mimsave(gif_dirs, image_list, format = 'gif', duration = duration)
|
216
|
-
|
217
|
-
# gif to mp4
|
218
|
-
clip = VideoFileClip(gif_dirs)
|
219
|
-
clip.write_videofile(video_name, logger = None)
|
220
|
-
# delete gif
|
221
|
-
os.remove(gif_dirs)
|
222
201
|
|
223
202
|
|
224
203
|
|
225
|
-
def make_video(sim, func_name = 'UV_heatmap', frames = 100,
|
204
|
+
def make_video(sim, func_name = 'UV_heatmap', frames = 100, fps = 30, U_color = 'Greens', V_color = 'Purples', annot = False, fmt = '.3g', del_frames = False, dirs = 'videos'):
|
226
205
|
'''
|
227
206
|
Make a mp4 video based on simulation results.
|
228
207
|
|
@@ -230,8 +209,7 @@ def make_video(sim, func_name = 'UV_heatmap', frames = 100, speed = 1.25, dpi =
|
|
230
209
|
- sim: a stochastic_model.simulation object, the simulation results.
|
231
210
|
- func_name: what function to use to make the frames. Should be one of the functions in figures.py
|
232
211
|
- frames: how many frames to make. Use more frames for more smooth evolutions.
|
233
|
-
-
|
234
|
-
- dpi: dpi of frames
|
212
|
+
- fps: frames per second.
|
235
213
|
- U_color: color for U's videos. Color maps or regular colors, based on what function you use.
|
236
214
|
- V_color: color for V's videos.
|
237
215
|
- annot: used by heatmaps. Whether to show numbers.
|
@@ -268,7 +246,6 @@ def make_video(sim, func_name = 'UV_heatmap', frames = 100, speed = 1.25, dpi =
|
|
268
246
|
if os.path.exists(V_frame_dirs):
|
269
247
|
file_t.del_dirs(V_frame_dirs)
|
270
248
|
os.makedirs(V_frame_dirs)
|
271
|
-
|
272
249
|
|
273
250
|
#### for loop ####
|
274
251
|
|
@@ -277,30 +254,31 @@ def make_video(sim, func_name = 'UV_heatmap', frames = 100, speed = 1.25, dpi =
|
|
277
254
|
print('making frames', round(i / frames * 100), '%', end = '\r')
|
278
255
|
current_progress += one_progress
|
279
256
|
|
257
|
+
fig_U, ax_U = plt.subplots(figsize = (6.4, 4.8))#, constrained_layout = True)
|
258
|
+
fig_V, ax_V = plt.subplots(figsize = (6.4, 4.8))#, constrained_layout = True)
|
259
|
+
|
280
260
|
if 'heatmap' in func_name:
|
281
|
-
|
261
|
+
ax_U, ax_V = func(sim, ax_U = ax_U, ax_V = ax_V, U_color = U_color, V_color = V_color, start = i / frames, end = (i + 1) / frames, annot = annot, fmt = fmt)
|
282
262
|
else:
|
283
|
-
|
284
|
-
U_ax = U_fig.get_axes()[0]
|
285
|
-
V_ax = V_fig.get_axes()[0]
|
263
|
+
ax_U, ax_V = func(sim, ax_U = ax_U, ax_V = ax_V, U_color = U_color, V_color = V_color, start = i / frames, end = (i + 1) / frames)
|
286
264
|
|
287
265
|
if 'heatmap' in func_name:
|
288
|
-
|
289
|
-
|
266
|
+
ax_U.collections[0].set_clim(U_clim)
|
267
|
+
ax_V.collections[0].set_clim(V_clim)
|
290
268
|
else:
|
291
269
|
# make sure y axis not changing if not heatmap and not UV_pi
|
292
|
-
|
293
|
-
|
270
|
+
ax_U.set_ylim(U_ylim)
|
271
|
+
ax_V.set_ylim(V_ylim)
|
294
272
|
if ('hist' in func_name) or (func_name == 'UV_pi'):
|
295
273
|
# need to set xlim as well for UV_pi and histograms
|
296
|
-
|
297
|
-
|
274
|
+
ax_V.set_xlim(U_xlim)
|
275
|
+
ax_V.set_xlim(V_xlim)
|
298
276
|
|
299
|
-
|
300
|
-
|
277
|
+
fig_U.savefig(U_frame_dirs + '/' + 'U_frame_' + str(i) + '.png', pad_inches = 0.25)
|
278
|
+
fig_V.savefig(V_frame_dirs + '/' + 'V_frame_' + str(i) + '.png', pad_inches = 0.25)
|
301
279
|
|
302
|
-
plt.close(
|
303
|
-
plt.close(
|
280
|
+
plt.close(fig_U)
|
281
|
+
plt.close(fig_V)
|
304
282
|
|
305
283
|
#### for loop ends ####
|
306
284
|
|
@@ -308,8 +286,8 @@ def make_video(sim, func_name = 'UV_heatmap', frames = 100, speed = 1.25, dpi =
|
|
308
286
|
print('making mp4... ', end = '\r')
|
309
287
|
|
310
288
|
# make videos based on frames
|
311
|
-
make_mp4(dirs
|
312
|
-
make_mp4(dirs
|
289
|
+
make_mp4(dirs + '/U-' + func_name + '.mp4', U_frame_dirs, fps)
|
290
|
+
make_mp4(dirs + '/V-' + func_name + '.mp4', V_frame_dirs, fps)
|
313
291
|
|
314
292
|
if del_frames:
|
315
293
|
file_t.del_dirs(U_frame_dirs)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: piegy
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.1.1
|
4
4
|
Summary: Payoff-Driven Stochastic Spatial Model for Evolutionary Game Theory
|
5
5
|
Author-email: Chenning Xu <cxu7@caltech.edu>
|
6
6
|
License: BSD 3-Clause License
|
@@ -49,7 +49,6 @@ Description-Content-Type: text/markdown
|
|
49
49
|
License-File: LICENSE.txt
|
50
50
|
Requires-Dist: numpy
|
51
51
|
Requires-Dist: matplotlib
|
52
|
-
Requires-Dist: imageio>=2.37.0
|
53
52
|
Requires-Dist: moviepy>=2.1.1
|
54
53
|
Requires-Dist: seaborn>=0.13.2
|
55
54
|
Dynamic: license-file
|
@@ -62,20 +61,22 @@ Provides a stochastic spatial model for simulating the interaction and evolution
|
|
62
61
|
|
63
62
|
## Installation
|
64
63
|
|
64
|
+
To install *piegy*, run the following in terminal:
|
65
|
+
|
65
66
|
```bash
|
66
67
|
pip install piegy
|
67
68
|
```
|
68
69
|
|
69
70
|
## Documentation and Source
|
70
71
|
|
71
|
-
See source code at: [
|
72
|
-
The *piegy* documentation at: [piegy
|
72
|
+
See source code at: [piegy GitHub repository](https://github.com/Chenning04/piegy.git).
|
73
|
+
The *piegy* documentation at: [piegy Documentation](https://piegy.readthedocs.io/en/).
|
73
74
|
|
74
75
|
## How the Model Works
|
75
76
|
|
76
|
-
Our model can be summarized as "classical game theory endowed with
|
77
|
+
Our model can be summarized as "classical evolutionary game theory endowed with spatial structure and payoff-driven migration rules". Consider two species, predators and preys (denoted by *U* and *V*), in a rectangular region. We divide the region into N by M patches and simulate their interaction within a patch by classical game theory (i.e., payoff matrices and carrying capacity). Interactions across patches are simulated by payoff-driven migration rules. An individual migrates to a neighboring patch with probability weighted by payoff in the neighbors.
|
77
78
|
|
78
|
-
We use the Gillepie algorithm as the fundamental event-selection algorithm. At each time step, one event is selected and let happen; and step
|
79
|
+
We use the Gillepie algorithm as the fundamental event-selection algorithm. At each time step, one event is selected and let happen; and the step size is continuous, dependent on the current state in the space. Data are recorded every some specified time interval.
|
79
80
|
|
80
81
|
## Analytic Tools
|
81
82
|
|
@@ -95,10 +96,11 @@ dynamics = figures.UV_dyna(sim)
|
|
95
96
|
U_hmap, V_hmap = figures.UV_heatmap(sim)
|
96
97
|
```
|
97
98
|
|
98
|
-
The figures reveal the population dynamics and steady state distribution.
|
99
|
+
The figures reveal the population dynamics and steady state population distribution.
|
99
100
|
|
100
101
|
|
101
102
|
## Acknowledgments
|
102
103
|
|
103
104
|
- Thanks Professor Daniel Cooney at University of Illinois Urbana-Champaign. This package is developed alongside a project with Prof. Cooney and received enormous help from him.
|
104
105
|
- Special thanks to the open-source community for making this package possible.
|
106
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
piegy/__init__.py,sha256=Lrh6NegSvo6LOCXg_tBTu804eicnHpQY2zmE0FchjKE,3241
|
2
|
+
piegy/__version__.py,sha256=8IfclnXlmVE5p-odcoFI_9v7RIOmz2Cxd8Dvx1dMjNc,526
|
3
|
+
piegy/analysis.py,sha256=1cF06igQMGJGVjLiyhtgepGk8fYhzvL0orI48tOK1qY,8713
|
4
|
+
piegy/data_tools.py,sha256=lNFOX4H0o_WfRSNQoC9QGCK66-IdrZ0zCnz12N-Ael4,3599
|
5
|
+
piegy/figures.py,sha256=xR4NKuHc-7E3ld6NjyAAVcJG8CtIoKoM4mqd8qPOXsg,19063
|
6
|
+
piegy/model.py,sha256=NkP_Apnun3MhATSihR4_irnA-8p4FW879xQjCXVEPMA,45502
|
7
|
+
piegy/test_var.py,sha256=PDtCCou-kFXumEe2EdAQNKJohwHH58ifLSsp5xQraVI,23532
|
8
|
+
piegy/videos.py,sha256=vPl1aTIOaWxIUsxX5yL3JPiuf-Um0bPo7qYIHZP0bo0,10143
|
9
|
+
piegy/tools/__init__.py,sha256=eYOl_HJHDonYexfrmKh3koOlxvtSo46vH6jHvCEEB4k,300
|
10
|
+
piegy/tools/figure_tools.py,sha256=tAI5sBMsxN_1BN5_G_3UoMcDeYTj2DXr8l4HpPl9FSs,6961
|
11
|
+
piegy/tools/file_tools.py,sha256=ncxFWeHfIE-GYLQlOrahFlhBgqPyuY3R5_93fpQeCEs,630
|
12
|
+
piegy-1.1.1.dist-info/licenses/LICENSE.txt,sha256=wfzEht_CxOcfGGmg3f3at4mWJb9rTBjA51mXLl_3O3g,1498
|
13
|
+
piegy-1.1.1.dist-info/METADATA,sha256=qawzMEDrKZITzujlqMf_9WJoEklAGFYcOw3I2u8plbQ,5097
|
14
|
+
piegy-1.1.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
15
|
+
piegy-1.1.1.dist-info/top_level.txt,sha256=k4QLYL8PqdqDuy95-4NZD_FVLqJDsmq67tpKkBn4vMw,6
|
16
|
+
piegy-1.1.1.dist-info/RECORD,,
|
piegy-1.0.0.dist-info/RECORD
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
piegy/__init__.py,sha256=Lrh6NegSvo6LOCXg_tBTu804eicnHpQY2zmE0FchjKE,3241
|
2
|
-
piegy/__version__.py,sha256=H58EUm6wBWYw2Q4gXk5PznfRrEry4c4zk7c--daUx_8,365
|
3
|
-
piegy/analysis.py,sha256=1cF06igQMGJGVjLiyhtgepGk8fYhzvL0orI48tOK1qY,8713
|
4
|
-
piegy/data_tools.py,sha256=dXESWglAXN4q79ZG8wtpZftJoiiaOJFU7NSaip1ZTq0,3518
|
5
|
-
piegy/figures.py,sha256=46Vg6AsWswF-juGbyndaRaChrdVuzPbpRQQd9grTWfk,17842
|
6
|
-
piegy/model.py,sha256=2Y49NDzdtog9effo9Lr_-psu5NMBF3iH9BeE8zhCHZ8,45700
|
7
|
-
piegy/test_var.py,sha256=fk_e0Hko6zNfsOx-SMnnEcsgeu6fx0rQcdfuXGceY7U,20892
|
8
|
-
piegy/videos.py,sha256=vW0F9WYDvPVJM0fHM_0Vi9Y8ZSVfJBcuCLJ2lLXeZ2U,10410
|
9
|
-
piegy/tools/__init__.py,sha256=eYOl_HJHDonYexfrmKh3koOlxvtSo46vH6jHvCEEB4k,300
|
10
|
-
piegy/tools/figure_tools.py,sha256=qhuMPZn2krEzjhjmAd6ac9QVBeCWUkSdCGOz7RASAhA,5931
|
11
|
-
piegy/tools/file_tools.py,sha256=ncxFWeHfIE-GYLQlOrahFlhBgqPyuY3R5_93fpQeCEs,630
|
12
|
-
piegy-1.0.0.dist-info/licenses/LICENSE.txt,sha256=wfzEht_CxOcfGGmg3f3at4mWJb9rTBjA51mXLl_3O3g,1498
|
13
|
-
piegy-1.0.0.dist-info/METADATA,sha256=hn5JGkA5jBMN2toZ0xPdJ-0munvYBE-BzcOMKWb-d-g,5035
|
14
|
-
piegy-1.0.0.dist-info/WHEEL,sha256=DnLRTWE75wApRYVsjgc6wsVswC54sMSJhAEd4xhDpBk,91
|
15
|
-
piegy-1.0.0.dist-info/top_level.txt,sha256=k4QLYL8PqdqDuy95-4NZD_FVLqJDsmq67tpKkBn4vMw,6
|
16
|
-
piegy-1.0.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|