Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# NetworkLayout Release Notes

## v0.4.11 Changelog
- New `Egocentric` layout: stress majorization centered on a focal vertex, placing every node on a ring at its graph distance from the focus (Brandes & Pich 2011).
- Fixes two bugs in the iteration scheme:
- The layout iterator returned the second-to-last layout; now it returns the final positions after full iteration.
- Iterative layouts computed `iterations` layouts, including the initial guess. Now `iterations` describes the number of actual *iterations*, and the layout iterator returns at most `iterations + 1` layouts.
59 changes: 57 additions & 2 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,60 @@ nothing #hide
```
![stress animation](stress_animation.mp4)

## Egocentric Layout
```@docs
Egocentric
```
### Example
An egocentric layout puts one vertex at the centre and arranges everyone else on
concentric rings, one per geodesic step away from it. The angles still come from
a regular stress layout, so vertices that are close in the network stay close on
their ring.
```@example layouts
set_theme!(size=(800, 400)) #hide
g = watts_strogatz(120, 4, 0.3; seed=2)
focus = 1
layout = Egocentric(; focus)

node_color = [i == focus ? :tomato : :black for i in 1:nv(g)]
node_size = [i == focus ? 20 : 6 for i in 1:nv(g)]
f, ax, p = graphplot(g; layout, node_color, node_size, edge_width=0.5)
for r in 1:maximum(gdistances(g, focus))
arc!(ax, Point2f(0), r, -pi, pi; color=(:gray, 0.5), linewidth=0.5)
end
hidedecorations!(ax); hidespines!(ax); ax.aspect = DataAspect(); f
```

### Bounding the extent with `maxdist`
Since the radius of a vertex equals its graph distance, a few remote vertices can
dominate the frame. `maxdist` keeps the rings up to that distance intact and
compresses everything beyond it onto a narrow band, keeping the angles:
```@example layouts
layout = Egocentric(; focus, maxdist=4)
f, ax, p = graphplot(g; layout, node_color, node_size, edge_width=0.5)
for r in 1:4
arc!(ax, Point2f(0), r, -pi, pi; color=(:gray, 0.5), linewidth=0.5)
end
hidedecorations!(ax); hidespines!(ax); ax.aspect = DataAspect(); f
```
Passing a number instead of a function, e.g. `compress=1`, collapses everything
past `maxdist` onto a single outer ring, which is a compact way to show "further
away than `maxdist`" without saying how much further.

### Iterator Example
```@example layouts
layout = Egocentric(; focus)
f, ax, p = graphplot(g; layout, node_color, node_size, edge_width=0.5)
hidedecorations!(ax); hidespines!(ax); ax.aspect = DataAspect() #hide
iterator = LayoutIterator(layout, g)
record(f, "egocentric_animation.mp4", iterator; framerate = 10) do pos
p[:node_pos][] = pos
autolimits!(ax)
end
nothing #hide
```
![egocentric animation](egocentric_animation.mp4)

## Shell/Circular Layout
```@docs
Shell
Expand Down Expand Up @@ -195,8 +249,9 @@ f #hide

## `pin` Positions in Interative Layouts
Sometimes it is desired to fix the positions of a few nodes while arranging the rest "naturally" around them.
The iterative layouts [`Stress`](@ref), [`Spring`](@ref) and [`SFDP`](@ref) allow to pin
nodes to certain positions, i.e. those node will stay fixed during the iteration.
The iterative layouts [`Stress`](@ref), [`Spring`](@ref), [`SFDP`](@ref) and
[`Egocentric`](@ref) allow to pin nodes to certain positions, i.e. those nodes will
stay fixed during the iteration.
```@example layouts
g = SimpleGraph(vcat(hcat(zeros(4,4), ones(4,4)), hcat(ones(4,4), zeros(4,4))))
nothing #hide
Expand Down
1 change: 1 addition & 0 deletions src/NetworkLayout.jl
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ include("sfdp.jl")
include("buchheim.jl")
include("spring.jl")
include("stress.jl")
include("egocentric.jl")
include("spectral.jl")
include("shell.jl")
include("squaregrid.jl")
Expand Down
Loading
Loading