Have two (or more) node label sets in Julia GraphPlot maybe using Compose?
Asked Answered
A

1

6

Here is a minimal working code from Julia Discourse:

using LightGraphs
using GraphPlot
using Colors

g = graphfamous("karate")

membership = [1,1,1,1,1,1,1,1,2,1,1,1,1,1,2,2,1,1,2,1,2,1,2,1,1,1,1,2,1,1,2,1,1,1]
nodelabels = 1:34
nodecolor = [colorant"lightgrey", colorant"orange"]
nodefillc = nodecolor[membership]

colors = [colorant"lightgray" for i in  1:78]
colors[42] = colorant"orange"

gplot(g, nodefillc=nodefillc, layout=circular_layout, edgestrokec=colors, nodelabel=nodelabels)

Which produces: enter image description here

I succeed to have node labels, from 1 to 34, however, I need to display another type of labels for some specific nodes. e.g., the weight of some nodes. That is, I need, for instance, the weight of node 19 is 100 and the weight of node 1 is 0.001.

Is there a way to display such data? I could node find a relevant keyword in GraphPlot (only nodelabel only accepts a Vector) and I could not find another Julia package that could do it for plotting graphs.

EDIT thanks to @Dan Getz, before posting on SE, I had the same idea as he suggested: try to label the nodes with a string of the format "$i\n $weight" However, the result is highly unsatisfying as you can see in this picture of one of my actual graphs. Node 12 in Orange, separated from its weight 177.0 with \n is not really nice to read!

EDIT thanks to @Przemyslaw Szufel maybe my question could be resolved with Compose (that I actually already use) which is a graphic backend for GraphPlot. Unfortunately it is a bit undocumented despite I and other people asking about it!

enter image description here

Aromatize answered 9/12, 2022 at 11:0 Comment(5)
Haven't tried it yet myself, but did you try changing nodelabels to a vector of string including your extra annotation info? (i.e. nodelabels = ["$i $(weight[i])" for i=1:34] or something like this)Tulle
@DanGetz, thank you for your relevant comment. I had the same idea before asking my question. Please look at the edit I made thanks to you!Aromatize
If you need more than @DanGetz did It should be possible by using Compose which is a graphic backend for GraphPlot. Unfortunately it is seems to be undocumented how to do it despite people were asking such thing. Perhaps you should reframe your question around Compose?Satchel
@PrzemyslawSzufel, done! Question reframed :) Thank youAromatize
If nobody answers I have done what you need with GraphMakie. Unfortunately Makie takes tons of time to load the first plot and hence is quite annoying. Anyway if you do not get GraphPlot answer ask about GraphMakie and I will share my code with you.Satchel
M
1

You could use GraphMakie.jl, which is also compatible with (Light)Graphs.jl and possibly a bit more flexible than GraphPlot.jl.

using Graphs, GraphMakie, Colors

g = smallgraph(:karate)

membership = [1,1,1,1,1,1,1,1,2,1,1,1,1,1,2,2,1,1,2,1,2,1,2,1,1,1,1,2,1,1,2,1,1,1]
nodelabels = repr.(collect(1:34))
nodecolor = [colorant"lightgrey", colorant"orange"]
nodefillc = nodecolor[membership]

colors = [colorant"lightgray" for i in  1:78]
colors[42] = colorant"orange"

fig = Figure(resolution=(500,500))
ax = Axis(fig[1,1])
pos = Shell()(g) # = circular layout
graphplot!(ax, g, 
    layout=_->pos,
    edge_color=colors, 
    node_color=nodefillc, 
    node_size=30, 
    nlabels=nodelabels,
    nlabels_align=(:center, :center)
)
hidedecorations!(ax)
hidespines!(ax)    

# add additional annotation to node 17
weightOffset = Point2(0, 0.045)
text!(ax, "0.001", position=pos[17] - weightOffset, space=:data, align=(:center, :top), fontsize=10)

display(fig)

enter image description here

Mothball answered 21/1, 2023 at 14:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.