JuliaGraphs / GraphPlot.jl

Graph visualization for Julia.
http://JuliaGraphs.github.io/GraphPlot.jl/
Other
198 stars 62 forks source link

Plots not displaying #144

Open axmat opened 3 years ago

axmat commented 3 years ago

Hi, gplot is not displaying the graph.

When I run the first example in the README I get the following errors:

julia> using LightGraphs

julia> using GraphPlot

julia> g = smallgraph(:karate)
{34, 78} undirected simple Int64 graph

julia> gplot(g)
Compose.Context(Measures.BoundingBox{Tuple{Measures.Length{:w,Float64},Measures.Length{:h,Float64}},Tuple{Measures.Length{:w,Float64},Measures.Length{:h,Float64}}}((0.0w, 0.0h), (1.0w, 1.0h)), Compose.UnitBox{Float64,Float64,Float64,Float64}(-1.2, -1.2, 2.4, 2.4, 0.0mm, 0.0mm, 0.0mm, 0.0mm), nothing, nothing, nothing, List([Compose.Context(Measures.BoundingBox{Tuple{Measures.Length{:w,Float64},Measures.Length{:h,Float64}},Tuple{Measures.Length{:w,Float64},Measures.Length{:h,Float64}}}((0.0w, 0.0h), (1.0w, 1.0h)), nothing, nothing, nothing, nothing, List([]), List([Compose.Form{Compose.LinePrimitive}(Compose.LinePrimitive[Compose.LinePrimitive{Tuple{Measures.Measure,Measures.Measure}}(Tuple{Measures.Measure,Measures.Measure}[(0.08934610842720356cx, -0.37704406202874835cy), (-0.18110982229451952cx, -0.3771993781974277cy)]), Compose.LinePrimitive{Tuple{Measures.Measure,Measures.Measure}}(Tuple{Measures.Measure,Measures.Measure}[(0.10864119559154817cx, -0.3412110610057567cy), (-0.14438439942069048cx, 0.0430386663652027cy)]), Compose.LinePrimitive{Tuple{Measures.Measure,Measures.Measure}}(Tuple{Measures.Measure,Measures.Measure}[(0.10735415039250729cx, -0.34209255032107505cy), (0.07557145491616724cx, -0.29745151266003794cy)]), Compose.LinePrimitive{Tuple{Measures.Measure,Measures.Measure}}(Tuple{Measures.Measure,Measures.Measure}[(0.1750722862452998cx, -0.37842689658578194cy), (0.5928736834516073cx, -0.3921495602642345cy)]), Compose.LinePrimitive{Tuple{Measures.Measure,Measures.Measure}}(Tuple{Measures.Measure,Measures.Measure}[(0.16535217408878897cx, -0.4042323759982464cy), (0.6036547347840725cx, -0.7642379879557237cy)]), Compose.LinePrimitive{Tuple{Measures.Measure,Measures.Measure}}(Tuple{Measures.Measure,Measures.Measure}[(0.17150983704153394cx, -0.3941834358800225cy), (0.6816013321373464cx, -0.6170241369972667cy)]), Compose.LinePrimitive{Tuple{Measures.Measure,Measures.Measure}}(Tuple{Measures.Measure,Measures.Measure}[(0.08937032314251579cx, -0.3784604170194491cy), (-0.021216068699521737cx, -0.3821792233353336cy)]), Compose.LinePrimitive{Tuple{Measures.Measure,Measures.Measure}}(Tuple{Measures.Measure,Measures.Measure}[(0.10019826508575921cx, -0.3485098645093131cy), (-0.3299338593121275cx, 0.03443622118279489cy)]), Compose.LinePrimitive{Tuple{Measures.Measure,Measures.Measure}}(Tuple{Measures.Measure,Measures.Measure}[(0.17032482342164668cx, -0.39667433023864823cy), (0.5025002454156248cx, -0.5680174547118075cy)]), Compose.LinePrimitive{Tuple{Measures.Measure,Measures.Measure}}(Tuple{Measures.Measure,Measures.Measure}[(0.14114662761842545cx, -0.4189546754944887cy), (0.2558957619379454cx, -0.9580647646867049cy)])  …  Compose.LinePrimitive{Tuple{Measures.Measure,Measures.Measure}}(Tuple{Measures.Measure,Measures.Measure}[(-0.21223710721029948cx, 0.6554043704716472cy), (-0.5200992343482614cx, 0.48007117094537083cy)]), Compose.LinePrimitive{Tuple{Measures.Measure,Measures.Measure}}(Tuple{Measures.Measure,Measures.Measure}[(-0.19639427035505516cx, 0.4590053428302107cy), (-0.13132781004924035cx, 0.44387868208784004cy)]), Compose.LinePrimitive{Tuple{Measures.Measure,Measures.Measure}}(Tuple{Measures.Measure,Measures.Measure}[(-0.28100944071680134cx, 0.46739006684625967cy), (-0.5145012642343073cx, 0.4601769270067843cy)]), Compose.LinePrimitive{Tuple{Measures.Measure,Measures.Measure}}(Tuple{Measures.Measure,Measures.Measure}[(-0.7075827499792824cx, 0.7945266626610871cy), (-0.6408449512264207cx, 0.5139753951614744cy)]), Compose.LinePrimitive{Tuple{Measures.Measure,Measures.Measure}}(Tuple{Measures.Measure,Measures.Measure}[(-0.7007560847102858cx, 0.796769548300042cy), (-0.5741043207340182cx, 0.49832090464644413cy)]), Compose.LinePrimitive{Tuple{Measures.Measure,Measures.Measure}}(Tuple{Measures.Measure,Measures.Measure}[(-0.6002868254792169cx, 0.06008007593112684cy), (-0.6277448370353009cx, 0.4295079515267264cy)]), Compose.LinePrimitive{Tuple{Measures.Measure,Measures.Measure}}(Tuple{Measures.Measure,Measures.Measure}[(-0.5932642034089134cx, 0.06002528351643539cy), (-0.5612001633442053cx, 0.41615113906534257cy)]), Compose.LinePrimitive{Tuple{Measures.Measure,Measures.Measure}}(Tuple{Measures.Measure,Measures.Measure}[(-0.1323357282120023cx, 0.43717968156486264cy), (-0.5881538761066724cx, 0.46925506381894794cy)]), Compose.LinePrimitive{Tuple{Measures.Measure,Measures.Measure}}(Tuple{Measures.Measure,Measures.Measure}[(-0.13238192751752698cx, 0.43642923312385257cy), (-0.5145403810397486cx, 0.4565939073838827cy)]), Compose.LinePrimitive{Tuple{Measures.Measure,Measures.Measure}}(Tuple{Measures.Measure,Measures.Measure}[(-0.588743298353732cx, 0.4645751788484526cy), (-0.5995349305117559cx, 0.4665425354703513cy)])], Symbol(""))]), List([Compose.Property{Compose.LineWidthPrimitive}(Compose.LineWidthPrimitive[Compose.LineWidthPrimitive(0.5144957554275265mm)]), Compose.Property{Compose.FillPrimitive}(Compose.FillPrimitive[Compose.FillPrimitive(RGBA{Float64}(0.0,0.0,0.0,0.0))]), Compose.Property{Compose.StrokePrimitive}(Compose.StrokePrimitive[Compose.StrokePrimitive(RGBA{Float64}(0.8274509803921568,0.8274509803921568,0.8274509803921568,1.0))])]), 0, false, false, false, false, nothing, nothing, 0.0, Symbol("")), Compose.Context(Measures.BoundingBox{Tuple{Measures.Length{:w,Float64},Measures.Length{:h,Float64}},Tuple{Measures.Length{:w,Float64},Measures.Length{:h,Float64}}}((0.0w, 0.0h), (1.0w, 1.0h)), nothing, nothing, nothing, nothing, List([]), List([]), List([Compose.Property{Compose.LineWidthPrimitive}(Compose.LineWidthPrimitive[Compose.LineWidthPrimitive(0.5144957554275265mm)]), Compose.Property{Compose.StrokePrimitive}(Compose.StrokePrimitive[Compose.StrokePrimitive(RGBA{Float64}(0.8274509803921568,0.8274509803921568,0.8274509803921568,1.0))])]), 0, false, false, false, false, nothing, nothing, 0.0, Symbol("")), Compose.Context(Measures.BoundingBox{Tuple{Measures.Length{:w,Float64},Measures.Length{:h,Float64}},Tuple{Measures.Length{:w,Float64},Measures.Length{:h,Float64}}}((0.0w, 0.0h), (1.0w, 1.0h)), nothing, nothing, nothing, nothing, List([]), List([]), List([Compose.Property{Compose.FontSizePrimitive}(Compose.FontSizePrimitive[Compose.FontSizePrimitive(4.0mm)]), Compose.Property{Compose.StrokePrimitive}(Compose.StrokePrimitive[Compose.StrokePrimitive(RGBA{Float64}(0.0,0.0,0.0,0.0))]), Compose.Property{Compose.FillPrimitive}(Compose.FillPrimitive[Compose.FillPrimitive(RGBA{Float64}(0.0,0.0,0.0,1.0))])]), 0, false, false, false, false, nothing, nothing, 0.0, Symbol("")), Compose.Context(Measures.BoundingBox{Tuple{Measures.Length{:w,Float64},Measures.Length{:h,Float64}},Tuple{Measures.Length{:w,Float64},Measures.Length{:h,Float64}}}((0.0w, 0.0h), (1.0w, 1.0h)), nothing, nothing, nothing, nothing, List([]), List([Compose.Form{Compose.CirclePrimitive{Tuple{Measures.Measure,Measures.Measure},Measures.Measure}}(Compose.CirclePrimitive{Tuple{Measures.Measure,Measures.Measure},Measures.Measure}[Compose.CirclePrimitive{Tuple{Measures.Measure,Measures.Measure},Measures.Measure}((0.13222074764297154cx, -0.3770194401811936cy), 0.017149858514250882w), Compose.CirclePrimitive{Tuple{Measures.Measure,Measures.Measure},Measures.Measure}((-0.2239844615102875cx, -0.37722400004498247cy), 0.017149858514250882w), Compose.CirclePrimitive{Tuple{Measures.Measure,Measures.Measure},Measures.Measure}((-0.16796395147211385cx, 0.0788470455406396cy), 0.017149858514250882w), Compose.CirclePrimitive{Tuple{Measures.Measure,Measures.Measure},Measures.Measure}((0.050704857665702985cx, -0.2625246227999194cy), 0.017149858514250882w), Compose.CirclePrimitive{Tuple{Measures.Measure,Measures.Measure},Measures.Measure}((0.6357252220539356cx, -0.3935570166688228cy), 0.017149858514250882w), Compose.CirclePrimitive{Tuple{Measures.Measure,Measures.Measure},Measures.Measure}((0.63678616122989cx, -0.7914509237727766cy), 0.017149858514250882w), Compose.CirclePrimitive{Tuple{Measures.Measure,Measures.Measure},Measures.Measure}((0.7208904215359089cx, -0.6341881326960955cy), 0.017149858514250882w), Compose.CirclePrimitive{Tuple{Measures.Measure,Measures.Measure},Measures.Measure}((-0.06406649319997748cx, -0.3836202001735891cy), 0.017149858514250882w), Compose.CirclePrimitive{Tuple{Measures.Measure,Measures.Measure},Measures.Measure}((-0.3619563418693398cx, 0.06294579685467538cy), 0.017149858514250882w), Compose.CirclePrimitive{Tuple{Measures.Measure,Measures.Measure},Measures.Measure}((-0.4151573206061677cx, 0.29508825136161176cy), 0.017149858514250882w)  …  Compose.CirclePrimitive{Tuple{Measures.Measure,Measures.Measure},Measures.Measure}((0.13199437274739378cx, 0.8727658733452666cy), 0.017149858514250882w), Compose.CirclePrimitive{Tuple{Measures.Measure,Measures.Measure},Measures.Measure}((-0.05508928040230843cx, 0.9984143040047977cy), 0.017149858514250882w), Compose.CirclePrimitive{Tuple{Measures.Measure,Measures.Measure},Measures.Measure}((-0.8860315293133993cx, 1.0cy), 0.017149858514250882w), Compose.CirclePrimitive{Tuple{Measures.Measure,Measures.Measure},Measures.Measure}((-0.1749808750065165cx, 0.6766224866956538cy), 0.017149858514250882w), Compose.CirclePrimitive{Tuple{Measures.Measure,Measures.Measure},Measures.Measure}((-0.23815523839906427cx, 0.4687139391316797cy), 0.017149858514250882w), Compose.CirclePrimitive{Tuple{Measures.Measure,Measures.Measure},Measures.Measure}((-0.7175049388922596cx, 0.8362373982251219cy), 0.017149858514250882w), Compose.CirclePrimitive{Tuple{Measures.Measure,Measures.Measure},Measures.Measure}((-0.5971089002010743cx, 0.017323367860413663cy), 0.017149858514250882w), Compose.CirclePrimitive{Tuple{Measures.Measure,Measures.Measure},Measures.Measure}((-0.08956684200523124cx, 0.43417008578637106cy), 0.017149858514250882w), Compose.CirclePrimitive{Tuple{Measures.Measure,Measures.Measure},Measures.Measure}((-0.6309227623134435cx, 0.4722646595974396cy), 0.017149858514250882w), Compose.CirclePrimitive{Tuple{Measures.Measure,Measures.Measure},Measures.Measure}((-0.5573554665520444cx, 0.4588530547213643cy), 0.017149858514250882w)], Symbol(""))]), List([Compose.Property{Compose.LineWidthPrimitive}(Compose.LineWidthPrimitive[Compose.LineWidthPrimitive(0.0mm)]), Compose.Property{Compose.StrokePrimitive}(Compose.StrokePrimitive[Compose.StrokePrimitive(RGBA{Float64}(0.0,0.0,0.0,0.0))]), Compose.Property{Compose.FillPrimitive}(Compose.FillPrimitive[Compose.FillPrimitive(RGBA{Float64}(0.25098039215686274,0.8784313725490196,0.8156862745098039,1.0))])]), 0, false, false, false, false, nothing, nothing, 0.0, Symbol("")), Compose.Context(Measures.BoundingBox{Tuple{Measures.Length{:w,Float64},Measures.Length{:h,Float64}},Tuple{Measures.Length{:w,Float64},Measures.Length{:h,Float64}}}((0.0w, 0.0h), (1.0w, 1.0h)), nothing, nothing, nothing, nothing, List([]), List([]), List([Compose.Property{Compose.FontSizePrimitive}(Compose.FontSizePrimitive[Compose.FontSizePrimitive(4.0mm)]), Compose.Property{Compose.StrokePrimitive}(Compose.StrokePrimitive[Compose.StrokePrimitive(RGBA{Float64}(0.0,0.0,0.0,0.0))]), Compose.Property{Compose.FillPrimitive}(Compose.FillPrimitive[Compose.FillPrimitive(RGBA{Float64}(0.0,0.0,0.0,1.0))])]), 0, false, false, false, false, nothing, nothing, 0.0, Symbol(""))]), List([]), List([]), 0, false, false, false, false, nothing, nothing, 0.0, Symbol(""))

