Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect location order returned by shell_layout #149

Closed
kuchenluege opened this issue Jul 14, 2021 · 1 comment
Closed

Incorrect location order returned by shell_layout #149

kuchenluege opened this issue Jul 14, 2021 · 1 comment

Comments

@kuchenluege
Copy link

using LightGraphs
using GraphPlot

g = SimpleGraph(6)
add_edge!(g, 1, 3)
add_edge!(g, 1, 5)
add_edge!(g, 3, 5)

nlist = Array{Vector{Int}}(undef, 2)
nlist[1] = [1, 3, 5]
nlist[2] = [2, 4, 6]

locs_x, locs_y = shell_layout(g, nlist)

gplot(g, locs_x, locs_y, nodelabel=1:6)

One would expect the layout of the resulting plot to be a inner shell of connected nodes [1, 3, 5], and an outer shell of unconnected nodes [2, 4, 6]. However, the output is:

image

This is due to an error in the shell_layout function that is returning the x and y locations in the wrong order:

function shell_layout(g, nlist::Union{Nothing, Vector{Vector{Int}}} = nothing)
    if nv(g) == 1
        return [0.0], [0.0]
    end
    if nlist == nothing
        nlist = [collect(1:nv(g))]
    end
    radius = 0.0
    if length(nlist[1]) > 1
        radius = 1.0
    end
    locs_x = Float64[] # <--
    locs_y = Float64[] # <--
    for nodes in nlist
        # Discard the extra angle since it matches 0 radians.
        θ = range(0, stop=2pi, length=length(nodes)+1)[1:end-1]
        append!(locs_x, radius*cos.(θ)) # <--
        append!(locs_y, radius*sin.(θ)) # <--
        radius += 1.0
    end
    return locs_x, locs_y
end

The x and y locations are returned in the order of appearance in each node [1, 3, 5, 2, 4, 6] instead of numerical order [1, 2, 3, 4, 5, 6]. Changing the 4 marked lines will fix the error:

function shell_layout(g, nlist::Union{Nothing, Vector{Vector{Int}}} = nothing)
    if nv(g) == 1
        return [0.0], [0.0]
    end
    if nlist == nothing
        nlist = [collect(1:nv(g))]
    end
    radius = 0.0
    if length(nlist[1]) > 1
        radius = 1.0
    end
    locs_x = zeros(size(g, 1)) # <--
    locs_y = zeros(size(g, 1)) # <--
    for nodes in nlist
        # Discard the extra angle since it matches 0 radians.
        θ = range(0, stop=2pi, length=length(nodes)+1)[1:end-1]
        locs_x[nodes] = radius*cos.(θ) # <--
        locs_y[nodes] = radius*sin.(θ) # <--
        radius += 1.0
    end
    return locs_x, locs_y
end
hdavid16 added a commit to hdavid16/GraphPlot.jl that referenced this issue Jul 27, 2022
hdavid16 added a commit to hdavid16/GraphPlot.jl that referenced this issue Aug 5, 2022
@hdavid16
Copy link
Contributor

hdavid16 commented Apr 3, 2023

@kuchenluege , this is fixed in PR #186. However Shell layouts work well in GraphMakie:

using Graphs, GraphMakie
using GraphMakie:Shell

g = SimpleGraph(6)
add_edge!(g, 1, 3)
add_edge!(g, 1, 5)
add_edge!(g, 3, 5)

nlist = Array{Vector{Int}}(undef, 2)
nlist[1] = [1, 3, 5]
nlist[2] = [2, 4, 6]

graphplot(g,layout=Shell(;nlist),nlabels=repr.(vertices(g)))

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants