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 .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
*.jl.cov
*.jl.*.cov
*.jl.mem
Manifest.toml
32 changes: 32 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name = "GraphRecipes"
uuid = "bd48cda9-67a9-57be-86fa-5b3c104eda73"
version = "0.5.0"

[deps]
AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c"
GeometryTypes = "4d00f742-c7ba-57c2-abde-4428a4b178cb"
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
Interpolations = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59"
LightGraphs = "093fc24a-ae57-5d10-9952-331d41423f4d"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
NaNMath = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3"
NetworkLayout = "46757867-2c16-5918-afeb-47bfcb05e46a"
PlotUtils = "995b91a9-d308-5afd-9ec6-746e21dbc043"
RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"

[compat]
julia = "^1"

[extras]
ImageMagick = "6218d12a-5da1-5696-b52f-db25d2ecc6d1"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
VisualRegressionTests = "34922c18-7c2a-561c-bac1-01e79b2c4c92"

[targets]
test = ["VisualRegressionTests", "LinearAlgebra", "Plots", "ImageMagick", "Random", "SparseArrays", "Test"]
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,27 @@ plot(AbstractFloat, method=:tree, fontsize=10, nodeshape=:ellipse)

```
![](assets/julia_type_tree.png)


#### `AbstractTrees` Trees

```julia
using AbstractTrees

AbstractTrees.children(d::Dict) = [p for p in d]
AbstractTrees.children(p::Pair) = AbstractTrees.children(p[2])
function AbstractTrees.printnode(io::IO, p::Pair)
str = isempty(AbstractTrees.children(p[2])) ? string(p[1], ": ", p[2]) : string(p[1], ": ")
print(io, str)
end

d = Dict(:a => 2,:d => Dict(:b => 4,:c => "Hello"),:e => 5.0)

using GraphRecipes
using Plots
default(size=(1000, 1000))

plot(TreePlot(d), method=:tree, fontsize=10, nodeshape=:ellipse)

```
![](assets/julia_dict_tree.png)
9 changes: 0 additions & 9 deletions REQUIRE

This file was deleted.

Binary file added assets/julia_dict_tree.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/GraphRecipes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ include("utils.jl")
include("graph_layouts.jl")
include("graphs.jl")
include("misc.jl")
include("trees.jl")

end # module
60 changes: 60 additions & 0 deletions src/trees.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import AbstractTrees
using AbstractTrees: children

export TreePlot

"""
TreePlot(root)

Wrap a tree-like object for plotting. Uses `AbstractTrees.children()` to recursively add children to the plot and `AbstractTrees.printnode()` to generate the labels.

# Example

```julia
using AbstractTrees, GraphRecipes
AbstractTrees.children(d::Dict) = [p for p in d]
AbstractTrees.children(p::Pair) = AbstractTrees.children(p[2])
function AbstractTrees.printnode(io::IO, p::Pair)
str = isempty(AbstractTrees.children(p[2])) ? string(p[1], ": ", p[2]) : string(p[1], ": ")
print(io, str)
end

d = Dict(:a => 2,:d => Dict(:b => 4,:c => "Hello"),:e => 5.0)

plot(TreePlot(d))
````
"""
struct TreePlot{T}
root::T
end

function add_children!(nodes, source, destiny, node, parent_idx)
for child in children(node)
push!(nodes, child)
child_idx = length(nodes)
push!(source, parent_idx)
push!(destiny, child_idx)
add_children!(nodes, source, destiny, child, child_idx)
end
end

function string_from_node(node)
io = IOBuffer()
AbstractTrees.printnode(io, node)
String(take!(io))
end

# recursively build a graph of children of `tree_wrapper.root`
@recipe function f(tree_wrapper::TreePlot; namefunc = string_from_node )
root = tree_wrapper.root
# recursively add children
nodes = Any[root]
source, destiny = Int[], Int[]
add_children!(nodes, source, destiny, root, 1)

# set up the graphplot
names := map(namefunc, nodes)
method --> :buchheim
root --> :top
GraphPlot((source, destiny))
end
3 changes: 0 additions & 3 deletions test/REQUIRE

This file was deleted.

15 changes: 15 additions & 0 deletions test/generate_readme_images.jl
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,18 @@ savefig("AST_example.png")

plot(AbstractFloat, method=:tree, fontsize=10, nodeshape=:ellipse)
savefig("julia_type_tree.png")


# `AbstractTrees` example
using AbstractTrees
AbstractTrees.children(d::Dict) = [p for p in d]
AbstractTrees.children(p::Pair) = AbstractTrees.children(p[2])
function AbstractTrees.printnode(io::IO, p::Pair)
str = isempty(AbstractTrees.children(p[2])) ? string(p[1], ": ", p[2]) : string(p[1], ": ")
print(io, str)
end

d = Dict(:a => 2,:d => Dict(:b => 4,:c => "Hello"),:e => 5.0)

plot(TreePlot(d), method=:tree, fontsize=10, nodeshape=:ellipse)
savefig("julia_dict_tree.png")
12 changes: 12 additions & 0 deletions test/readme.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ using LinearAlgebra
using SparseArrays
using ImageMagick

using AbstractTrees
AbstractTrees.children(d::Dict) = [p for p in d]
AbstractTrees.children(p::Pair) = AbstractTrees.children(p[2])
function AbstractTrees.printnode(io::IO, p::Pair)
str = isempty(AbstractTrees.children(p[2])) ? string(p[1], ": ", p[2]) : string(p[1], ": ")
print(io, str)
end

istravis = "TRAVIS" ∈ keys(ENV)

default(show=false, reuse=true)
Expand Down Expand Up @@ -68,4 +76,8 @@ cd("../assets")
default(size=(1000, 1000))
@plottest plot(code, fontsize=10, shorten=0.01, axis_buffer=0.15, nodeshape=:rect) "AST_example.png" popup=!istravis tol=0.02
@plottest plot(AbstractFloat, method=:tree, fontsize=10, nodeshape=:ellipse) "julia_type_tree.png" popup=!istravis tol=0.2

d = Dict(:a => 2,:d => Dict(:b => 4,:c => "Hello"),:e => 5.0)
@plottest plot(TreePlot(d), method=:tree, fontsize=10, nodeshape=:ellipse) "julia_dict_tree.png" popup=!istravis tol=0.2

end