From b0efb93ba59652d14ec67a2e274d423a1cff1ff8 Mon Sep 17 00:00:00 2001 From: Simon Schoelly Date: Sun, 12 Aug 2018 01:43:08 +0200 Subject: [PATCH 1/8] fix for function gplot (#63) --- REQUIRE | 3 ++- src/graphio.jl | 8 +++++--- src/layout.jl | 9 ++++++--- src/lines.jl | 48 ++++++++++++++++++++++++------------------------ src/plot.jl | 26 +++++++++++++------------- test/runtests.jl | 6 ++++-- 6 files changed, 54 insertions(+), 46 deletions(-) diff --git a/REQUIRE b/REQUIRE index 8d752f0..9295a33 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1,4 +1,5 @@ -julia 0.6 +julia 0.7 +Arpack Colors ColorTypes Compose diff --git a/src/graphio.jl b/src/graphio.jl index 24f2966..4c99dee 100644 --- a/src/graphio.jl +++ b/src/graphio.jl @@ -1,3 +1,5 @@ +using DelimitedFiles: readdlm + """ read some famous graphs @@ -21,9 +23,9 @@ end """read graph from in edgelist format""" function readedgelist(filename; is_directed::Bool=false, start_index::Int=0, delim::Char=' ') es = readdlm(filename, delim, Int) - es = unique(es, 1) + es = unique(es, dims=1) if start_index == 0 - es = es + 1 + es = es .+ 1 end N = maximum(es) if is_directed @@ -38,7 +40,7 @@ function readedgelist(filename; is_directed::Bool=false, start_index::Int=0, del es[i,1], es[i,2] = es[i,2], es[i,1] end end - es = unique(es, 1) + es = unique(es, dims=1) g = Graph(N) for i=1:size(es,1) add_edge!(g, es[i,1], es[i,2]) diff --git a/src/layout.jl b/src/layout.jl index 2777424..ba92cd9 100644 --- a/src/layout.jl +++ b/src/layout.jl @@ -1,3 +1,6 @@ +using SparseArrays: SparseMatrixCSC +using Arpack: eigs + """ Position nodes uniformly at random in the unit square. For every node, a position is generated by choosing each of dim @@ -96,11 +99,11 @@ julia> locs_x, locs_y = spring_layout(g) function spring_layout(G, locs_x=2*rand(_nv(G)).-1.0, locs_y=2*rand(_nv(G)).-1.0; C=2.0, MAXITER=100, INITTEMP=2.0) #size(adj_matrix, 1) != size(adj_matrix, 2) && error("Adj. matrix must be square.") - const N = _nv(G) + N = _nv(G) adj_matrix = _adjacency_matrix(G) # The optimal distance bewteen vertices - const K = C * sqrt(4.0 / N) + K = C * sqrt(4.0 / N) # Store forces and apply at end of iteration all at once force_x = zeros(N) @@ -183,7 +186,7 @@ julia> nlist[2] = [6:num_vertiecs(g)] julia> locs_x, locs_y = shell_layout(g, nlist) ``` """ -function shell_layout(G, nlist::Union{Void, Vector{Vector{Int}}} = nothing) +function shell_layout(G, nlist::Union{Nothing, Vector{Vector{Int}}} = nothing) if _nv(G) == 1 return [0.0], [0.0] end diff --git a/src/lines.jl b/src/lines.jl index a85a437..78bb8dc 100644 --- a/src/lines.jl +++ b/src/lines.jl @@ -1,16 +1,16 @@ """ Return lines and arrow heads """ -function graphline{T<:Real}(g, locs_x, locs_y, nodesize::Vector{T}, arrowlength, angleoffset) - lines = Array{Vector{Tuple{Float64,Float64}}}(_ne(g)) - arrows = Array{Vector{Tuple{Float64,Float64}}}(_ne(g)) +function graphline(g, locs_x, locs_y, nodesize::Vector{T}, arrowlength, angleoffset) where {T<:Real} + lines = Array{Vector{Tuple{Float64,Float64}}}(undef, _ne(g)) + arrows = Array{Vector{Tuple{Float64,Float64}}}(undef, _ne(g)) for (e_idx, e) in enumerate(_edges(g)) i = _src_index(e, g) j = _dst_index(e, g) Δx = locs_x[j] - locs_x[i] Δy = locs_y[j] - locs_y[i] d = sqrt(Δx^2 + Δy^2) - θ = atan2(Δy,Δx) + θ = atan(Δy,Δx) startx = locs_x[i] + nodesize[i]*cos(θ) starty = locs_y[i] + nodesize[i]*sin(θ) endx = locs_x[i] + (d-nodesize[j])*1.00*cos(θ) @@ -22,16 +22,16 @@ function graphline{T<:Real}(g, locs_x, locs_y, nodesize::Vector{T}, arrowlength, lines, arrows end -function graphline{T<:Real}(g, locs_x, locs_y, nodesize::T, arrowlength, angleoffset) - lines = Array{Vector{Tuple{Float64,Float64}}}(_ne(g)) - arrows = Array{Vector{Tuple{Float64,Float64}}}(_ne(g)) +function graphline(g, locs_x, locs_y, nodesize::T, arrowlength, angleoffset) where {T<:Real} + lines = Array{Vector{Tuple{Float64,Float64}}}(undef, _ne(g)) + arrows = Array{Vector{Tuple{Float64,Float64}}}(undef, _ne(g)) for (e_idx, e) in enumerate(_edges(g)) i = _src_index(e, g) j = _dst_index(e, g) Δx = locs_x[j] - locs_x[i] Δy = locs_y[j] - locs_y[i] d = sqrt(Δx^2 + Δy^2) - θ = atan2(Δy,Δx) + θ = atan(Δy,Δx) startx = locs_x[i] + nodesize*cos(θ) starty = locs_y[i] + nodesize*sin(θ) endx = locs_x[i] + (d-nodesize)*1.00*cos(θ) @@ -43,15 +43,15 @@ function graphline{T<:Real}(g, locs_x, locs_y, nodesize::T, arrowlength, angleof lines, arrows end -function graphline{T<:Real}(g, locs_x, locs_y, nodesize::Vector{T}) - lines = Array{Vector{Tuple{Float64,Float64}}}(_ne(g)) +function graphline(g, locs_x, locs_y, nodesize::Vector{T}) where {T<:Real} + lines = Array{Vector{Tuple{Float64,Float64}}}(undef, _ne(g)) for (e_idx, e) in enumerate(_edges(g)) i = _src_index(e, g) j = _dst_index(e, g) Δx = locs_x[j] - locs_x[i] Δy = locs_y[j] - locs_y[i] d = sqrt(Δx^2 + Δy^2) - θ = atan2(Δy,Δx) + θ = atan(Δy,Δx) startx = locs_x[i] + nodesize[i]*cos(θ) starty = locs_y[i] + nodesize[i]*sin(θ) endx = locs_x[i] + (d-nodesize[j])*1.00*cos(θ) @@ -61,15 +61,15 @@ function graphline{T<:Real}(g, locs_x, locs_y, nodesize::Vector{T}) lines end -function graphline{T<:Real}(g, locs_x, locs_y, nodesize::T) - lines = Array{Vector{Tuple{Float64,Float64}}}(_ne(g)) +function graphline(g, locs_x, locs_y, nodesize::T) where {T<:Real} + lines = Array{Vector{Tuple{Float64,Float64}}}(undef, _ne(g)) for (e_idx, e) in enumerate(_edges(g)) i = _src_index(e, g) j = _dst_index(e, g) Δx = locs_x[j] - locs_x[i] Δy = locs_y[j] - locs_y[i] d = sqrt(Δx^2 + Δy^2) - θ = atan2(Δy,Δx) + θ = atan(Δy,Δx) startx = locs_x[i] + nodesize*cos(θ) starty = locs_y[i] + nodesize*sin(θ) endx = locs_x[i] + (d-nodesize)*1.00*cos(θ) @@ -79,16 +79,16 @@ function graphline{T<:Real}(g, locs_x, locs_y, nodesize::T) lines end -function graphcurve{T<:Real}(g, locs_x, locs_y, nodesize::Vector{T}, arrowlength, angleoffset, outangle=pi/5) +function graphcurve(g, locs_x, locs_y, nodesize::Vector{T}, arrowlength, angleoffset, outangle=pi/5) where {T<:Real} lines = Array{Vector}(_ne(g)) - arrows = Array{Vector{Tuple{Float64,Float64}}}(_ne(g)) + arrows = Array{Vector{Tuple{Float64,Float64}}}(undef, _ne(g)) for (e_idx, e) in enumerate(_edges(g)) i = _src_index(e, g) j = _dst_index(e, g) Δx = locs_x[j] - locs_x[i] Δy = locs_y[j] - locs_y[i] d = sqrt(Δx^2 + Δy^2) - θ = atan2(Δy,Δx) + θ = atan(Δy,Δx) startx = locs_x[i] + nodesize[i]*cos(θ) starty = locs_y[i] + nodesize[i]*sin(θ) endx = locs_x[i] + (d-nodesize[j])*1.00*cos(θ) @@ -105,16 +105,16 @@ function graphcurve{T<:Real}(g, locs_x, locs_y, nodesize::Vector{T}, arrowlength lines, arrows end -function graphcurve{T<:Real}(g, locs_x, locs_y, nodesize::T, arrowlength, angleoffset, outangle=pi/5) +function graphcurve(g, locs_x, locs_y, nodesize::T, arrowlength, angleoffset, outangle=pi/5) where {T<:Real} lines = Array{Vector}(_ne(g)) - arrows = Array{Vector{Tuple{Float64,Float64}}}(_ne(g)) + arrows = Array{Vector{Tuple{Float64,Float64}}}(undef, _ne(g)) for (e_idx, e) in enumerate(_edges(g)) i = _src_index(e, g) j = _dst_index(e, g) Δx = locs_x[j] - locs_x[i] Δy = locs_y[j] - locs_y[i] d = sqrt(Δx^2 + Δy^2) - θ = atan2(Δy,Δx) + θ = atan(Δy,Δx) startx = locs_x[i] + nodesize*cos(θ) starty = locs_y[i] + nodesize*sin(θ) endx = locs_x[i] + (d-nodesize)*1.00*cos(θ) @@ -131,7 +131,7 @@ function graphcurve{T<:Real}(g, locs_x, locs_y, nodesize::T, arrowlength, angleo lines, arrows end -function graphcurve{T<:Real}(g, locs_x, locs_y, nodesize::T, outangle) +function graphcurve(g, locs_x, locs_y, nodesize::T, outangle) where {T<:Real} lines = Array{Vector}(_ne(g)) for (e_idx, e) in enumerate(_edges(g)) i = _src_index(e, g) @@ -139,7 +139,7 @@ function graphcurve{T<:Real}(g, locs_x, locs_y, nodesize::T, outangle) Δx = locs_x[j] - locs_x[i] Δy = locs_y[j] - locs_y[i] d = sqrt(Δx^2 + Δy^2) - θ = atan2(Δy,Δx) + θ = atan(Δy,Δx) startx = locs_x[i] + nodesize*cos(θ) starty = locs_y[i] + nodesize*sin(θ) endx = locs_x[i] + (d-nodesize)*1.00*cos(θ) @@ -149,7 +149,7 @@ function graphcurve{T<:Real}(g, locs_x, locs_y, nodesize::T, outangle) lines end -function graphcurve{T<:Real}(g, locs_x, locs_y, nodesize::Vector{T}, outangle) +function graphcurve(g, locs_x, locs_y, nodesize::Vector{T}, outangle) where {T<:Real} lines = Array{Vector}(_ne(g)) for (e_idx, e) in enumerate(_edges(g)) i = _src_index(e, g) @@ -157,7 +157,7 @@ function graphcurve{T<:Real}(g, locs_x, locs_y, nodesize::Vector{T}, outangle) Δx = locs_x[j] - locs_x[i] Δy = locs_y[j] - locs_y[i] d = sqrt(Δx^2 + Δy^2) - θ = atan2(Δy,Δx) + θ = atan(Δy,Δx) startx = locs_x[i] + nodesize*cos(θ) starty = locs_y[i] + nodesize*sin(θ) endx = locs_x[i] + (d-nodesize)*1.00*cos(θ) diff --git a/src/plot.jl b/src/plot.jl index 4dc8fd3..b4490cc 100644 --- a/src/plot.jl +++ b/src/plot.jl @@ -85,7 +85,7 @@ Equal to 0 for undirected graphs. Default: `0.1` for the directed graphs Optional. Angular width in radians for the arrows. Default: `π/9 (20 degrees)` """ -function gplot{T<:Real}(G, +function gplot(G, locs_x_in::Vector{T}, locs_y_in::Vector{T}; nodelabel = nothing, nodelabelc = colorant"black", @@ -110,11 +110,11 @@ function gplot{T<:Real}(G, arrowlengthfrac = _is_directed(G) ? 0.1 : 0.0, arrowangleoffset = π/9.0, linetype = "straight", - outangle = pi/5) + outangle = pi/5) where {T <: Real} length(locs_x_in) != length(locs_y_in) && error("Vectors must be same length") - const N = _nv(G) - const NE = _ne(G) + N = _nv(G) + NE = _ne(G) if nodelabel != nothing && length(nodelabel) != N error("Must have one label per node (or none)") end @@ -135,8 +135,8 @@ function gplot{T<:Real}(G, map!(z -> scaler(z, min_y, max_y), locs_y, locs_y) # Determine sizes - #const NODESIZE = 0.25/sqrt(N) - #const LINEWIDTH = 3.0/sqrt(N) + #NODESIZE = 0.25/sqrt(N) + #LINEWIDTH = 3.0/sqrt(N) max_nodesize = NODESIZE/maximum(nodesize) nodesize *= max_nodesize @@ -226,14 +226,14 @@ end # take from [Gadfly.jl](https://github.com/dcjones/Gadfly.jl) function open_file(filename) - if OS_NAME == :Darwin + if Sys.KERNEL == :Darwin run(`open $(filename)`) - elseif OS_NAME == :Linux || OS_NAME == :FreeBSD + elseif Sys.KERNEL == :Linux || Sys.KERNEL == :FreeBSD run(`xdg-open $(filename)`) - elseif OS_NAME == :Windows + elseif Sys.KERNEL == :Windows run(`$(ENV["COMSPEC"]) /c start $(filename)`) else - warn("Showing plots is not supported on OS $(string(OS_NAME))") + warn("Showing plots is not supported on OS $(string(Sys.KERNEL))") end end @@ -245,7 +245,7 @@ function gplothtml(G; layout::Function=spring_layout, keyargs...) plot_output = IOBuffer() draw(SVGJS(plot_output, Compose.default_graphic_width, Compose.default_graphic_width, false), gplot(G, layout(G)...; keyargs...)) - plotsvg = takebuf_string(plot_output) + plotsvg = String(take!(plot_output)) write(output, """ @@ -257,10 +257,10 @@ function gplothtml(G; layout::Function=spring_layout, keyargs...) $(plotsvg) diff --git a/test/runtests.jl b/test/runtests.jl index fab7827..ec301cf 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,8 +1,10 @@ using GraphPlot using LightGraphs +using Cairo using Colors using Compose -using Base.Test +using Random +using Test using VisualRegressionTests # global variables @@ -15,7 +17,7 @@ h = LightGraphs.WheelGraph(10) # plot and save function for visual regression tests function plot_and_save(fname, g; gplot_kwargs...) - srand(2017) + Random.seed!(2017) draw(PNG(fname, 8inch, 8inch), gplot(g; gplot_kwargs...)) end From 52f3a78c6d0464893327b33d760fb92af2e1d06e Mon Sep 17 00:00:00 2001 From: Simon Schoelly Date: Thu, 6 Sep 2018 15:36:18 +0200 Subject: [PATCH 2/8] upgraded .travis.yml to v0.7 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8c1ad98..f399290 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ os: - linux - osx julia: - - 0.6 + - 0.7 - nightly matrix: From fee9443b3bbf7d8e467aea4768cfc9fd900cae31 Mon Sep 17 00:00:00 2001 From: Simon Schoelly Date: Sat, 8 Sep 2018 00:30:09 +0200 Subject: [PATCH 3/8] added a minimum version for VisualRegressionTests for the tests --- src/GraphPlot.jl | 6 ------ test/REQUIRE | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/GraphPlot.jl b/src/GraphPlot.jl index 90d6a72..928ee60 100644 --- a/src/GraphPlot.jl +++ b/src/GraphPlot.jl @@ -1,5 +1,3 @@ -__precompile__(true) - module GraphPlot using Compose # for plotting features @@ -31,10 +29,6 @@ include("plot.jl") # read graph include("graphio.jl") -function test() - include(joinpath(dirname(@__DIR__), "test", "runtests.jl")) -end - # These functions are mappings to various graph packages. # Currently only LightGraphs is supported. diff --git a/test/REQUIRE b/test/REQUIRE index 63280fd..adebffb 100644 --- a/test/REQUIRE +++ b/test/REQUIRE @@ -1,3 +1,3 @@ -VisualRegressionTests +VisualRegressionTests 0.2.2 Cairo Fontconfig From 48f37a90e4c946c863ff1d97c4de83122b19fc46 Mon Sep 17 00:00:00 2001 From: Simon Schoelly Date: Tue, 11 Sep 2018 00:28:34 +0200 Subject: [PATCH 4/8] using builtin function LightGraphs.LinAlg.eigs instead uf Arpack.eigs --- REQUIRE | 3 +-- src/layout.jl | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/REQUIRE b/REQUIRE index 9295a33..e2961da 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1,6 +1,5 @@ julia 0.7 -Arpack Colors ColorTypes Compose -LightGraphs +LightGraphs 1.1.0 diff --git a/src/layout.jl b/src/layout.jl index ba92cd9..255e90d 100644 --- a/src/layout.jl +++ b/src/layout.jl @@ -1,5 +1,4 @@ using SparseArrays: SparseMatrixCSC -using Arpack: eigs """ Position nodes uniformly at random in the unit square. @@ -262,7 +261,7 @@ function _spectral(A::SparseMatrixCSC) D = sparse([1:length(data)], [1:length(data)], data) L = D - A ncv = max(7, int(sqrt(length(data)))) - eigenvalues, eigenvectors = eigs(L, nev=3, ncv=ncv) + eigenvalues, eigenvectors = LightGraphs.LinAlg.eigs(L, nev=3, ncv=ncv) index = sortperm(real(eigenvalues))[2:3] real(eigenvectors[:, index[1]]), real(eigenvectors[:, index[2]]) end From 5f82f5c68bd7f33e72503b9191b71c3b9c0546c1 Mon Sep 17 00:00:00 2001 From: Simon Schoelly Date: Wed, 19 Sep 2018 20:11:22 +0200 Subject: [PATCH 5/8] further fixes for problems that are not covered by tests --- .travis.yml | 4 +++ REQUIRE | 1 + src/GraphPlot.jl | 3 ++ src/collapse_plot.jl | 43 +++++++++++++-------------- src/layout.jl | 30 +++++++++++-------- src/pienode.jl | 4 +-- src/plot.jl | 2 +- src/precompile.jl | 70 -------------------------------------------- src/stress.jl | 24 ++++++++------- 9 files changed, 62 insertions(+), 119 deletions(-) delete mode 100644 src/precompile.jl diff --git a/.travis.yml b/.travis.yml index f399290..8d45c55 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,7 @@ os: - osx julia: - 0.7 + - 1.0 - nightly matrix: @@ -16,3 +17,6 @@ notifications: #script: # - if [[ -a .git/shallow ]]; then git fetch --unshallow; fi # - julia --check-bounds=yes -e 'Pkg.clone(pwd()); Pkg.build("GraphPlot"); Pkg.test("GraphPlot"; coverage=true)' +after_success: + # push coverage results to Codecov + - julia -e 'cd(using Pkg; Pkg.dir("GraphPlot")); Pkg.add("Coverage"); using Coverage; Codecov.submit(Codecov.process_folder())' diff --git a/REQUIRE b/REQUIRE index e2961da..b46d210 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1,4 +1,5 @@ julia 0.7 +ArnoldiMethod Colors ColorTypes Compose diff --git a/src/GraphPlot.jl b/src/GraphPlot.jl index 928ee60..404fa61 100644 --- a/src/GraphPlot.jl +++ b/src/GraphPlot.jl @@ -10,6 +10,8 @@ export gplothtml, random_layout, circular_layout, + collapse_layout, + community_layout, spring_layout, spectral_layout, shell_layout, @@ -25,6 +27,7 @@ include("stress.jl") include("shape.jl") include("lines.jl") include("plot.jl") +include("collapse_plot.jl") # read graph include("graphio.jl") diff --git a/src/collapse_plot.jl b/src/collapse_plot.jl index 736579c..9f03271 100644 --- a/src/collapse_plot.jl +++ b/src/collapse_plot.jl @@ -1,24 +1,21 @@ -using Graphs using GraphPlot -function collapse_graph{V}(g::AbstractGraph{V}, membership::Vector{Int}) +function collapse_graph(g::AbstractGraph, membership::Vector{Int}) nb_comm = maximum(membership) - collapsed_edge_weights = Array(Dict{Int,Float64}, nb_comm) + collapsed_edge_weights = Vector{Dict{Int,Float64}}(undef, nb_comm) for i=1:nb_comm collapsed_edge_weights[i] = Dict{Int,Float64}() end - for e in Graphs.edges(g) - u = source(e,g) - v = target(e,g) - u_idx = vertex_index(u,g) - v_idx = vertex_index(v,g) - u_comm = membership[u_idx] - v_comm = membership[v_idx] + for e in _edges(g) + u = _src_index(e,g) + v = _dst_index(e,g) + u_comm = membership[u] + v_comm = membership[v] # for special case of undirected network - if !Graphs.is_directed(g) + if !_is_directed(g) u_comm, v_comm = minmax(u_comm, v_comm) end @@ -29,12 +26,12 @@ function collapse_graph{V}(g::AbstractGraph{V}, membership::Vector{Int}) end end - collapsed_graph = simple_graph(nb_comm, is_directed=false) + collapsed_graph = SimpleGraph(nb_comm) collapsed_weights = Float64[] for u=1:nb_comm for (v,w) in collapsed_edge_weights[u] - Graphs.add_edge!(collapsed_graph, u, v) + add_edge!(collapsed_graph, u, v) push!(collapsed_weights, w) end end @@ -42,7 +39,7 @@ function collapse_graph{V}(g::AbstractGraph{V}, membership::Vector{Int}) collapsed_graph, collapsed_weights end -function community_layout{V}(g::AbstractGraph{V}, membership::Vector{Int}) +function community_layout(g::AbstractGraph, membership::Vector{Int}) N = length(membership) lx = zeros(N) ly = zeros(N) @@ -51,13 +48,13 @@ function community_layout{V}(g::AbstractGraph{V}, membership::Vector{Int}) if haskey(comms, lbl) push!(comms[lbl], idx) else - comms[lbl] = collect(idx) + comms[lbl] = Int[idx] end end h, w = collapse_graph(g, membership) clx, cly = spring_layout(h) for (lbl, nodes) in comms - θ = linspace(0, 2pi, length(nodes) + 1)[1:end-1] + θ = range(0, stop=2pi, length=(length(nodes) + 1))[1:end-1] for (idx, node) in enumerate(nodes) lx[node] = 1.8*length(nodes)/N*cos(θ[idx]) + clx[lbl] ly[node] = 1.8*length(nodes)/N*sin(θ[idx]) + cly[lbl] @@ -66,11 +63,11 @@ function community_layout{V}(g::AbstractGraph{V}, membership::Vector{Int}) lx, ly end -function collapse_layout{V}(g::AbstractGraph{V}, membership::Vector{Int}) - lightg = LightGraphs.Graph(num_vertices(g)) - for e in Graphs.edges(g) - u = vertex_index(source(e,g), g) - v = vertex_index(target(e,g), g) +function collapse_layout(g::AbstractGraph, membership::Vector{Int}) + lightg = LightGraphs.SimpleGraph(_nv(g)) + for e in _edges(g) + u = _src_index(e, g) + v = _dst_index(e, g) LightGraphs.add_edge!(lightg, u, v) end N = length(membership) @@ -81,7 +78,7 @@ function collapse_layout{V}(g::AbstractGraph{V}, membership::Vector{Int}) if haskey(comms, lbl) push!(comms[lbl], idx) else - comms[lbl] = collect(idx) + comms[lbl] = Int[idx] end end h, w = collapse_graph(g, membership) @@ -89,7 +86,7 @@ function collapse_layout{V}(g::AbstractGraph{V}, membership::Vector{Int}) for (lbl, nodes) in comms subg = lightg[nodes] sublx, subly = spring_layout(subg) - θ = linspace(0, 2pi, length(nodes) + 1)[1:end-1] + θ = range(0, stop=2pi, length=(length(nodes) + 1))[1:end-1] for (idx, node) in enumerate(nodes) lx[node] = 1.8*length(nodes)/N*sublx[idx] + clx[lbl] ly[node] = 1.8*length(nodes)/N*subly[idx] + cly[lbl] diff --git a/src/layout.jl b/src/layout.jl index 255e90d..5046003 100644 --- a/src/layout.jl +++ b/src/layout.jl @@ -1,4 +1,6 @@ -using SparseArrays: SparseMatrixCSC +using SparseArrays: SparseMatrixCSC, sparse +using ArnoldiMethod: LR +using LinearAlgebra: eigen """ Position nodes uniformly at random in the unit square. @@ -58,7 +60,7 @@ function circular_layout(G) return [0.0], [0.0] else # Discard the extra angle since it matches 0 radians. - θ = linspace(0, 2pi, _nv(G) + 1)[1:end-1] + θ = range(0, stop=2pi, length=_nv(G)+1)[1:end-1] return cos.(θ), sin.(θ) end end @@ -201,7 +203,7 @@ function shell_layout(G, nlist::Union{Nothing, Vector{Vector{Int}}} = nothing) locs_y = Float64[] for nodes in nlist # Discard the extra angle since it matches 0 radians. - θ = linspace(0, 2pi, length(nodes) + 1)[1:end-1] + θ = range(0, stop=2pi, length=length(nodes)+1)[1:end-1] append!(locs_x, radius*cos.(θ)) append!(locs_y, radius*sin.(θ)) radius += 1.0 @@ -231,14 +233,19 @@ julia> weight = rand(num_edges(g)) julia> locs_x, locs_y = spectral_layout(g, weight) ``` """ -function spectral_layout(G) +function spectral_layout(G, weight=nothing) if _nv(G) == 1 return [0.0], [0.0] + elseif _nv(G) == 2 + return [0.0, 1.0], [0.0, 0.0] end + if weight == nothing + weight = ones(length(_edges(G))) + end if _nv(G) > 500 - A = sparse(Int[_src_index(e) for e in _edges(G)], - Int[_dst_index(e) for e in _edges(G)], + A = sparse(Int[_src_index(e, G) for e in _edges(G)], + Int[_dst_index(e, G) for e in _edges(G)], weight, _nv(G), _nv(G)) if _is_directed(G) A = A + A' @@ -246,22 +253,21 @@ function spectral_layout(G) return _spectral(A) else L = _laplacian_matrix(G) - return _spectral(full(L)) + return _spectral(Matrix(L)) end end function _spectral(L::Matrix) - eigenvalues, eigenvectors = eig(L) + eigenvalues, eigenvectors = eigen(L) index = sortperm(eigenvalues)[2:3] eigenvectors[:, index[1]], eigenvectors[:, index[2]] end function _spectral(A::SparseMatrixCSC) - data = collect(sum(A, 1)) - D = sparse([1:length(data)], [1:length(data)], data) + data = vec(sum(A, dims=1)) + D = sparse(Base.OneTo(length(data)), Base.OneTo(length(data)), data) L = D - A - ncv = max(7, int(sqrt(length(data)))) - eigenvalues, eigenvectors = LightGraphs.LinAlg.eigs(L, nev=3, ncv=ncv) + eigenvalues, eigenvectors = LightGraphs.LinAlg.eigs(L, nev=3, which=LR()) index = sortperm(real(eigenvalues))[2:3] real(eigenvectors[:, index[1]]), real(eigenvectors[:, index[2]]) end diff --git a/src/pienode.jl b/src/pienode.jl index 5118255..dbafe5b 100644 --- a/src/pienode.jl +++ b/src/pienode.jl @@ -1,5 +1,5 @@ # to do -type PIENODE +mutable struct PIENODE x::Float64 y::Float64 r::Float64 @@ -32,7 +32,7 @@ function sector(x, y, r, θ1, θ2) end end -function sector{T<:Real}(x::Vector{T}, y::Vector{T}, r::Vector{T}, θ1::Vector{T}, θ2::Vector{T}) +function sector(x::Vector{T}, y::Vector{T}, r::Vector{T}, θ1::Vector{T}, θ2::Vector{T}) where {T} s = Vector[] for i=1:length(x) push!(s, sector(x[i],y[i],r[i],θ1[i],θ2[i])) diff --git a/src/plot.jl b/src/plot.jl index b4490cc..e7da136 100644 --- a/src/plot.jl +++ b/src/plot.jl @@ -233,7 +233,7 @@ function open_file(filename) elseif Sys.KERNEL == :Windows run(`$(ENV["COMSPEC"]) /c start $(filename)`) else - warn("Showing plots is not supported on OS $(string(Sys.KERNEL))") + @warn("Showing plots is not supported on OS $(string(Sys.KERNEL))") end end diff --git a/src/precompile.jl b/src/precompile.jl deleted file mode 100644 index a3b67a0..0000000 --- a/src/precompile.jl +++ /dev/null @@ -1,70 +0,0 @@ -function _precompile_() - ccall(:jl_generating_output, Cint, ()) == 1 || return nothing - precompile(GraphPlot.random_layout, (Graphs.AbstractGraph{KeyVertex},)) - precompile(GraphPlot.random_layout, (Graphs.AbstractGraph{ExVertex},)) - precompile(GraphPlot.circular_layout, (Graphs.AbstractGraph{KeyVertex},)) - precompile(GraphPlot.circular_layout, (Graphs.AbstractGraph{ExVertex},)) - precompile(GraphPlot.spring_layout, (Graphs.AbstractGraph{KeyVertex}, Float64, Float64, Float64,)) - precompile(GraphPlot.spring_layout, (Graphs.AbstractGraph{ExVertex}, Float64, Float64, Float64,)) - precompile(GraphPlot.spring_layout, (Graphs.AbstractGraph{KeyVertex}, Vector{Float64}, Vector{Float64}, Float64, Float64, Float64,)) - precompile(GraphPlot.spring_layout, (Graphs.AbstractGraph{ExVertex}, Vector{Float64}, Vector{Float64}, Float64, Float64, Float64,)) - precompile(GraphPlot.shell_layout, (Graphs.AbstractGraph{KeyVertex}, Void,)) - precompile(GraphPlot.shell_layout, (Graphs.AbstractGraph{ExVertex}, Void,)) - precompile(GraphPlot.shell_layout, (Graphs.AbstractGraph{KeyVertex}, Vector{Vector{Int}},)) - precompile(GraphPlot.shell_layout, (Graphs.AbstractGraph{ExVertex}, Void, Vector{Vector{Int}},)) - precompile(GraphPlot.spectral_layout, (Graphs.AbstractGraph{KeyVertex}, Void,)) - precompile(GraphPlot.spectral_layout, (Graphs.AbstractGraph{ExVertex}, Void,)) - precompile(GraphPlot.spectral_layout, (Graphs.AbstractGraph{KeyVertex}, Vector{Float64},)) - precompile(GraphPlot.spectral_layout, (Graphs.AbstractGraph{ExVertex}, Vector{Float64},)) - precompile(GraphPlot.stressmajorize_layout, (Graphs.AbstractGraph{KeyVertex}, Int, Void, Vector{Float64}, Int,)) - precompile(GraphPlot.spectral_layout, (Graphs.AbstractGraph{ExVertex}, Int, Void, Vector{Float64}, Int,)) - precompile(GraphPlot.spectral_layout, (Graphs.AbstractGraph{KeyVertex}, Int, Vector{Float64}, Vector{Float64}, Int,)) - precompile(GraphPlot.spectral_layout, (Graphs.AbstractGraph{ExVertex}, Int, Vector{Float64}, Vector{Float64}, Int,)) - precompile(GraphPlot.graphline, (Graphs.AbstractGraph{KeyVertex}, Vector{Float64}, Vector{Float64}, Vector{Float64}, Float64, Float64,)) - precompile(GraphPlot.graphline, (Graphs.AbstractGraph{ExVertex}, Vector{Float64}, Vector{Float64}, Vector{Float64}, Float64, Float64,)) - precompile(GraphPlot.graphline, (Graphs.AbstractGraph{KeyVertex}, Vector{Float64}, Vector{Float64}, Float64, Float64, Float64,)) - precompile(GraphPlot.graphline, (Graphs.AbstractGraph{ExVertex}, Vector{Float64}, Vector{Float64}, Float64, Float64, Float64,)) - precompile(GraphPlot.graphline, (Graphs.AbstractGraph{KeyVertex}, Vector{Float64}, Vector{Float64}, Vector{Float64},)) - precompile(GraphPlot.graphline, (Graphs.AbstractGraph{ExVertex}, Vector{Float64}, Vector{Float64}, Vector{Float64},)) - precompile(GraphPlot.graphline, (Graphs.AbstractGraph{KeyVertex}, Vector{Float64}, Vector{Float64}, Float64,)) - precompile(GraphPlot.graphline, (Graphs.AbstractGraph{ExVertex}, Vector{Float64}, Vector{Float64}, Float64,)) - precompile(GraphPlot.graphcurve, (Graphs.AbstractGraph{KeyVertex}, Vector{Float64}, Vector{Float64}, Vector{Float64}, Float64, Float64, Float64,)) - precompile(GraphPlot.graphcurve, (Graphs.AbstractGraph{ExVertex}, Vector{Float64}, Vector{Float64}, Vector{Float64}, Float64, Float64, Float64,)) - precompile(GraphPlot.graphcurve, (Graphs.AbstractGraph{KeyVertex}, Vector{Float64}, Vector{Float64}, Float64, Float64, Float64, Float64,)) - precompile(GraphPlot.graphcurve, (Graphs.AbstractGraph{ExVertex}, Vector{Float64}, Vector{Float64}, Float64, Float64, Float64, Float64,)) - precompile(GraphPlot.graphcurve, (Graphs.AbstractGraph{KeyVertex}, Vector{Float64}, Vector{Float64}, Vector{Float64}, Float64,)) - precompile(GraphPlot.graphcurve, (Graphs.AbstractGraph{ExVertex}, Vector{Float64}, Vector{Float64}, Vector{Float64}, Float64,)) - precompile(GraphPlot.graphcurve, (Graphs.AbstractGraph{KeyVertex}, Vector{Float64}, Vector{Float64}, Float64, Float64,)) - precompile(GraphPlot.graphcurve, (Graphs.AbstractGraph{ExVertex}, Vector{Float64}, Vector{Float64}, Float64, Float64,)) - precompile(GraphPlot.arrowcoords, (Float64, Float64, Float64, Float64, Float64,)) - precompile(GraphPlot.curvearrowcoords1, (Float64, Float64, Float64, Float64, Float64, Float64,)) - precompile(GraphPlot.curvearrowcoords2, (Float64, Float64, Float64, Float64, Float64, Float64,)) - precompile(GraphPlot.curveedge, (Float64, Float64, Float64, Float64, Float64,)) - precompile(GraphPlot.graphfamous, (UTF8String,)) - precompile(GraphPlot.readedgelist, (UTF8String, Bool, Int,)) - precompile(GraphPlot.gplot, (Graphs.AbstractGraph{KeyVertex}, Vector{Float64}, Vector{Float64},)) - precompile(GraphPlot.gplot, (Graphs.AbstractGraph{ExVertex}, Vector{Float64}, Vector{Float64},)) - precompile(GraphPlot.gplothtml, (Graphs.AbstractGraph{KeyVertex}, Vector{Float64}, Vector{Float64},)) - precompile(GraphPlot.gplothtml, (Graphs.AbstractGraph{ExVertex}, Vector{Float64}, Vector{Float64},)) - - precompile(GraphPlot.random_layout, (LightGraphs.SimpleGraph,)) - precompile(GraphPlot.circular_layout, (LightGraphs.SimpleGraph,)) - precompile(GraphPlot.spring_layout, (LightGraphs.SimpleGraph, Float64, Float64, Float64,)) - precompile(GraphPlot.spring_layout, (LightGraphs.SimpleGraph, Vector{Float64}, Vector{Float64}, Float64, Float64, Float64,)) - precompile(GraphPlot.shell_layout, (LightGraphs.SimpleGraph, Void,)) - precompile(GraphPlot.shell_layout, (LightGraphs.SimpleGraph, Vector{Vector{Int}},)) - precompile(GraphPlot.spectral_layout, (LightGraphs.SimpleGraph, Void,)) - precompile(GraphPlot.spectral_layout, (LightGraphs.SimpleGraph, Vector{Float64},)) - precompile(GraphPlot.stressmajorize_layout, (LightGraphs.SimpleGraph, Int, Void, Vector{Float64}, Int,)) - precompile(GraphPlot.spectral_layout, (LightGraphs.SimpleGraph, Int, Vector{Float64}, Vector{Float64}, Int,)) - precompile(GraphPlot.graphline, (LightGraphs.SimpleGraph, Vector{Float64}, Vector{Float64}, Vector{Float64}, Float64, Float64,)) - precompile(GraphPlot.graphline, (LightGraphs.SimpleGraph, Vector{Float64}, Vector{Float64}, Float64, Float64, Float64,)) - precompile(GraphPlot.graphline, (LightGraphs.SimpleGraph, Vector{Float64}, Vector{Float64}, Vector{Float64},)) - precompile(GraphPlot.graphline, (LightGraphs.SimpleGraph, Vector{Float64}, Vector{Float64}, Float64,)) - precompile(GraphPlot.graphcurve, (LightGraphs.SimpleGraph, Vector{Float64}, Vector{Float64}, Vector{Float64}, Float64, Float64, Float64,)) - precompile(GraphPlot.graphcurve, (LightGraphs.SimpleGraph, Vector{Float64}, Vector{Float64}, Float64, Float64, Float64, Float64,)) - precompile(GraphPlot.graphcurve, (LightGraphs.SimpleGraph, Vector{Float64}, Vector{Float64}, Vector{Float64}, Float64,)) - precompile(GraphPlot.graphcurve, (LightGraphs.SimpleGraph, Vector{Float64}, Vector{Float64}, Float64, Float64,)) - precompile(GraphPlot.gplot, (LightGraphs.SimpleGraph, Vector{Float64}, Vector{Float64},)) - precompile(GraphPlot.gplothtml, (LightGraphs.SimpleGraph, Vector{Float64}, Vector{Float64},)) -end diff --git a/src/stress.jl b/src/stress.jl index f4ff02d..eaddaf5 100644 --- a/src/stress.jl +++ b/src/stress.jl @@ -1,3 +1,5 @@ +using LinearAlgebra + # This layout algorithm is copy from [IainNZ](https://github.com/IainNZ)'s [GraphLayout.jl](https://github.com/IainNZ/GraphLayout.jl) @doc """ Compute graph layout using stress majorization @@ -52,7 +54,7 @@ Reference: publisher={Springer Berlin Heidelberg}, pages={239--250}, } -""" -> +""" function stressmajorize_layout(G, p::Int=2, w=nothing, X0=randn(_nv(G), p); maxiter = 400size(X0, 1)^2, abstols=√(eps(eltype(X0))), reltols=√(eps(eltype(X0))), abstolx=√(eps(eltype(X0))), @@ -63,7 +65,7 @@ function stressmajorize_layout(G, p::Int=2, w=nothing, X0=randn(_nv(G), p); if w==nothing w = δ.^-2 - w[.!isfinite.(w)] = 0 + w[.!isfinite.(w)] .= 0 end @assert size(X0, 1)==size(δ, 1)==size(δ, 2)==size(w, 1)==size(w, 2) @@ -73,23 +75,23 @@ function stressmajorize_layout(G, p::Int=2, w=nothing, X0=randn(_nv(G), p); Xs = Matrix[X0] stresses = [newstress] iter = 0 - for iter = 1:maxiter + for outer iter = 1:maxiter #TODO the faster way is to drop the first row and col from the iteration X = pinvLw * (LZ(X0, δ, w)*X0) @assert all(isfinite.(X)) newstress, oldstress = stress(X, δ, w), newstress - verbose && info("""Iteration $iter - Change in coordinates: $(vecnorm(X - X0)) + verbose && @info("""Iteration $iter + Change in coordinates: $(norm(X - X0)) Stress: $newstress (change: $(newstress-oldstress)) """) push!(Xs, X) push!(stresses, newstress) abs(newstress - oldstress) < reltols * newstress && break abs(newstress - oldstress) < abstols && break - vecnorm(X - X0) < abstolx && break + norm(X - X0) < abstolx && break X0 = X end - iter == maxiter && warn("Maximum number of iterations reached without convergence") + iter == maxiter && @warn("Maximum number of iterations reached without convergence") #returnall ? (Xs, stresses) : Xs[end] Xs[end][:,1], Xs[end][:,2] end @@ -103,7 +105,7 @@ Input: w: Weights for each pairwise distance See (1) of Reference -""" -> +""" function stress(X, d=fill(1.0, size(X, 1), size(X, 1)), w=nothing) s = 0.0 n = size(X, 1) @@ -123,9 +125,9 @@ end Compute weighted Laplacian given ideal weights w Lʷ defined in (4) of the Reference -""" -> +""" function weightedlaplacian(w) - n = Base.LinAlg.checksquare(w) + n = LinearAlgebra.checksquare(w) T = eltype(w) Lw = zeros(T, n, n) for i=1:n @@ -146,7 +148,7 @@ Computes L^Z defined in (5) of the Reference Input: Z: current layout (coordinates) d: Ideal distances (default: all 1) w: weights (default: d.^-2) -""" -> +""" function LZ(Z, d, w) n = size(Z, 1) L = zeros(n, n) From ab527a75be2965eea0b1d9944a2ca61d39a37021 Mon Sep 17 00:00:00 2001 From: Simon Schoelly Date: Thu, 27 Sep 2018 17:48:19 +0200 Subject: [PATCH 6/8] added min requirement for Compose.jl --- REQUIRE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/REQUIRE b/REQUIRE index b46d210..5a68070 100644 --- a/REQUIRE +++ b/REQUIRE @@ -2,5 +2,5 @@ julia 0.7 ArnoldiMethod Colors ColorTypes -Compose +Compose 0.7.0 LightGraphs 1.1.0 From a6184049eb807afadc0a193878b53775b42577d1 Mon Sep 17 00:00:00 2001 From: Simon Schoelly Date: Thu, 27 Sep 2018 18:12:33 +0200 Subject: [PATCH 7/8] added VisualRegresionTests to the requirements --- REQUIRE | 1 + 1 file changed, 1 insertion(+) diff --git a/REQUIRE b/REQUIRE index 5a68070..5f357ba 100644 --- a/REQUIRE +++ b/REQUIRE @@ -4,3 +4,4 @@ Colors ColorTypes Compose 0.7.0 LightGraphs 1.1.0 +VisualRegressionTests 0.2.2 # this shouldn't be necessary here as it is only used by the tests From 182c7acda4a439f6c3a79077b1f897ddae79878a Mon Sep 17 00:00:00 2001 From: Simon Schoelly Date: Thu, 27 Sep 2018 18:56:10 +0200 Subject: [PATCH 8/8] some changes to deal with an error on travis --- test/REQUIRE | 2 +- test/runtests.jl | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/test/REQUIRE b/test/REQUIRE index adebffb..2341592 100644 --- a/test/REQUIRE +++ b/test/REQUIRE @@ -1,3 +1,3 @@ VisualRegressionTests 0.2.2 Cairo -Fontconfig +ImageMagick diff --git a/test/runtests.jl b/test/runtests.jl index ec301cf..a29f51d 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,3 +1,7 @@ + +# This should fix an error, see : https://github.com/JuliaIO/ImageMagick.jl/issues/133 +(Sys.islinux() || Sys.iswindows()) && import ImageMagick + using GraphPlot using LightGraphs using Cairo