Plots is working as expected and the plot is displayed in a new window

Screenshot_after

I am using julia v1.5.3 and a tiling window manager (i3).

Thanks, Ahmat

simonschoelly commented 3 years ago

This is, because GraphPlot does not have any code included to show a Compose.Context object (which can be rendered as png or svg) in a window. I think there is probably some package somewhere that would provide this functionality, but I did not find one, when I was looking around right now.

As an alternative you could:

axmat commented 3 years ago

@simonschoelly Thank you for your suggestions, gplothtml is good enough and I will stick to it for now.

I didn't find any other package or method that does what I want, but I think it is possible to call feh or imagemagick from julia and display an svg image in a new window ?

DhruvaSambrani commented 3 years ago

Hi @simonschoelly Wouldn't it be easier to write a Plots.recipe for a Context object? I don't know how to do that myself, but I guess it should be pretty straightforward?

Also, an equivalent for Maki-e would also be appreciated.

simonschoelly commented 3 years ago

I think that plotting Context objects should probably be either done in Compose.jl or in some downstream package - but it should probably not be the responsibility of this package to decide how a Compose.Context should be rendered - otherwise we would also change the behavior of other packages that depend on Compose,jl.

DhruvaSambrani commented 3 years ago

Oh right. Yes I agree with you.

Plots has such a beautiful support for so many different kinds of plots, and it's api is well known, so why not use that too? But I suppose it will involve some significant changes to code?

I don't mean to challenge, just want to know why Compose was chosen instead of Plots 😊

simonschoelly commented 3 years ago

I don't really know, as I was not involved at the time of the creation of this package. But there is a graph plotting library GraphRecipes.jl that uses Plots.jl as a backend.

They kind of use the same layout algorithms as this package - I think they relay on NetworkLayou.jl, but that code was copy/pasted from GraphPlot.jl anyway - or maybe it happened in the other direction, I am not sure about that.

hdavid16 commented 1 year ago

Related issue to allow plotting Compose objects: https://github.com/GiovineItalia/Compose.jl/issues/423

hdavid16 commented 1 year ago

Also, an equivalent for Maki-e would also be appreciated.

From the slack channel (written by Pavan Chaggar), you can make your network plots with Makie.jl. You could use the layout functions in GraphPlot.jl to get the coordinates for the nodes and then pass those over to Makie.

using CairoMakie; CairoMakie.activate!()
using Graphs

A = [ #adjacency matrix
    #x1 x2  x3  x4  f1  f2  f3
    0   0   0   0   1   1   0   #x1
    0   0   0   0   1   0   1   #x2
    0   0   0   0   0   1   0   #x3
    0   0   0   0   0   0   1   #x4
    0   0   0   0   0   0   0   #f1
    0   0   0   0   0   0   0   #f2
    0   0   0   0   0   0   0   #f3
]

