Skip to content

Instantly share code, notes, and snippets.

@tpoisot
Created August 2, 2018 18:26
Show Gist options
  • Save tpoisot/29ae5c110acff5bfdf69568331493175 to your computer and use it in GitHub Desktop.
Save tpoisot/29ae5c110acff5bfdf69568331493175 to your computer and use it in GitHub Desktop.
force directed layout
# http://faculty.washington.edu/joelross/courses/archive/s13/cs261/lab/k/
using EcologicalNetworks
using Plots
N = simplify(nz_stream_foodweb()[1])
mutable struct NodePosition
x::Float64
y::Float64
vx::Float64
vy::Float64
end
function stop!(p::NodePosition)
p.vx = 0.0
p.vy = 0.0
end
function repel!(pos, s1, s2, fr)
δx = pos[s1].x - pos[s2].x
δy = pos[s1].y - pos[s2].y
Δ = sqrt(δx^2.0+δy^2.0)
pos[s1].vx = pos[s1].vx + δx/Δ*fr(Δ)
pos[s1].vy = pos[s1].vy + δy/Δ*fr(Δ)
end
function attract!(pos, s1, s2, fa)
δx = pos[s1].x - pos[s2].x
δy = pos[s1].y - pos[s2].y
Δ = sqrt(δx^2.0+δy^2.0)
pos[s1].vx = pos[s1].vx - δx/Δ*fa(Δ)
pos[s1].vy = pos[s1].vy - δy/Δ*fa(Δ)
pos[s2].vx = pos[s2].vx + δx/Δ*fa(Δ)
pos[s2].vy = pos[s2].vy + δy/Δ*fa(Δ)
end
function update!(pos, s)
Δ = sqrt(pos[s].vx^2.0+pos[s].vy^2.0)
pos[s].x += pos[s].vx/Δ*min(Δ, 0.01)
pos[s].y += pos[s].vy/Δ*min(Δ, 0.01)
stop!(pos[s])
end
function lay!(N, pos; k=0.2)
fa(x) = (x*x)/k
fr(x) = (k*k)/x
for (i, s1) in enumerate(species(N))
stop!(pos[s1])
for (j, s2) in enumerate(species(N))
if j != i
repel!(pos, s1, s2, fr)
end
end
end
for int in interactions(N)
s1, s2 = int.from, int.to
attract!(pos, s1, s2, fa)
end
for (i,s) in enumerate(species(N))
update!(pos, s)
end
end
init(N) = Dict([s => NodePosition(rand(), rand(), 0.0, 0.0) for s in species(N)])
function mkplot(N, pos, d; size=(600,600))
x = [pos[s].x for s in species(N)]
y = [pos[s].y for s in species(N)]
z = [d[s] for s in species(N)]
pl = scatter(x, y, ms=0, leg=false, frame=:none, size=size)
for int in interactions(N)
s1, s2 = int.from, int.to
plot!(pl, [pos[s1].x, pos[s2].x], [pos[s1].y, pos[s2].y], c=:lightgrey, lw=1, lab="")
end
scatter!(pl, x, y, marker_z = z, c=:viridis, lab="Degree", ms=5)
pl
end
N = simplify(nz_stream_foodweb()[2])
pos = init(N)
[lay!(N, pos; k=0.2) for i in 1:1000];
mkplot(N, pos, trophic_level(N))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment