-
Notifications
You must be signed in to change notification settings - Fork 4
Open
Description
I discussed with @percyfal some ideas of how to plot a GNN equivalent when we don't have a set of defined subpopulations. One possibility is to look at the nearest neighbours and to summarize their x/y locations, perhaps using an average location and some sort of variance.
Here's a SLiM script we could use for testing (try running it in the SLiM GUI: needs the world_map_540x217.png file from the SLiM docs):
// Keywords: continuous space, continuous spatial landscape, spatial map, reprising boundaries
initialize() {
initializeSLiMOptions(dimensionality="xy");
initializeTreeSeq();
initializeMutationRate(1e-7);
initializeMutationType("m1", 0.5, "f", 0.0);
initializeGenomicElementType("g1", m1, 1.0);
initializeGenomicElement(g1, 0, 99999);
initializeRecombinationRate(1e-8);
// spatial competition
initializeInteractionType(1, "xy", reciprocal=T, maxDistance=30.0);
i1.setInteractionFunction("n", 5.0, 10.0);
// spatial mate choice
initializeInteractionType(2, "xy", reciprocal=T, maxDistance=30.0);
i2.setInteractionFunction("n", 1.0, 10.0);
}
1 late() {
sim.addSubpop("p1", 1000);
p1.setSpatialBounds(c(0.0, 0.0, 539.0, 216.0));
// this file is in the recipe archive at http://benhaller.com/slim/SLiM_Recipes.zip
mapImage = Image("~/Downloads/SLiM_Recipes/world_map_540x217.png");
p1.defineSpatialMap("world", "xy", 1.0 - mapImage.floatK,
valueRange=c(0.0, 1.0), colors=c("#0000CC", "#55FF22"));
// start near a specific map location
for (ind in p1.individuals) {
ind.x = rnorm(1, 300.0, 1.0);
ind.y = rnorm(1, 100.0, 1.0);
}
}
1: late() {
i1.evaluate();
inds = sim.subpopulations.individuals;
competition = i1.totalOfNeighborStrengths(inds) / size(inds);
competition = pmin(competition, 0.99);
inds.fitnessScaling = 1.0 - competition;
}
first() {
i2.evaluate();
}
mateChoice() {
return i2.strength(individual);
}
modifyChild() {
do pos = parent1.spatialPosition + rnorm(2, 0, 0.5);
while (!p1.pointInBounds(pos));
// prevent dispersal into water
if (p1.spatialMapValue("world", pos) == 0.0)
return F;
child.setSpatialPosition(pos);
return T;
}
3000 late() {
sim.treeSeqOutput("~/Downloads/SLiM_Recipes/spatial.trees");
}
And here's a rough, non-efficient, way of plotting out the spatial GNN (lots could be improved, and I think there's a bug, but putting it down here for reference):
import tskit
import numpy as np
import matplotlib.pyplot as plt
ts = tskit.load("/Users/Yan/Downloads/SLiM_Recipes/spatial.trees")
GNN_x = np.zeros(ts.num_samples)
GNN_y = np.zeros(ts.num_samples)
for u in ts.samples():
loc = ts.individual(ts.node(u).individual).location
GNN_x[u] = loc[0]
GNN_y[u] = loc[1]
GNN_u = np.zeros(ts.num_samples)
GNN_v = np.zeros(ts.num_samples)
for tree in ts.trees():
for u in ts.samples():
x = 0
y = 0
n = 0
focal_node = tree.parent(u)
for s in tree.samples(focal_node):
if s != u:
loc = ts.individual(ts.node(s).individual).location
n += 1
x += GNN_x[u] - loc[0]
y += GNN_y[u] - loc[1]
GNN_u[u] += x * tree.span
GNN_v[u] += y * tree.span
GNN_u /= ts.sequence_length
GNN_v /= ts.sequence_length
fig, ax = plt.subplots(figsize=(20, 15))
q = ax.quiver(GNN_x, GNN_y, GNN_u, GNN_v, units='xy')
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels