# Plotting a weighted tree graph

**URL:** <https://discourse.julialang.org/t/plotting-a-weighted-tree-graph/82637>\
**Category:** Graphs\
**Tags:** graphs\
**Created:** [June 12, 2022, 1:37pm UTC](https://discourse.julialang.org/t/plotting-a-weighted-tree-graph/82637 "2022-06-12T13:37:01Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![devanshu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/devanshu/32/37104_2.png) [@devanshu](https://discourse.julialang.org/u/devanshu)\
**Post date:** [June 12, 2022, 1:37pm UTC](https://discourse.julialang.org/t/plotting-a-weighted-tree-graph/82637/1 "2022-06-12T13:37:01Z")

</div>

I am trying to plot a weighted graph using `SimpleWeightedGraphs` using `GraphPlot`.

```julia
g = SimpleWeightedGraph(5)
add_edge!(g, 1, 2, 0.5)
add_edge!(g, 1, 3, 2.0)
add_edge!(g, 1, 4, 3.5)
add_edge!(g, 1, 5, 5.0)
gplot(g)

```

 ![weighted](https://global.discourse-cdn.com/julialang/original/3X/4/9/49dd614ca2973f4797335e18d2da41938836d2c2.png)  
But, I would like to have it (a) as a tree with vertex 1 as the root, and (b) the edge’s thickness are as per the weights assigned to them. How can I do it?

---

<div class="post-metadata">

**Author:** ![etienne\_dg](https://avatars.discourse-cdn.com/v4/letter/e/fbc32d/32.png) [@etienne\_dg](https://discourse.julialang.org/u/etienne_dg)\
**Post date:** [June 14, 2022, 8:35am UTC](https://discourse.julialang.org/t/plotting-a-weighted-tree-graph/82637/2 "2022-06-14T08:35:59Z")

</div>

```julia
gplot(g, nodelabel=vertices(g), edgelinewidth=weight.(edges(g)))

```

 ![graph](https://global.discourse-cdn.com/julialang/original/3X/3/0/304a802e37ce18e5d159a303f6678c0eff538401.png)

---

<div class="post-metadata">

**Author:** ![devanshu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/devanshu/32/37104_2.png) [@devanshu](https://discourse.julialang.org/u/devanshu)\
**Post date:** [June 14, 2022, 9:29am UTC](https://discourse.julialang.org/t/plotting-a-weighted-tree-graph/82637/3 "2022-06-14T09:29:18Z")

</div>

Thank you! Could you please also address the problem that I would like it to have a tree structure, rather than a star?

---

<div class="post-metadata">

**Author:** ![skleinbo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skleinbo/32/36080_2.png) [@skleinbo](https://discourse.julialang.org/u/skleinbo)\
**Post date:** [June 14, 2022, 9:47am UTC](https://discourse.julialang.org/t/plotting-a-weighted-tree-graph/82637/4 "2022-06-14T09:47:58Z")

</div>

I don’t think `GraphPlot.jl` can do tree layout. But [Home · NetworkLayout.jl](https://juliagraphs.org/NetworkLayout.jl/stable/#Buchheim-Tree-Drawing) can. It is best integrated with [`GraphMakie.jl`](http://juliaplots.org/GraphMakie.jl/stable/) though.

---

<div class="post-metadata">

**Author:** ![etienne\_dg](https://avatars.discourse-cdn.com/v4/letter/e/fbc32d/32.png) [@etienne\_dg](https://discourse.julialang.org/u/etienne_dg)\
**Post date:** [June 14, 2022, 9:49am UTC](https://discourse.julialang.org/t/plotting-a-weighted-tree-graph/82637/5 "2022-06-14T09:49:09Z")

</div>

Yes, I don’t see any tree layout or layered layout, that could be a good addition to GraphPlot

---

<div class="post-metadata">

**Author:** ![devanshu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/devanshu/32/37104_2.png) [@devanshu](https://discourse.julialang.org/u/devanshu)\
**Post date:** [June 14, 2022, 9:55am UTC](https://discourse.julialang.org/t/plotting-a-weighted-tree-graph/82637/6 "2022-06-14T09:55:46Z")

</div>

Thank you, I will check them.

---

<div class="post-metadata">

**Author:** ![cormullion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cormullion/32/49131_2.png) [@cormullion](https://discourse.julialang.org/u/cormullion)\
**Post date:** [June 14, 2022, 11:36am UTC](https://discourse.julialang.org/t/plotting-a-weighted-tree-graph/82637/7 "2022-06-14T11:36:28Z")

</div>

If you want to explore even more possibilities that are possibly still experimental (🙂) , you could try Karnak.jl:

```julia
using Graphs
using SimpleWeightedGraphs
using Karnak

g = SimpleWeightedGraph(5)
add_edge!(g, 1, 2, 0.5)
add_edge!(g, 1, 3, 2.0)
add_edge!(g, 1, 4, 3.5)
add_edge!(g, 1, 5, 5.0)

@drawsvg begin
    background("black")
    sethue("gold")
    drawgraph(g,
        layout=vcat(
            Point(0, -200), # point 1 is at the top
            between.(Point(-200, 150), Point(200, 150), range(0, 1, length=4))
            ),
        vertexshapesizes = 20,
        edgestrokeweights =
            (n, s, d, f, t) -> 2get_weight(g, s, d)
        )
end 

```

 ![Screenshot 2022-06-14 at 12.26.48](https://global.discourse-cdn.com/julialang/original/3X/c/a/ca63ae20ed5146ba9f86246e45def6d80e2dc620.png)

This is merely passing some calculated positions for the vertices.

If you want to use the `buchheim` algorithm from NetworkLayout, you can do it like this;

```julia
g = SimpleWeightedDiGraph(5) # must be a Directed Graph
add_edge!(g, 1, 2, 0.5)
add_edge!(g, 1, 3, 2.0)
add_edge!(g, 1, 4, 3.5)
add_edge!(g, 1, 5, 5.0)

@drawsvg begin
    background("black")
    sethue("cyan")
    drawgraph(g,
        layout=buchheim,
        edgestrokeweights =
            (n, s, d, f, t) -> get_weight(g, s, d)
        )
end

```

 ![Screenshot 2022-06-14 at 12.31.32](https://global.discourse-cdn.com/julialang/original/3X/2/6/265718e8d6d0ae97c667f99c65a4eef4907d4528.png)

The `NetworkLayout.Buchheim()` algorithm lets you also specify the vertex spacing:

```julia
      ...
      layout=Buchheim(nodesize=[1.0, 4.0, 8.0, 16.0]),
      ...

```

 ![Screenshot 2022-06-14 at 12.32.58](https://global.discourse-cdn.com/julialang/original/3X/a/3/a3d260bb0d9f69c8e5b15b01e921ab3e56c34a5f.png)

---

<div class="post-metadata">

**Author:** ![devanshu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/devanshu/32/37104_2.png) [@devanshu](https://discourse.julialang.org/u/devanshu)\
**Post date:** [June 14, 2022, 12:15pm UTC](https://discourse.julialang.org/t/plotting-a-weighted-tree-graph/82637/8 "2022-06-14T12:15:13Z")

</div>

Thank you so much!

---

<div class="post-metadata">

**Author:** ![filchristou](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/filchristou/32/26760_2.png) [@filchristou](https://discourse.julialang.org/u/filchristou)\
**Post date:** [June 14, 2022, 4:53pm UTC](https://discourse.julialang.org/t/plotting-a-weighted-tree-graph/82637/9 "2022-06-14T16:53:40Z")

</div>

As other people mentioned, you can also use [GraphMakie.jl](https://github.com/JuliaPlots/GraphMakie.jl)

`Bucheim` breaks with your graph because it assumes double edges and a node cannot have multiple parent nodes.  
If this is not a deal breaker you can work it around with `SimpleWeightedDiGraph`:

```julia
using GraphMakie

g = SimpleWeightedDiGraph(5)    
add_edge!(g, 1, 2, 0.5)    
add_edge!(g, 1, 3, 2.0)    
add_edge!(g, 1, 4, 3.5)    
add_edge!(g, 1, 5, 5.0)    
     
edws = [get_weight(g, e.src, e.dst) for e in edges(g)]    
            
graphplot(g, layout=NetworkLayout.Buchheim(), edge_width=edws, arrow_size=5 .+ 5 .* edws)                

```

 ![Screenshot from 2022-06-14 18-52-03](https://global.discourse-cdn.com/julialang/original/3X/c/3/c3b1108caecb583c4952bec02fe848d4525d3abe.png)

---

<div class="post-metadata">

**Author:** ![filchristou](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/filchristou/32/26760_2.png) [@filchristou](https://discourse.julialang.org/u/filchristou)\
**Post date:** [June 14, 2022, 5:26pm UTC](https://discourse.julialang.org/t/plotting-a-weighted-tree-graph/82637/10 "2022-06-14T17:26:26Z")

</div>

If `SimpleWeightedDiGraph` is a deal breaker, you can of course get around that by being a little bit more verbose, i.e. making a directed graph representation just for plotting:

_(maybe there is an easier way, but that came on top of my head)_

```julia
using SparseArrays
                                
g = SimpleWeightedGraph(5) 
add_edge!(g, 1, 2, 0.5)    
add_edge!(g, 1, 3, 2.0)    
add_edge!(g, 1, 4, 3.5)    
add_edge!(g, 1, 5, 5.0)
                                                          
# directed graph equivalent just for plotting
sdg = let                     
    adg = adjacency_matrix(g)
    [adg[i,j] = 0.0 for i in vertices(g) for j in vertices(g) if i > j];
    dropzeros!(adg);        
    SimpleDiGraph(adg)
end                       

edws = [get_weight(g, e.src, e.dst) for e in edges(sdg)] 

# same plotting as before with the directed representation
graphplot(sdg, layout=NetworkLayout.Buchheim(), edge_width=edws, arrow_size=5 .+ 5 .* edws)

```

---

<div class="post-metadata">

**Author:** ![devanshu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/devanshu/32/37104_2.png) [@devanshu](https://discourse.julialang.org/u/devanshu)\
**Post date:** [June 15, 2022, 11:11am UTC](https://discourse.julialang.org/t/plotting-a-weighted-tree-graph/82637/11 "2022-06-15T11:11:35Z")

</div>

Hi, thank you! I was wondering if there is any way to assign edge styles, like dash, dashdot etc.? I looked up the documentation, but not sure I see anything that helps! Also how to save the graph as a pdf?

---

<div class="post-metadata">

**Author:** ![filchristou](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/filchristou/32/26760_2.png) [@filchristou](https://discourse.julialang.org/u/filchristou)\
**Post date:** [June 15, 2022, 12:28pm UTC](https://discourse.julialang.org/t/plotting-a-weighted-tree-graph/82637/12 "2022-06-15T12:28:43Z")

</div>

You can save the graph as every figure in the `Makie` ecosystem.  
For example when using the `CairoMakie` backend

```julia
using CairoMakie
f,a,p = graphplot(sdg, layout=NetworkLayout.Buchheim(), edge_width=edws, arrow_size=5 .+ 5 .* edws)
save("mygraphplot.pdf", f)

```

> [@devanshu](#):
>
> f there is any way to assign edge styles, like dash, dashdot etc.?

`GraphMakie` uses the [`linesegments`](https://makie.juliaplots.org/stable/examples/plotting_functions/linesegments/) function in order to plot edges. By using the `edge_attr` attribute, you can pass whatever namedtuple that will be forwarded to the `linesegments`. For example if you want dashed edges you can do:

```julia
f,a,p = graphplot(sdg, layout=NetworkLayout.Buchheim(), edge_width=edws, arrow_size=5 .+ 5 .* edws, edge_attr=(linestyle=:dash,))    

```

Be careful of the single-namedtuple ending with a comma.

 ![Screenshot from 2022-06-15 14-26-42](https://global.discourse-cdn.com/julialang/original/3X/a/6/a67e0465049bcfb221d339c98c5fddc5da61239b.png)

---

<div class="post-metadata">

**Author:** ![devanshu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/devanshu/32/37104_2.png) [@devanshu](https://discourse.julialang.org/u/devanshu)\
**Post date:** [June 15, 2022, 12:49pm UTC](https://discourse.julialang.org/t/plotting-a-weighted-tree-graph/82637/13 "2022-06-15T12:49:32Z")

</div>

Thank you! This helps. One final thing, is there any attribute by which I can control the edge length? I mean the distance between the nodes, the default seems too long.

---

<div class="post-metadata">

**Author:** ![filchristou](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/filchristou/32/26760_2.png) [@filchristou](https://discourse.julialang.org/u/filchristou)\
**Post date:** [June 15, 2022, 2:27pm UTC](https://discourse.julialang.org/t/plotting-a-weighted-tree-graph/82637/14 "2022-06-15T14:27:53Z")

</div>

If you want a different layout you need to modify the layout function or pass in different parameters as defined e.g. in [`Buchheim`](https://juliagraphs.org/NetworkLayout.jl/stable/#Buchheim-Tree-Drawing) and demonstrated by cormullion.

But I think what you really want is a different aspect of your plotted data.  
No matter how closely you will plot the children with the `nodesize` from `Buchheim`, `Makie` will always zoom, as a result always looking the same. But you can change the aspect ratio, e.g.:

```julia
f = Figure()
# width of three times the height.
ax = Axis(f[1,1], aspect=AxisAspect(3))
# same plot command
graphplot!(ax, sdg, layout=NetworkLayout.Buchheim(), edge_width=edws, arrow_size=5 .+ 5 .* edws, edge_attr=(linestyle=:dash,))  

```

![Screenshot from 2022-06-15 16-24-44](https://global.discourse-cdn.com/julialang/original/3X/d/2/d2d753a65f913c72ef9ec0467cc209419ac6eca9.png)

---

<div class="post-metadata">

**Author:** ![devanshu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/devanshu/32/37104_2.png) [@devanshu](https://discourse.julialang.org/u/devanshu)\
**Post date:** [June 16, 2022, 5:31am UTC](https://discourse.julialang.org/t/plotting-a-weighted-tree-graph/82637/15 "2022-06-16T05:31:14Z")

</div>

Thank you! Also, specifying the `width` of the axis makes it look a little nicer!
