GraphMakie

This is the Documentation for GraphMakie.

This Package consists of two parts: a plot recipe for graphs types from LightGraphs.jl and some helper functions to add interactions to those plots.

There are also plot examples and interaction examples.

graphplot recipe

GraphMakie.graphplotFunction
graphplot(graph::AbstractGraph)
graphplot!(ax, graph::AbstractGraph)

Creates a plot of the network graph. Consists of multiple steps:

  • Layout the nodes: the layout attribute is has to be a function f(adj_matrix)::pos where pos is either an array of Point2f0 or (x, y) tuples
  • plot edges as linesegments-plot
  • plot nodes as scatter-plot
  • if nlabels!=nothing plot node labels as text-plot
  • if elabels!=nothing plot edge labels as text-plot

The main attributes for the subplots are exposed as attributes for graphplot. Additional attributes for the scatter, linesegments and text plots can be provided as a named tuples to node_attr, edge_attr, nlabels_attr and elabels_attr.

Most of the arguments can be either given as a vector of length of the edges/nodes or as a single value. One might run into errors when changing the underlying graph and therefore changing the number of Edges/Nodes.

Attributes

Available attributes and their defaults for Combined{GraphMakie.graphplot, T} where T are:

  edge_attr         Attributes with 0 entries
  edge_color        :black
  edge_width        1.0
  elabels           "nothing"
  elabels_align     (:center, :bottom)
  elabels_attr      Attributes with 0 entries
  elabels_color     :black
  elabels_distance  0.0
  elabels_offset    Float32[0.0, 0.0]
  elabels_opposite  Int64[]
  elabels_rotation  "nothing"
  elabels_shift     0.0
  elabels_textsize  20
  layout            NetworkLayout.Spring.layout
  nlabels           "nothing"
  nlabels_align     (:left, :bottom)
  nlabels_attr      Attributes with 0 entries
  nlabels_color     :black
  nlabels_offset    Float32[0.0, 0.0]
  nlabels_textsize  20
  node_attr         Attributes with 0 entries
  node_color        :gray65
  node_marker       Circle{T} where T
  node_size         8
source

Interactions

GraphMakie.jl provides some helper functions to register interactions to your graph plot. There are special Interaction types for hovering, clicking and draging nodes and edges. For more information on the axis interaction please consult the Makie.jl docs.

The general idea is to create some handler type, provide some action function and register it as an interaction with the axes.

Click interactions

GraphMakie.NodeClickHandlerFunction
NodeClickHandler(fun)

Initializes ClickHandler for nodes. Calls function

fun(idx, event, axis)

on left-click events where idx is the node index.

Example

julia> using AbstractPlotting.Colors
julia> g = wheel_digraph(10)
julia> f, ax, p = graphplot(g, node_size=30, node_color=[colorant"red" for i in 1:nv(g)])
julia> function action(idx, event, axis)
           p.node_color[][idx] = rand(RGB)
           p.node_color[] = p.node_color[]
       end
julia> register_interaction!(ax, :nodeclick, NodeClickHandler(action))
source
GraphMakie.EdgeClickHandlerFunction
EdgeClickHandler(fun)

Initializes ClickHandler for edges. Calls function

fun(idx, event, axis)

on left-click events where idx is the edge index.

Example

julia> using AbstractPlotting.Colors
julia> g = wheel_digraph(10)
julia> f, ax, p = graphplot(g, edge_width=4, edge_color=[colorant"black" for i in 1:ne(g)])
julia> function action(idx, event, axis)
           p.edge_color[][idx] = rand(RGB)
           p.edge_color[] = p.edge_color[]
       end
julia> register_interaction!(ax, :edgeclick, EdgeClickHandler(action))
source

Hover interactions

GraphMakie.NodeHoverHandlerFunction
NodeHoverHandler(fun)

Initializes HoverHandler for nodes. Calls function

fun(hoverstate, idx, event, axis)

with hoverstate=true on hover and false at the end of hover. idx is the node index.

Example

julia> g = wheel_digraph(10)
julia> f, ax, p = graphplot(g, node_size = [20 for i in 1:nv(g)])
julia> function action(state, idx, event, axis)
           p.node_size[][idx] = state ? 40 : 20
           p.node_size[] = p.node_size[] #trigger observable
       end
julia> register_interaction!(ax, :nodehover, NodeHoverHandler(action))
source
GraphMakie.EdgeHoverHandlerFunction
EdgeHoverHandler(fun)

Initializes HoverHandler for edges. Calls function

fun(hoverstate, idx, event, axis)

with hoverstate=true on hover and false at the end of hover. idx is the edge index.

Example

julia> g = wheel_digraph(10)
julia> f, ax, p = graphplot(g, edge_width = [3.0 for i in 1:ne(g)])
julia> function action(state, idx, event, axis)
           p.edge_width[][idx] = state ? 6.0 : 3.0
           p.edge_width[] = p.edge_width[] #trigger observable
       end
julia> register_interaction!(ax, :edgehover, EdgeHoverHandler(action))
source

Drag interactions

GraphMakie.NodeDragHandlerFunction
NodeDragHandler(fun)

Initializes DragHandler for Nodes. Calls function

fun(dragstate, idx, event, axis)

where dragstate=true during the drag and false at the end of the drag, the last time fun is triggered. idx is the node index.

Example

julia> g = wheel_digraph(10)
julia> f, ax, p = graphplot(g, node_size=20)
julia> deregister_interaction!(ax, :rectanglezoom)
julia> function action(state, idx, event, axis)
           p[:node_positions][][idx] = event.data
           p[:node_positions][] = p[:node_positions][]
       end
julia> register_interaction!(ax, :nodedrag, NodeDragHandler(action))
source
GraphMakie.EdgeDragHandlerFunction
EdgeDragHandler(fun)

Initializes DragHandler for Edges. Calls function

fun(dragstate, idx, event, axis)

where dragstate=true during the drag and false at the end of the drag, the last time fun is triggered. idx is the edge index.

Example

julia> g = wheel_digraph(10)
julia> f, ax, p = graphplot(g, edge_width=3)
julia> deregister_interaction!(ax, :rectanglezoom)
julia> mutable struct EdgeDragAction
           init::Union{Nothing, Point2f0} # save click position
           src::Union{Nothing, Point2f0}  # save src vertex position
           dst::Union{Nothing, Point2f0}  # save dst vertex position
           EdgeDragAction() = new(nothing, nothing, nothing)
       end
julia> function (action::EdgeDragAction)(state, idx, event, axis)
           edge = collect(edges(g))[idx]
           if state == true
               if action.src===action.dst===action.init===nothing
                   action.init = event.data
                   action.src = p[:node_positions][][edge.src]
                   action.dst = p[:node_positions][][edge.dst]
               end
               offset = event.data - action.init
               p[:node_positions][][edge.src] = action.src + offset
               p[:node_positions][][edge.dst] = action.dst + offset
               p[:node_positions][] = p[:node_positions][] # trigger change
           elseif state == false
               action.src = action.dst = action.init =  nothing
           end
       end
julia> handler = EdgeDragHandler(EdgeDragAction())
julia> register_interaction!(ax, :edgedrag, handler)
source