Graphs.jl
Graphs.jl copied to clipboard
human-readable output for simple graphs
Fix #139
Should I omit vertices with degree 0 ?
julia> Graph()
{0, 0} undirected simple Int64 graph
julia> Graph(5)
{5, 0} undirected simple Int64 graph
1 => []
2 => []
3 => []
4 => []
5 => []
julia> Graph(100)
{100, 0} undirected simple Int64 graph
1 => []
2 => []
3 => []
4 => []
5 => []
6 => []
⋮
95 => []
96 => []
97 => []
98 => []
99 => []
100 => []
julia> Graph{Int16}(5)
{5, 0} undirected simple Int16 graph
1 => []
2 => []
3 => []
4 => []
5 => []
julia> path_graph(5)
{5, 4} undirected simple Int64 graph
1 => [2]
2 => [1, 3]
3 => [2, 4]
4 => [3, 5]
5 => [4]
julia> path_graph(100)
{100, 99} undirected simple Int64 graph
1 => [2]
2 => [1, 3]
3 => [2, 4]
4 => [3, 5]
5 => [4, 6]
6 => [5, 7]
⋮
95 => [94, 96]
96 => [95, 97]
97 => [96, 98]
98 => [97, 99]
99 => [98, 100]
100 => [99]
julia> path_graph(100) # REPL with minimum height
{100, 99} undirected simple Int64 graph …
julia> path_graph(100) # slowly increasing height
{100, 99} undirected simple Int64 graph
⋮
julia> path_graph(100)
{100, 99} undirected simple Int64 graph
1 => [2]
⋮
julia> path_graph(100)
{100, 99} undirected simple Int64 graph
1 => [2]
⋮
100 => [99]
julia> erdos_renyi(1000, 0.5)
{1000, 249729} undirected simple Int64 graph
1 => [2, 3, 5, 6, 7, 9, 10, 16, 17, 19 … 977, 980, 981, 983, 987, 992, 993, 994, 995, 999]
2 => [1, 3, 6, 7, 13, 14, 16, 17, 18, 19 … 984, 985, 987, 988, 991, 994, 996, 997, 998, 1000]
3 => [1, 2, 6, 7, 9, 11, 13, 16, 17, 18 … 978, 979, 980, 981, 987, 992, 994, 998, 999, 1000]
4 => [6, 9, 11, 16, 17, 20, 21, 22, 24, 25 … 984, 985, 987, 988, 992, 994, 995, 997, 999, 1000]
5 => [1, 6, 7, 10, 15, 17, 18, 19, 21, 25 … 984, 986, 988, 991, 994, 995, 996, 998, 999, 1000]
6 => [1, 2, 3, 4, 5, 7, 8, 9, 11, 15 … 977, 980, 983, 984, 989, 993, 995, 996, 998, 1000]
⋮
995 => [1, 4, 5, 6, 7, 10, 11, 12, 13, 14 … 983, 985, 986, 987, 988, 989, 992, 994, 998, 1000]
996 => [2, 5, 6, 8, 9, 10, 13, 14, 15, 16 … 979, 980, 982, 985, 987, 990, 991, 993, 999, 1000]
997 => [2, 4, 7, 8, 9, 11, 13, 15, 18, 22 … 985, 988, 989, 990, 991, 992, 993, 994, 998, 1000]
998 => [2, 3, 5, 6, 7, 8, 9, 11, 13, 16 … 984, 985, 988, 990, 991, 994, 995, 997, 999, 1000]
999 => [1, 3, 4, 5, 8, 9, 11, 12, 14, 15 … 975, 977, 978, 982, 983, 984, 986, 989, 996, 998]
1000 => [2, 3, 4, 5, 6, 7, 11, 13, 17, 18 … 986, 989, 991, 992, 993, 994, 995, 996, 997, 998]
Codecov Report
Merging #148 (110545f) into master (48cb6ec) will increase coverage by
0.49%
. The diff coverage is78.04%
.
@@ Coverage Diff @@
## master #148 +/- ##
==========================================
+ Coverage 97.54% 98.04% +0.49%
==========================================
Files 109 109
Lines 6314 5779 -535
==========================================
- Hits 6159 5666 -493
+ Misses 155 113 -42
I am not sure if I like this. For small graph it makes sense, but for larger graphs like your last example, I feel like it adds too much noise, without providing much information to the user.
I wonder if a small adjacency matrix with some unicode characters would be more useful?
Another point, if we are going for printing the whole graph, maybe we can use do-syntax instead of =>
? https://en.wikipedia.org/wiki/DOT_%28graph_description_language%29
Something like 2 -- {1 3}
(or with commas) and 2 -> {1 3}
for directed graphs?
Do you have an idea for an adjacency matrix representation? A dotted representation like for sparse arrays?
I tried a circle plot, not sure if this is better, even for small graphs (it looks better by copy-pasting it in the REPL). For bigger graphs, maybe we can use some scaling on the density of edges passing through a point but it gets time consuming, and I'm not sure it will be much more informative. IMO, I prefer printing the outneighbors lists.
julia> plot(stdout, erdos_renyi(5, 0.5))
{5, 6} undirected simple Int64 graph
⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠴1⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⡠⠒⠁⠀⠀⢱⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⣀⠔⠉⠀⠀⠀⠀⠀⠀⢇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⢀⡤⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀5⠦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢱⠀⠀⠀⠀⠀⢀⠴2⠀
⠀⠘⡄⠈⠓⢄⡀⠀⠀⠀⠀⠀⠀⠀⠀⢇⠀⢀⡠⠚⠁⢠⠃⠀
⠀⠀⢸⠀⠀⠀⠉⠒⣄⠀⠀⠀⠀⠀⠀⣸⡖⠉⠀⠀⠀⡇⠀⠀
⠀⠀⠀⢇⠀⠀⠀⠀⠀⠙⠤⣀⣀⠴⠉⠀⢱⠀⠀⠀⡸⠀⠀⠀
⠀⠀⠀⠸⡀⠀⠀⠀⠀⢀⡤⠚⠓⢤⡀⠀⠀⢇⠀⢀⠇⠀⠀⠀
⠀⠀⠀⠀⢱⠀⠀⡠⠖⠁⠀⠀⠀⠀⠈⠲⢄⠘⡄⡎⠀⠀⠀⠀
⠀⠀⠀⠀⠈4⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙3⠁⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
julia> plot(stdout, erdos_renyi(7, 0.5))
{7, 14} undirected simple Int64 graph
⠀⠀⠀⠀⠀⠀⠀⠀⢀⡠⢶1⢷⠦⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⢀⡠⠔⠚⠁⡔⠁⠀⠀⠑⡄⠈⠓⠤⢄⡀⠀⠀⠀⠀
⠀⠀⠀7⡿⡒⠒⢲⠚⠒⠒⠒⠒⠒⠚⢳⡒⠒⠒⠛2⠀⠀⠀
⠀⠀⠀⠀⠑⢌⡕⠓⠤⡀⠀⠀⠀⠀⠀⠀⠘⢄⠀⠀⡇⡇⠀⠀
⠀⠀⠀⠀⢠⠊⠢⡀⠀⠈⠑⠒⠤⡀⠀⠀⠀⠀⠣⣼⠀⢸⡀⠀
⠀⠀⠀⡔⠁⠀⠀⠑⢆⠀⠀⠀⠀⠈⠑⠒⠤⡀⠀⡞⢢⠀⢇⠀
⠀⣠⠊⠀⠀⠀⠀⠀⠈⠲⡀⠀⠀⠀⠀⠀⠀⠈⢱⠓⠤⡑⣼⡀
6⣷⢖⡒⠒⠒⠒⠒⠒⠒⠛⢖⠒⠒⠒⠒⠒⠒⡞⠒⠒⠚⣻3
⠀⠀⠓⡌⠑⠢⢤⡀⠀⠀⠀⠈⠱⡀⠀⠀⠀⢰⠁⠀⢠⠚⠀⠀
⠀⠀⠀⠘⢢⡀⠀⠈⠑⠒⢤⣀⠀⠈⢆⠀⠀⡜⢀⡔⠁⠀⠀⠀
⠀⠀⠀⠀⠀⠘⢄⠀⠀⠀⠀⠀⠉⠒⠢⣱⣤⡣⠃⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀5⠉⠉⠉⠉⠉⠉⠉⠉4⠀⠀⠀⠀⠀⠀⠀
julia> plot(stdout, erdos_renyi(10, 0.5))
{10, 19} undirected simple Int64 graph
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⢦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⣠⠒⠶⠶⣒⡒⢲⢻⠒⠳⡖⠒⠒⠒⢢⠀⠀⠀⠀⠀
⠀⠀⢀⡰⠁⠀⠀⠀⠀⢈⡟⢺⠢⠤⣘⣄⠀⠀⢸⠀⠀⠀⠀⠀
⠀⢠⠎⠀⠀⠀⠀⠀⠀⡸⠀⢸⠀⠀⠀⠈⠫⡑⢺⠤⣀⣀⠀⠀
⠀⠹⡶⡢⢤⣀⠀⠀⢠⠃⠀⢸⠀⠀⠀⠀⠀⠑⣼⡤⢔⢶⣷⠀
⠀⠀⠘⢬⠓⢄⡉⠑⡞⠤⢄⣸⣀⡠⠤⠒⠊⢉⣸⢺⡥⢣⢻⠀
⠀⠀⠀⠀⢣⡀⣉⣲⣥⠒⠊⢹⠉⠑⠒⣤⢖⣉⢸⠚⠓⡇⢸⠀
⠀⣀⣤⣔⣚⣙⣄⣇⣀⣙⣤⣸⣀⣴⣉⣀⣀⣰⣻⣓⣺⣼⣾⠀
⠀⠘⢆⠀⠀⠀⡜⢆⡀⢀⡤⢺⠓⢤⡀⢀⠞⠀⢸⢀⠇⡰⠃⠀
⠀⠀⠈⠲⡀⢰⠁⡠⠷⡁⠀⢸⠀⠀⡸⠺⢄⠀⢸⣎⠖⠁⠀⠀
⠀⠀⠀⠀⠙⠾⣋⣀⠀⠉⢆⢸⢀⠎⠁⠀⠀⠙⠺⠋⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠉⠒⠚⠿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
julia> plot(stdout, erdos_renyi(20, 0.5))
{20, 95} undirected simple Int64 graph
⠀⠀⠀⠀⠀⠀⢀⣠⣤⣶⢶⣷⣯⣶⣦⣤⡀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⣠⣶⣿⣿⡿⣿⣟⠶⣿⣿⣿⣿⢾⢶⣦⠀⠀⠀⠀⠀
⠀⠀⢠⣴⣿⣿⣿⣷⣷⣿⢷⡽⣿⣿⣿⢿⣷⣿⣯⣦⣤⡀⠀⠀
⠀⢠⣾⣿⣿⣿⡮⢿⣿⡭⢟⣿⡻⣛⣽⣿⣿⣬⣿⣟⣻⣺⣆⠀
⢠⣿⣿⣾⣿⣿⡿⡽⣿⣠⠛⣼⢟⣷⣿⣽⢎⢽⣅⡬⠶⣻⣿⠀
⣼⣿⣿⣽⢳⣷⣟⣝⣿⣿⣾⣿⣱⣷⢿⢿⠯⣿⢌⣢⡮⢫⠻⡄
⠘⣿⣻⣿⣻⡾⣿⣻⣷⣿⢿⣏⣟⡿⣷⢼⣄⣯⢾⢿⣗⣇⣾⠁
⠀⣿⣿⣿⣿⣽⣶⣷⡟⡹⣭⣽⡿⡏⢏⣻⢿⡲⠫⢷⡾⣿⣏⠀
⠀⠘⢿⣿⣿⢿⣏⣟⣯⡕⢣⢯⣻⣽⣺⣸⣿⣯⠗⣾⣿⣽⠃⠀
⠀⠀⠘⠻⣽⢧⣿⣿⡷⣱⡮⡤⡞⣷⣿⣿⣧⣿⣼⣾⡿⠃⠀⠀
⠀⠀⠀⠀⠙⠾⣿⣿⣿⣿⣯⣭⣯⢯⣿⣿⣿⣿⠷⠋⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠈⠛⠛⠛⠿⠿⠿⠛⠛⠁⠀⠀⠀⠀⠀⠀⠀