1664869800
A Julia module to render graphs in 3D using ThreeJS tightly coupled with LightGraphs.
In a Julia REPL, run:
Pkg.add("NetworkViz")
The NodeProperty
type stores the properties of each node in the graph. It stores the following properties :
color
: It is a Colors
array that stores the colors of all the nodes in the graph.size
: Size of the node. eg : 0.2
.shape
: Shape of the node. Can be 0 or 1. 0 - Square
, 1 - Circle
.The EdgeProperty
type stores the properties of each edge in the graph. It stores the following properties :
color
: It is a hex string that stores the color of the edges.width
: Thickness of the edges. eg : 1.5
.The drawGraph
function can be used to draw the graphs in 2D or 3D with nodes having different colors. It can accept LightGraphs.Graph
and LightGraphs.Digraph
types. drawGraph
can be used to draw graphs from adjacency matrices also. The function accepts an additional kwargs node::NodeProperty
, edge::EdgeProperty
, and z
. If z=1
, it draws a 3D graph. If z=0
, a 2D visualization of the graph is drawn. node
and edge
determines the properties of nodes and edges respectively.
Usage :
g = CompleteGraph(10)
c = Color[parse(Colorant,"#00004d") for i in 1:nv(g)]
n = NodeProperty(c,0.2,0)
e = EdgeProperty("#ff3333",1)
drawGraph(g,node=n,edge=e,z=1) #Draw using a Graph object (3D).
am = full(adjacency_matrix(g))
drawGraph(am,node=n,edge=e,z=0) #Draw using an adjacency matrix (2D).
dgraph = bfs_tree(g,1)
drawGraph(dgraph,z=1) #Draw a Digraph.
addEdge(g::Graph,node1::Int,node2::Int,z=1)
- Add a new edge node1-node2
and redraws the graph. z
toggles 2D-3D conversion. Fails silently if an already existing node is added again.removeEdge(g::Graph,node1::Int,node2::Int,z=1)
- Removes the edge node1-node2
if it exists and redraws the graph. z
toggles 2D-3D conversion.addNode(g::Graph,z=1)
- Adds a new node to the graph. z
toggles 2D-3D conversion.removeNode(g::Graph,node::Int,z=1)
- Removes node
if it exists and redraws the graph. z
toggles 2D-3D conversion.#Run this code in Escher
using NetworkViz
using LightGraphs
main(window) = begin
push!(window.assets, "widgets")
push!(window.assets,("ThreeJS","threejs"))
g = CompleteGraph(10)
drawGraph(g)
end
The above code produces the following output :
Here is another example with a code-mirror where functions can be typed in. Depending on the LightGraphs function used, 2D as well as 3D graphs are drawn. You can see the working demo here.
You can find many other examples in the examples/
folder.
IainNZ for the original Spring-Embedder code. (Taken from GraphLayout.jl).
Author: Abhijithanilkumar
Source Code: https://github.com/abhijithanilkumar/NetworkViz.jl
License: View license
1664869800
A Julia module to render graphs in 3D using ThreeJS tightly coupled with LightGraphs.
In a Julia REPL, run:
Pkg.add("NetworkViz")
The NodeProperty
type stores the properties of each node in the graph. It stores the following properties :
color
: It is a Colors
array that stores the colors of all the nodes in the graph.size
: Size of the node. eg : 0.2
.shape
: Shape of the node. Can be 0 or 1. 0 - Square
, 1 - Circle
.The EdgeProperty
type stores the properties of each edge in the graph. It stores the following properties :
color
: It is a hex string that stores the color of the edges.width
: Thickness of the edges. eg : 1.5
.The drawGraph
function can be used to draw the graphs in 2D or 3D with nodes having different colors. It can accept LightGraphs.Graph
and LightGraphs.Digraph
types. drawGraph
can be used to draw graphs from adjacency matrices also. The function accepts an additional kwargs node::NodeProperty
, edge::EdgeProperty
, and z
. If z=1
, it draws a 3D graph. If z=0
, a 2D visualization of the graph is drawn. node
and edge
determines the properties of nodes and edges respectively.
Usage :
g = CompleteGraph(10)
c = Color[parse(Colorant,"#00004d") for i in 1:nv(g)]
n = NodeProperty(c,0.2,0)
e = EdgeProperty("#ff3333",1)
drawGraph(g,node=n,edge=e,z=1) #Draw using a Graph object (3D).
am = full(adjacency_matrix(g))
drawGraph(am,node=n,edge=e,z=0) #Draw using an adjacency matrix (2D).
dgraph = bfs_tree(g,1)
drawGraph(dgraph,z=1) #Draw a Digraph.
addEdge(g::Graph,node1::Int,node2::Int,z=1)
- Add a new edge node1-node2
and redraws the graph. z
toggles 2D-3D conversion. Fails silently if an already existing node is added again.removeEdge(g::Graph,node1::Int,node2::Int,z=1)
- Removes the edge node1-node2
if it exists and redraws the graph. z
toggles 2D-3D conversion.addNode(g::Graph,z=1)
- Adds a new node to the graph. z
toggles 2D-3D conversion.removeNode(g::Graph,node::Int,z=1)
- Removes node
if it exists and redraws the graph. z
toggles 2D-3D conversion.#Run this code in Escher
using NetworkViz
using LightGraphs
main(window) = begin
push!(window.assets, "widgets")
push!(window.assets,("ThreeJS","threejs"))
g = CompleteGraph(10)
drawGraph(g)
end
The above code produces the following output :
Here is another example with a code-mirror where functions can be typed in. Depending on the LightGraphs function used, 2D as well as 3D graphs are drawn. You can see the working demo here.
You can find many other examples in the examples/
folder.
IainNZ for the original Spring-Embedder code. (Taken from GraphLayout.jl).
Author: Abhijithanilkumar
Source Code: https://github.com/abhijithanilkumar/NetworkViz.jl
License: View license
1666064340
Metis.jl is a Julia wrapper to the Metis library which is a library for partitioning unstructured graphs, partitioning meshes, and computing fill-reducing orderings of sparse matrices.
Metis.partition
calculates graph partitions. As an example, here we partition a small graph into two, three and four parts, and visualize the result:
![]() | ![]() | ![]() |
---|---|---|
Metis.partition(g, 2) | Metis.partition(g, 3) | Metis.partition(g, 4) |
Metis.partition
calls METIS_PartGraphKway
or METIS_PartGraphRecursive
from the Metis C API, depending on the optional keyword argument alg
:
alg = :KWAY
: multilevel k-way partitioning (METIS_PartGraphKway
).alg = :RECURSIVE
: multilevel recursive bisection (METIS_PartGraphRecursive
).Metis.separator
calculates a vertex separator of a graph. Metis.separator
calls METIS_ComputeVertexSeparator
from the Metis C API. As an example, here we calculate a vertex separator (green) of a small graph:
![]() |
---|
Metis.separator(g) |
Metis.permutation
calculates the fill reducing permutation for a sparse matrices. Metis.permutation
calls METIS_NodeND
from the Metis C API. As an example, we calculate the fill reducing permutation for a sparse matrix S
originating from a typical (small) FEM problem, and visualize the sparsity pattern for the original matrix and the permuted matrix:
perm, iperm = Metis.permutation(S)
⠛⣤⢠⠄⠀⣌⠃⢠⠀⠐⠈⠀⠀⠀⠀⠉⠃⠀⠀⠀⠀⠀⠀⠀⠀⠘⠀⠂⠔⠀ ⠀⠖⠻⣦⡅⠘⡁⠀⠀⠀⠀⠐⠀⠁⠀⢂⠀⠀⠠⠀⠀⠀⠁⢀⠀⢀⠀⠀⠄⢣ ⡀⢤⣁⠉⠛⣤⡡⢀⠀⠂⠂⠀⠂⠃⢰⣀⠀⠔⠀⠀⠀⠀⠀⠀⠀⠀⠀⠄⠄⠀ ⠉⣀⠁⠈⠁⢊⠱⢆⡰⠀⠈⠀⠀⠀⠀⢈⠉⡂⠀⠐⢀⡞⠐⠂⠀⠄⡀⠠⠂⠀ ⢀⠀⠀⠀⠠⠀⠐⠊⠛⣤⡔⠘⠰⠒⠠⠀⡈⠀⠀⠀⠉⠉⠘⠂⠀⠀⠀⡐⢈⠀ ⠂⠀⢀⠀⠈⠀⠂⠀⣐⠉⢑⣴⡉⡈⠁⡂⠒⠀⠁⢠⡄⠀⠐⠀⠠⠄⠀⠁⢀⡀ ⠀⠀⠄⠀⠬⠀⠀⠀⢰⠂⡃⠨⣿⣿⡕⠂⠀⠨⠌⠈⠆⠀⠄⡀⠑⠀⠀⠘⠀⠀ ⡄⠀⠠⢀⠐⢲⡀⢀⠀⠂⠡⠠⠱⠉⢱⢖⡀⠀⡈⠃⠀⠀⠀⢁⠄⢀⣐⠢⠀⠀ ⠉⠀⠀⠀⢀⠄⠣⠠⠂⠈⠘⠀⡀⡀⠀⠈⠱⢆⣰⠠⠰⠐⠐⢀⠀⢀⢀⠀⠌⠀ ⠀⠀⠀⠂⠀⠀⢀⠀⠀⠀⠁⣀⡂⠁⠦⠈⠐⡚⠱⢆⢀⢀⠡⠌⡀⡈⠸⠁⠂⠀ ⠀⠀⠀⠀⠀⠀⣠⠴⡇⠀⠀⠉⠈⠁⠀⠀⢐⠂⠀⢐⣻⣾⠡⠀⠈⠀⠄⠀⡉⠄ ⠀⠀⠁⢀⠀⠀⠰⠀⠲⠀⠐⠀⠀⠡⠄⢀⠐⢀⡁⠆⠁⠂⠱⢆⡀⣀⠠⠁⠉⠇ ⣀⠀⠀⢀⠀⠀⠀⠄⠀⠀⠀⠆⠑⠀⠀⢁⠀⢀⡀⠨⠂⠀⠀⢨⠿⢇⠀⡸⠀⢀ ⠠⠀⠀⠀⠀⠄⠀⡈⢀⠠⠄⠀⣀⠀⠰⡘⠀⠐⠖⠂⠀⠁⠄⠂⣀⡠⠻⢆⠄⠃ ⠐⠁⠤⣁⠀⠁⠈⠀⠂⠐⠀⠰⠀⠀⠀⠀⠂⠁⠈⠀⠃⠌⠧⠄⠀⢀⠤⠁⠱⢆ | ⣕⢝⠀⠀⢸⠔⡵⢊⡀⠂⠀⠀⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣑⠑ ⠀⠀⠑⢄⠀⠳⠡⢡⣒⣃⢣⠯⠆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠌ ⢒⠖⢤⡀⠑⢄⢶⡈⣂⠎⢎⠉⠩⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⡱⢋⠅⣂⡘⠳⠻⢆⡥⣈⠆⡨⡩⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠁⠀ ⠠⠈⠼⢸⡨⠜⡁⢫⣻⢞⢔⠀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⠠ ⠀⠀⡭⡖⡎⠑⡈⡡⠐⠑⠵⣧⣜⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀ ⠀⠁⠈⠁⠃⠂⠃⠊⠀⠘⠒⠙⠛⢄⠀⠀⢄⠀⠤⢠⠀⢄⢀⢀⠀⡀⠀⠀⢄⢄ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⢄⠊⠀⣂⠅⢓⣤⡄⠢⠠⠀⠌⠉⢀⢁ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⠊⠀⠑⢄⠁⣋⠀⢀⢰⢄⢔⢠⡖⢥⠀⠁ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣃⠌⠜⡥⢠⠛⣤⠐⣂⡀⠀⡀⡁⠍⠤⠒⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢄⠙⣴⠀⢀⠰⢠⠿⣧⡅⠁⠂⢂⠂⠋⢃⢀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢐⠠⡉⠐⢖⠀⠈⠅⠉⢕⢕⠝⠘⡒⠠⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⠀⠂⠐⣑⠄⠨⠨⢀⣓⠁⣕⢝⡥⢉⠁⠠ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡆⠁⠜⣍⠃⡅⡬⠀⠘⡈⡅⢋⠛⣤⡅⠒ ⢕⠘⡂⠄⠀⠀⠁⠀⠀⡂⠀⢠⠀⢕⠄⢐⠄⠀⠘⠀⠉⢐⠀⠀⠁⡀⢡⠉⢟⣵ |
---|---|
S (5% stored values) | S[perm,perm] (5% stored values) |
We can also visualize the sparsity pattern of the Cholesky factorization of the same matrix. It is here clear that using the fill reducing permutation results in a sparser factorization:
⠙⢤⢠⡄⠀⣜⠃⢠⠀⠐⠘⠀⠀⠀⠀⠛⠃⠀⠀⠀⠀⠀⠀⠀⠀⠘⠀⠂⡔⠀ ⠀⠀⠙⢦⡇⠾⡃⠰⠀⠀⠀⠐⠀⠃⠀⢂⠀⠀⠠⠀⠀⠀⠃⢀⠀⢀⠀⠀⠆⢣ ⠀⠀⠀⠀⠙⢼⣣⢠⠀⣂⣂⢘⡂⡃⢰⣋⡀⣔⢠⠀⠀⠀⡃⠈⠀⢈⠀⡄⣄⡋ ⠀⠀⠀⠀⠀⠀⠑⢖⡰⠉⠉⠈⠁⠁⢘⢙⠉⡊⢐⢐⢀⣞⠱⠎⠀⠌⡀⡣⡊⠉ ⠀⠀⠀⠀⠀⠀⠀⠀⠙⢤⣴⢸⣴⡖⢠⣤⡜⢣⠀⠀⠛⠛⡜⠂⠀⢢⠀⡔⢸⡄ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢼⣛⣛⣛⣛⣓⣚⡃⢠⣖⣒⣓⢐⢠⣜⠀⡃⢘⣓ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣿⣿⣿⣿⣿⢸⣿⣿⣿⣾⣿⣿⠀⣿⢸⣿ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣒⣿⣺⣿ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣿⣿⣿⣿⣿⣿⣿⣿⣤⣿⣼⣿ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣿⣿⣿⣿⣿⣿⣿⣿ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣿⣿⣿⣿⣿⣿ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣿⣿⣿⣿ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣿⣿ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿ | ⠑⢝⠀⠀⢸⠔⡵⢊⡀⡂⠀⠀⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣕⢕ ⠀⠀⠑⢄⠀⠳⠡⢡⣒⣃⢣⠯⠆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠌ ⠀⠀⠀⠀⠑⢄⢶⡘⣂⡎⢎⡭⠯⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠶⠴ ⠀⠀⠀⠀⠀⠀⠙⢎⣷⣏⢷⣯⡫⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠛⡛ ⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⢼⣧⣧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠤⡤ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⢿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣭⣯ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢄⠀⠀⢄⠀⠤⢠⠀⢄⢀⢀⠀⡀⠀⠀⢟⢟ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⢄⠊⠀⣂⠅⢓⣤⡄⠢⠠⠀⠌⠉⢀⢁ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⢄⠉⣋⠀⢁⢰⢔⢔⢠⡖⢥⠁⠃ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢤⠘⣶⡂⠠⡀⣡⠭⣤⢓⢗ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢷⡇⡇⣢⣢⠂⣯⣷⣶ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⢕⢟⢝⣒⠭⠭⡭ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⢝⣿⣿⡭⡯ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣿⣿ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿ |
---|---|
chol(S) (16% stored values) | chol(S[perm,perm]) (6% stored values) |
For more fine tuned usage of Metis consider calling the C API directly. The following functions are currently exposed:
METIS_PartGraphRecursive
METIS_PartGraphKway
METIS_ComputeVertexSeparator
METIS_NodeND
all with the same arguments and argument order as described in the Metis manual.
Author: JuliaSparse
Source Code: https://github.com/JuliaSparse/Metis.jl
License: View license
1665083280
Graph visualization using GLVisualize.jl
by Simon Danisch. Tightly integrated with LightGraphs.jl
.
This is a pre-alpha version.
Pkg.clone("https://github.com/JuliaGraphs/GraphVisualize.jl")
Pkg.checkout("GLVisualize")
Pkg.checkout("GLAbstraction")
For the time being only the function
plot(g::Graph; observe=false)
returning an plot object of graph g
and visualizing it in an OpenGL window.
Is observe=true
updates to g
will be reflected in updates to the plot.
You can left-click and drag a vertex to move it around.
using LightGraphs
using GraphVisualize
g = erdos_renyi(10, 20)
plt = plot(g, observe=true) # a windows pops up displaying g
add_edge!(g, 3, 7) # the plot is updated
rem_edge!(g, 3, 7) # the plot is updated
rem_vertex!(g, 3) # the plot is updated
add_vertex!(g) # the plot is updated
# have fun moving the vertex around
# now close the window
g = WheelGraph(10) # create a new graph, DON'T ever plot twice the same graph
plt = plot(g, observe=false) # a windows pops up displaying g
add_edge!(g, 3, 7) # the plot is NOT updated
push!(obs, g) # the plot is updated
...
Author: CarloLucibello
Source Code: https://github.com/CarloLucibello/GraphVisualize.jl
License: View license
1665122040
Graph layout and visualization algorithms based on Compose.jl and inspired by GraphLayout.jl.
The spring_layout
and stressmajorize_layout
function are copy from IainNZ's GraphLayout.jl.
Other layout algorithms are wrapped from NetworkX.
gadfly.js
is copied from Gadfly.jl
Getting Started
From the Julia REPL the latest version can be installed with
Pkg.add("GraphPlot")
GraphPlot is then loaded with
using GraphPlot
Usage
using Graphs: smallgraph
g = smallgraph(:karate)
gplot(g)
using Graphs
nodelabel = 1:nv(g)
gplot(g, nodelabel=nodelabel)
gplot(g, nodelabel=nodelabel, nodelabeldist=1.5, nodelabelangleoffset=π/4)
# nodes size proportional to their degree
nodesize = [Graphs.outdegree(g, v) for v in Graphs.vertices(g)]
gplot(g, nodesize=nodesize)
Feed the keyword argument nodefillc
a color array, ensure each node has a color. length(nodefillc)
must be equal |V|
.
using Colors
# Generate n maximally distinguishable colors in LCHab space.
nodefillc = distinguishable_colors(nv(g), colorant"blue")
gplot(g, nodefillc=nodefillc, nodelabel=nodelabel, nodelabeldist=1.8, nodelabelangleoffset=π/4)
# stick out large degree nodes
alphas = nodesize/maximum(nodesize)
nodefillc = [RGBA(0.0,0.8,0.8,i) for i in alphas]
gplot(g, nodefillc=nodefillc)
nodelabelsize = nodesize
gplot(g, nodelabelsize=nodelabelsize, nodesize=nodesize, nodelabel=nodelabel)
edgelabel = 1:Graphs.ne(g)
gplot(g, edgelabel=edgelabel, nodelabel=nodelabel)
edgelabel = 1:Graphs.ne(g)
gplot(g, edgelabel=edgelabel, nodelabel=nodelabel, edgelabeldistx=0.5, edgelabeldisty=0.5)
# nodes membership
membership = [1,1,1,1,1,1,1,1,2,1,1,1,1,1,2,2,1,1,2,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2]
nodecolor = [colorant"lightseagreen", colorant"orange"]
# membership color
nodefillc = nodecolor[membership]
gplot(g, nodefillc=nodefillc)
This is the defaut layout and will be chosen if no layout is specified. The default parameters to the spring layout algorithm can be changed by supplying an anonymous function, e.g., if nodes appear clustered too tightly together, try
layout=(args...)->spring_layout(args...; C=20)
gplot(g, layout=layout, nodelabel=nodelabel)
where C
influences the desired distance between nodes.
gplot(g, layout=random_layout, nodelabel=nodelabel)
gplot(g, layout=circular_layout, nodelabel=nodelabel)
gplot(g, layout=spectral_layout)
nlist = Vector{Vector{Int}}(undef, 2) # two shells
nlist[1] = 1:5 # first shell
nlist[2] = 6:nv(g) # second shell
locs_x, locs_y = shell_layout(g, nlist)
gplot(g, locs_x, locs_y, nodelabel=nodelabel)
gplot(g, linetype="curve")
When using an IDE such as VSCode, Cairo.jl
is required to visualize the plot inside the IDE. When using the REPL, gplothtml
will allow displaying the plot on a browser.
using Compose
# save to pdf
draw(PDF("karate.pdf", 16cm, 16cm), gplot(g))
# save to png
draw(PNG("karate.png", 16cm, 16cm), gplot(g))
# save to svg
draw(SVG("karate.svg", 16cm, 16cm), gplot(g))
Graphs.jl integration
using Graphs
h = watts_strogatz(50, 6, 0.3)
gplot(h)
Arguments
G
Graph to drawlocs_x, locs_y
Locations of the nodes (will be normalized and centered). If not specified, will be obtained from layout
kwarg.Keyword Arguments
layout
Layout algorithm: random_layout
, circular_layout
, spring_layout
, shell_layout
, stressmajorize_layout
, spectral_layout
. Default: spring_layout
NODESIZE
Max size for the nodes. Default: 3.0/sqrt(N)
nodesize
Relative size for the nodes, can be a Vector. Default: 1.0
nodelabel
Labels for the vertices, a Vector or nothing. Default: nothing
nodelabelc
Color for the node labels, can be a Vector. Default: colorant"black"
nodelabeldist
Distances for the node labels from center of nodes. Default: 0.0
nodelabelangleoffset
Angle offset for the node labels. Default: π/4.0
NODELABELSIZE
Largest fontsize for the vertice labels. Default: 4.0
nodelabelsize
Relative fontsize for the vertice labels, can be a Vector. Default: 1.0
nodefillc
Color to fill the nodes with, can be a Vector. Default: colorant"turquoise"
nodestrokec
Color for the nodes stroke, can be a Vector. Default: nothing
nodestrokelw
Line width for the nodes stroke, can be a Vector. Default: 0.0
edgelabel
Labels for the edges, a Vector or nothing. Default: []
edgelabelc
Color for the edge labels, can be a Vector. Default: colorant"black"
edgelabeldistx, edgelabeldisty
Distance for the edge label from center of edge. Default: 0.0
EDGELABELSIZE
Largest fontsize for the edge labels. Default: 4.0
edgelabelsize
Relative fontsize for the edge labels, can be a Vector. Default: 1.0
EDGELINEWIDTH
Max line width for the edges. Default: 0.25/sqrt(N)
edgelinewidth
Relative line width for the edges, can be a Vector. Default: 1.0
edgestrokec
Color for the edge strokes, can be a Vector. Default: colorant"lightgray"
arrowlengthfrac
Fraction of line length to use for arrows. Equal to 0 for undirected graphs. Default: 0.1
for the directed graphsarrowangleoffset
Angular width in radians for the arrows. Default: π/9 (20 degrees)
linetype
Type of line used for edges ("straight", "curve"). Default: "straight"outangle
Angular width in radians for the edges (only used if linetype = "curve
). Default: π/5 (36 degrees)
Reporting Bugs
Filing an issue to report a bug, counterintuitive behavior, or even to request a feature is extremely valuable in helping me prioritize what to work on, so don't hestitate.
Author: JuliaGraphs
Source Code: https://github.com/JuliaGraphs/GraphPlot.jl
License: View license
1656899776
Simple scrolling events for d3 graphs. Based on stack
graph-scroll takes a selection of explanatory text sections and dispatches active
events as different sections are scrolled into to view. These active
events can be used to update a chart's state.
d3.graphScroll()
.sections(d3.selectAll('#sections > div'))
.on('active', function(i){ console.log(i + 'th section active') })
The top most element scrolled fully into view is classed graph-scroll-active
. This makes it easy to highlight the active section with css:
#sections > div{
opacity: .3
}
#sections div.graph-scroll-active{
opacity: 1;
}
To support headers and intro images/text, we use a container element containing the explanatory text and graph.
<h1>Page Title</div>
<div id='container'>
<div id='graph'></div>
<div id='sections'>
<div>Section 0</div>
<div>Section 1</div>
<div>Section 2</div>
</div>
</div>
<h1>Footer</h1>
If these elements are passed to graphScroll as selections with container
and graph
, every element in the graph selection will be classed graph-scroll-graph
if the top of the container is out of view.
d3.graphScroll()
.graph(d3.selectAll('#graph'))
.container(d3.select('#container'))
.sections(d3.selectAll('#sections > div'))
.on('active', function(i){ console.log(i + 'th section active') })
When the graph starts to scroll out of view, position: sticky
keeps the graph element stuck to the top of the page while the text scrolls by.
#container{
position: relative;
}
#sections{
width: 340px;
}
#graph{
margin-left: 40px;
width: 500px;
position: sticky;
top: 0px;
float: right;
}
On mobile centering the graph and sections while adding a some padding for the first slide is a good option:
@media (max-width: 925px) {
#graph{
width: 100%;
margin-left: 0px;
float: none;
}
#sections{
position: relative;
margin: 0px auto;
padding-top: 400px;
}
}
Adjust the amount of pixels before a new section is triggered is also helpful on mobile (Defaults to 200 pixels):
graphScroll.offset(300)
To update or replace a graphScroll instance, pass a string to eventId
to remove the old event listeners:
graphScroll.eventId('uniqueId1')
Author: 1wheel
Source Code: https://github.com/1wheel/graph-scroll
License: MIT license