G = SimpleDiGraph(A)

f = Figure(); 
ax = Axis(f[1, 1], yreversed = true,
    xautolimitmargin = (0.15, 0.20),
    yautolimitmargin = (0.15, 0.20)
)
hidespines!(ax)
hidedecorations!(ax)

leftx, lefty = zeros(4), 1.:4.
rightx, righty = ones(3) * 3, range(1, 4, 3)

x = vcat(leftx, rightx)
y = vcat(lefty, righty)

points = Point.(zip(x, y))

cols = (:blue, :green, :purple)

parents = [inneighbors(G, i) for i in vertices(G)]
childs = findall(x -> length(x) > 0, parents)

function finputs(x)
    str = "f(" 
    for i in x[1:end-1]
        str = str * "x_$i, "
    end
    str * "x_$(x[end]))"
end

for (i, v) in enumerate(childs)
    for node in parents[v] 
        lines!(Point(x[[node, v]]...), Point(y[[node, v]]...), 
               color=cols[i], linewidth=5)
    end
    text!(points[v], text=L"%$(finputs(parents[v]))", offset=(20,-10))
end

for (i, point) in enumerate(points[1:4])
    scatter!(point, color=:black, marker=:circle, markersize=25)
    text!(point, text=L"x_%$i", offset=(-75, -10))
end

for (i, point) in enumerate(points[5:end])
    scatter!(point, color=:black, marker=:rect, markersize=25)
end
f
save("fig.png", f)

image

hdavid16 commented 1 year ago

We can probably close this issue, unless anything else is going to be done on this end.

hdavid16 commented 1 year ago

Hi @simonschoelly Wouldn't it be easier to write a Plots.recipe for a Context object? I don't know how to do that myself, but I guess it should be pretty straightforward?

Also, an equivalent for Maki-e would also be appreciated.

There's GraphMakie.jl :)