Message Boards Message Boards

0
|
7612 Views
|
15 Replies
|
9 Total Likes
View groups...
Share
Share this post:

Plot Graph-objects with TreePlot?

Posted 7 years ago

According to the documentation, it should be possible to do a TreePlot[g] with some general Graph-object g. But this is not true. To make things worse, a Graph-object cannot be created from data suitable for TreePlot.

I have to create a graph g from some Depth-First-Search algorithm searching paths from some start-vertex to some end-vertex, draw it as a TreePlot, and then find and list paths from start to end by FindPath[g,start,end]. The algorithm records labeled edges of the graph, one after the other. (The graph is not really a tree, since in the last step all leaves end up in the same end-state, but this is not a problem for TreePlot).

Unfortunately such edges have to be recorded as

graphData={Labeled[vi->vj,label],...} for Graph, but as

graphData={{vi->vj,label},...} for TreePlot

and those two different notations are incompatible, i.e: the notation for Graph is not understood by TreePlot and the notation for TreePlot is not understood by Graph.

In the end I can either not draw a TreePlot or not create a Graph and FindPath from the same recorded data graphData.

Of course I could maintain both graphData-notations or convert one into the other. But why? For me the problem is, that TreePlot[g] does not accept general Graph-objects g. And this is a bug in Wolfram Language.

See the following code for tests. Actually I have the same problem with vertex labels, which is not elaborated here.

If[True, (* Test Graph (from Graph-Data) & TreePlot & FindPath *)
Block[{a, b1, b2, c, graphData, graph},

(* Define graphData as a labeled list of edges in a form suitable \
for Graph *)
Print[Style["1 Defining a graph by graphData suitable for Graph", 
Red, Bold]];
graphData = {Labeled[a -> b1, "a,b1"], Labeled[a -> b2, "a,b2"], 
b1 -> c, b2 -> c};
Echo[graphData, "1 graphData: "];
(* Make a Graph-object from graphData *)
graph = Graph[graphData];
Echo[Row[{Head[graph], " ", graph}], 
"1 make graph from graphData: "];
(* TreePlot and FindPath from graphData *)
Print[TreePlot[graphData, Left, a,
PlotLabel -> Style["1.1 TreePlot from graphData", Blue, Bold],
DirectedEdges -> True, VertexLabeling -> True, 
EdgeLabeling -> True]];
Print[Style[
Row[{"1.1 FindPath from graphData: All paths from a to c: ", 
FindPath[graphData, a, c, Infinity, All]}], Blue, Bold]];
(* TreePlot and FindPath from graph *)
Print[TreePlot[graph, Left, a,
PlotLabel -> Style["1.2 TreePlot from graph", Blue, Bold],
DirectedEdges -> True, VertexLabeling -> True, 
EdgeLabeling -> True]];
Print[Style[
Row[{"1.2 FindPath from graph: All paths from a to c: ", 
FindPath[graph, a, c, Infinity, All]}], Blue, Bold]];

(* Define graphData as a labeled list of edges in a Form suitable \
for TreePlot *)
Print[Style["2 Defining a graph by graphData suitable for TreePlot",
Red, Bold]];
graphData = {{a -> b1, "a,b1"}, {a -> b2, "a,b2"}, b1 -> c, b2 -> c};
Echo[graphData, "2 graphData: "];
(* Make a Graph-object from graphData *)
graph = Graph[graphData];
Echo[Row[{Head[graph], " ", graph}], 
"2 make graph from graphData: "];
(* TreePlot and FindPath from graphData *)
Print[TreePlot[graphData, Left, a,
PlotLabel -> Style["2.1 TreePlot from graphData", Blue, Bold],
DirectedEdges -> True, VertexLabeling -> True, 
EdgeLabeling -> True]];
Print[Style[
Row[{"2.1 FindPath from graphData: All paths from a to c: ", 
FindPath[graphData, a, c, Infinity, All]}], Blue, Bold]];
(* TreePlot and FindPath from graph *)
Print[TreePlot[graph, Left, a,
PlotLabel -> Style["2.2 TreePlot from graph", Blue, Bold],
DirectedEdges -> True, VertexLabeling -> True, 
EdgeLabeling -> True]];
Print[Style[
Row[{"2.2 FindPath from graph: All paths from a to c: ", 
FindPath[graph, a, c, Infinity, All]}], Blue, Bold]];
]
]

1 Defining a graph by graphData suitable for Graph

1 graphData:  {a->b1
a,b1

,a->b2
a,b2

,b1->c,b2->c}

1 make graph from graphData:  Graph 

TreePlot::grph: {a->b1
a,b1

,a->b2
a,b2

,b1->c,b2->c} is not a valid graph.

TreePlot::grph: {a->b1
a,b1

,a->b2
a,b2

,b1->c,b2->c} is not a valid graph.

TreePlot::grph: {a->b1
a,b1

,a->b2
a,b2

,b1->c,b2->c} is not a valid graph.

General::stop: Further output of TreePlot::grph will be suppressed during this calculation.

TreePlot[{a->b1
a,b1

,a->b2
a,b2

,b1->c,b2->c},Left,a,PlotLabel->1.1 TreePlot from graphData,DirectedEdges->True,VertexLabeling->True,EdgeLabeling->True]

1.1 FindPath from graphData: All paths from a to c: {{a,b2,c},{a,b1,c}}

TreePlot[SparseArray[Specified elements: 4
Dimensions: {4,4}

],Left,a,PlotLabel->1.2 TreePlot from graph,DirectedEdges->True,VertexLabeling->True,EdgeLabeling->True,DirectedEdges->True]

1.2 FindPath from graph: All paths from a to c: {{a,b2,c},{a,b1,c}}

2 Defining a graph by graphData suitable for TreePlot

2 graphData:  {{a->b1,a,b1},{a->b2,a,b2},b1->c,b2->c}

2 make graph from graphData:  Graph Graph[{{a->b1,a,b1},{a->b2,a,b2},b1->c,b2->c}]



FindPath::graph: A graph object is expected at position 1 in FindPath[{{a->b1,a,b1},{a->b2,a,b2},b1->c,b2->c},a,c,\[Infinity],All].

2.1 FindPath from graphData: All paths from a to c: FindPath[{{a->b1,a,b1},{a->b2,a,b2},b1->c,b2->c},a,c,\[Infinity],All]

TreePlot[Graph[{{a->b1,a,b1},{a->b2,a,b2},b1->c,b2->c}],Left,a,PlotLabel->2.2 TreePlot from graph,DirectedEdges->True,VertexLabeling->True,EdgeLabeling->True]

FindPath::graph: A graph object is expected at position 1 in FindPath[Graph[{{a->b1,a,b1},{a->b2,a,b2},b1->c,b2->c}],a,c,\[Infinity],All].

2.2 FindPath from graph: All paths from a to c: FindPath[Graph[{{a->b1,a,b1},{a->b2,a,b2},b1->c,b2->c}],a,c,\[Infinity],All]
POSTED BY: Werner Geiger
15 Replies
Posted 7 years ago

Thanks Sander for your help and explanations. I have to apologize for creating confusion here and of course for my far too long code examples.

I read the documentation carefully and I know what the difference is between an object and the data for its constructors. (Originally I did not realize that Graph and TreeGraph take (Un)DirectedEdge as input and not Rule like TreePlot does. Michael pointed me to that mistake and I fixed it. But this didn't cure my problem).

You say that TreePlot does not (officially) accept a Graph-object as input. I think the documentation clearly states something else, namely that it takes Graph-objects:

TreePlot[g]
generates a tree plot of the graph g.

And it does indeed. You can easily write:

graphDataEdge = {b1 \[DirectedEdge] c1, a \[DirectedEdge] b1, 
  b2 \[DirectedEdge] c2, a \[DirectedEdge] b2}
graph = Graph[graphDataEdge];
TreePlot[graph, Left, VertexLabeling -> True, ImageSize -> Small]

The same can be done with a treeGraph=TreeGraph[graphDataEdge]. It's a bit surprising that this TreePlot uses vertex-indices as labels instead of names, but this doesn't matter for the moment.

I thought that TreePlot does not accept Graph-objects and called this a bug. This was wrong.

I know now that the hole problem and all my confusion came from something else I had never paid attention to, namely specifying the root-vertex for TreePlot as a vertex name, which gives a strange error concerning SparseArray. As in:

TreePlot[graph, Left, a, VertexLabeling -> True, ImageSize -> Small]

Michael tried two days ago to point me to that issue by saying "Note that I also took out the "a"". But I did not realize that, since I did not understand, which "a" in our lengthy code he ment.

The documentation says:

TreePlot[g,pos,Subscript[v, k]]
uses vertex Subscript[v, k] as the root node in the tree plot.

I thought, the vertex-name must be given, but it is the index if the graph is specified as a Graph-object. The following works:

TreePlot[graph, Left, 3, VertexLabeling -> True, ImageSize -> Small]

If you do exactly the same without a Graph-object but with directly giving rules to TreePlot things change. Now the vertices are labeled as names and the root-vertex has to be specified as name, not index:

graphDataEdgeRule = {b1 -> c1, a -> b1, b2 -> c2, a -> b2}
TreePlot[graphDataEdgeRule, Left, a, VertexLabeling -> True, 
 ImageSize -> Small, DirectedEdges -> True]

Uff, this was a long and tedious way and I apologize again for all that.

At the end there is no bug in WL within this context. Only some explanations in the documentation maybe missing.

POSTED BY: Werner Geiger

Oops! I misread it! it does support it, and exactly by the code I presented above. Ok, so that IS officially supported.

When I run into these things I always look at the examples, it generally gives a good feel about what the various inputs/outputs are.

Good to hear you got it resolved!

POSTED BY: Sander Huisman

I'm not sure why this thread is so big for such a simple misunderstanding (definitely not a bug). Just read the manual.

You have two functions: TreePlot and TreeGraph, one handles a list of rules, the other handles directed and undirected edges. For all the functions is clearly states in the top of the documentation the various inputs they can receive (list of rules, list of directed/undirected edges, adjacency matrix, ...)

  • FindPath accepts Graph objects, but also a list of rules (as per the last line of the possible syntax inputs).
  • TreePlot accepts list of rules, adjacency matrix
  • TreeGraph accepts (just like Graph) a list of (un)directed edges.

See also the documentation headers:

enter image description here enter image description here

And note the info contained under Details and Options:

enter image description here

Read also the guides:

  • guide/GraphConstructionAndRepresentation
  • guide/GraphVisualization
  • guide/GraphsAndNetworks

Since v8 Mathematica has support for undirected edges, all functions prior to that only supported basic plotting through GraphPlot and its friends (working on list of rules and adjacency matrices, but only one-way). This functionality was more focused on visualization, not so much on calculations. The new Graph functionality since v8 support both types edge types and is also designed for calculations.

The difference between the two ways of graph visualisations is:

TreePlot[{1 -> 2, 1 -> 3, 1 -> 4}]
AtomQ[%]

TreeGraph[{1~DirectedEdge ~2, 1~DirectedEdge ~3, 1~DirectedEdge ~4}]
AtomQ[%]

Functions ending on Plot output visualisations, intended for viewing things, NOT to work and edit on (though not impossible to still manipulate it because of the homoiconic nature of Wolfram Language).

Functions ending on Graph output Graph objects which are displayed as plot, but are much more than that as they are treated as atoms, the internal structure of the graph is preserved (not turned into dots and lines and so on), and one can do calculations on those.

Also in the future you should try to get the core of your problem, long pieces of code make the thread unwieldy and hard to interpret, try to find the minimum amount of code to present your problem.

POSTED BY: Sander Huisman

To add:

Note that in the TreePlot documentation a Graph object is not a valid input. There is however some 'hidden' (undocumented) functionality inside the definition of Treeplot. Namely:

TreePlot[g_ ? GraphQ, expr___] := Block[{res, adj, opts},
    adj = AdjacencyMatrix @ g;
    Condition[
       opts = opts = toTreePlotOptions @ g;
       res = TreePlot[adj, expr, opts];
       res /; UnsameQ[res, $Failed],
       MatrixQ[adj]
    ]
]

You can see how that it can handle Graph objects in some ways, but note that this is undocumented and might as well get removed in future versions! It might be some remnants from development (opts = opts = makes me think this).

POSTED BY: Sander Huisman
Posted 7 years ago

*****"@Sam Carrettie - Word "bug" should not be placed in the title unless it is proven to be a bug. "*****

Yes. That's why I put it as a question.

Meanwhile I am sure that it's a bug. And not only one, but many. This happens, if one has a basic fault in design and architecture.

WL should clearly distinguish between some pure data defining a graph, making a graph-object from that and all those functions operating on those graph-objects. But WL doesn't do that. Instead, it mixes all that at will. That's the problem.

In principle it's easy: data->Create Object->Work on Object.

For example: TreePlot, FindPath, etc can work on some kind of graph.objects (but not all) and on some kind of pure data as well (but not all). But why? And Graph-object creating constructors work on different kinds of data-structures. But why?

I assume that this comes from a long history were totally different ideas have been applied, but all need to be maintained for upward-compatibility. That's a known problem in SW-architecture. And a difficult one. There are many solutions. The most radical is to just provide a new set of functions with some suffix, say "2" which are designed in a modern and consistent way.

POSTED BY: Werner Geiger
Posted 7 years ago

Standard Graph- or TreeGraph-objects or their defining data are obviously useless. It's a horrible mess.

I want to solve some problem, but not debug WL.

POSTED BY: Werner Geiger
Posted 7 years ago

Sorry for plaguing you with my funny but probably nonsense problems. I have enough of digging into all those strange features or bugs within WL concerning graphs. I will just maintain my own abstract data structure defining a graph and then convert this to whatever the WL-functions like to have.

POSTED BY: Werner Geiger
Posted 7 years ago

I am really stuck. Bugs or not within all those WL-functions defining and exploring or plotting graphs, I cannot understand them. Maybe my test-program got too complicated. I reduced it to almost nothing.

What is wrong with the following trivial code? (Sorry I could not find how to show code and its output in a reasonable way in this forum).

{graphDataVertex, graphDataEdge} = {
  {Labeled[a, "S=a"], b1, b2, Labeled[c, "E=c"], Labeled[c2, "E=c2"]},
  {Labeled[a \[DirectedEdge] b1, "a,b1"], 
   Labeled[a \[DirectedEdge] b2, "a,b2"], b1 \[DirectedEdge] c, 
   b2 \[DirectedEdge] c2}
  }
graph = Graph[graphDataVertex, graphDataEdge, ImageSize -> Tiny]
FindPath[graph, a, c, Infinity, All]
TreePlot[graph, Left, a]
treeGraph = 
 TreeGraph[graphDataVertex, graphDataEdge, ImageSize -> Tiny]
FindPath[treeGraph, a, c2, Infinity, All]
TreePlot[treeGraph, Left, a]

Strange enough the following TreePlot-calls without startnode and its position work. But why?

TreePlot[graph]
TreePlot[treeGraph]
POSTED BY: Werner Geiger
Posted 7 years ago

"@ Werner: "->" is not the same as \DirectedEdge, otherwise I would have no reason to changed it. Did you run the code with my corrections in it (as posted above)?"

Oh, what a shame! I missed that point indeed and defined the graphData with rules instead of (Un)DirectedEdge. I am embarrassed.

Strange enough, Graph accepts this wrong definition (See case 1.1. in my original code). I am somewhat confused.

Anyway, I fixed my code now by changing rules to DirectedEdge as data for Graph (Case 1, see below). For TreePlot and FindPath graphData still has to use rules instead of DirectedEdge (Case 2). I added a new case 3 as well which uses labeled vertices and labeled edges in a form suitable for Graph.

All in all this doesn't change very much. The basic problem that TreePlot does not accept a general Graph-object still holds true. Whereas FindPath does.

I come back to Sam Carretties hint to use TreeGraph, which should be the solution (See case 4 below). TreeGraph accepts the same defining data as Graph, i.e based on (Un)DirectedEdge, possibly with an explicit list of vertices. Edges and vertices can both be labeled (or - as I assume - wrapped with any other properties). Hence:

  • Define graphData in a form suitable for Graph and TreeGraph, i.e. (Un)DirectedEdge, possibly explicit vertices, possibly wrapped for labels or other properties.

  • use TreePlot[TreeGraph[graphData],...]

  • use FindPath[Graph[graphData],...]

But this does not work either. Maybe because of TreeGraph not accepting my not-so-nice-Tree (Common endnode c. Although it is connected and cycle-free). Hence I changed my graphData to a proper tree, adding another leave c2 and edge b2->c2 (See case 5 below). But this doesn't work either.

Before you read my following code just read my next message, which should be easier to understand.

If[True, (* Test Graph (from Graph-Data) & TreePlot & FindPath *)
 Block[{a, b1, b2, c, graphData, graph, treeGraph},

  (* Define graphData as a labeled list of edges in a form suitable \
for Graph (using DirectedEdge) *)
  Print[];
  Print[Style[
    "1 Defining a graph with edge labels by graphData suitable for \
Graph", Red, Bold, Larger]];
  graphData = {Labeled[a \[DirectedEdge] b1, "a,b1"], 
    Labeled[a \[DirectedEdge] b2, "a,b2"], b1 \[DirectedEdge] c, 
    b2 \[DirectedEdge] c};
  Echo[graphData, "1 graphData: "];
  (* Make a Graph-object from graphData *)
  graph = Graph[graphData];
  Echo[Row[{Head[graph], " ", graph}], 
   "1 make graph from graphData: "];
  (* TreePlot and FindPath from graphData *)
  Print[Style["\n1.1 TreePlot from graphData", Blue, Bold]];
  Print[TreePlot[graphData, Left, a,
    PlotLabel -> Style["1.1 TreePlot from graphData", Blue, Bold],
    DirectedEdges -> True, VertexLabeling -> True, 
    EdgeLabeling -> True]];
  Print[Style[
    Row[{"1.1 FindPath from graphData: All paths from a to c: ", 
      FindPath[graphData, a, c, Infinity, All]}], Blue, Bold]];
  (* TreePlot and FindPath from graph *)
  Print[Style["\n1.2 TreePlot from graph", Blue, Bold]];
  Print[TreePlot[graph, Left, a,
    PlotLabel -> Style["1.2 TreePlot from graph", Blue, Bold],
    DirectedEdges -> True, VertexLabeling -> True, 
    EdgeLabeling -> True]];
  Print[Style[
    Row[{"1.2 FindPath from graph: All paths from a to c: ", 
      FindPath[graph, a, c, Infinity, All]}], Blue, Bold]];

  (* Define graphData as a labeled list of edges in a Form suitable \
for TreePlot (using rules) *)
  Print[];
  Print[Style[
    "2 Defining a graph with edge labels by graphData suitable for \
TreePlot", Red, Bold, Larger]];
  graphData = {{a -> b1, "a,b1"}, {a -> b2, "a,b2"}, b1 -> c, b2 -> c};
  Echo[graphData, "2 graphData: "];
  (* Make a Graph-object from graphData *)
  graph = Graph[graphData];
  Echo[Row[{Head[graph], " ", graph}], 
   "2 make graph from graphData: "];
  (* TreePlot and FindPath from graphData *)
  Print[Style["\n2.1 TreePlot from graphData", Blue, Bold]];
  Print[TreePlot[graphData, Left, a,
    PlotLabel -> Style["2.1 TreePlot from graphData", Blue, Bold],
    DirectedEdges -> True, VertexLabeling -> True, 
    EdgeLabeling -> True]];
  Print[Style[
    Row[{"\n2.1 FindPath from graphData: All paths from a to c: ", 
      FindPath[graphData, a, c, Infinity, All]}], Blue, Bold]];
  (* TreePlot and FindPath from graph *)
  Print[Style["\n2.2 TreePlot from graph", Blue, Bold]];
  Print[TreePlot[graph, Left, a,
    PlotLabel -> Style["2.2 TreePlot from graph", Blue, Bold],
    DirectedEdges -> True, VertexLabeling -> True, 
    EdgeLabeling -> True]];
  Print[Style[
    Row[{"2.2 FindPath from graph: All paths from a to c: ", 
      FindPath[graph, a, c, Infinity, All]}], Blue, Bold]];

  (* Define graphData as a labeled list of vertices and edges in a \
form suitable for Graph (using DirectedEdge) *)
  Print[];
  Print[Style[
    "3 Defining a graph with vertex- and edge-labels by graphData \
suitable for Graph", Red, Bold, Larger]];
  graphData = {
    {Labeled[a, "S=a"], b1, b2, Labeled[c, "E=c"]},
    {Labeled[a \[DirectedEdge] b1, "a,b1"], 
     Labeled[a \[DirectedEdge] b2, "a,b2"], b1 \[DirectedEdge] c, 
     b2 \[DirectedEdge] c}
    };
  Echo[graphData, "3 graphData: "];
  (* Make a Graph-object from graphData *)
  graph = Graph[graphData[[1]], graphData[[2]]];
  Echo[Row[{Head[graph], " ", graph}], 
   "3 make graph from graphData: "];
  (* TreePlot and FindPath from graphData *)
  Print[Style["\n3.1 TreePlot from graphData", Blue, Bold]];
  Print[TreePlot[graphData[[2]], Left, a,
    PlotLabel -> Style["3.1 TreePlot from graphData", Blue, Bold],
    DirectedEdges -> True, VertexLabeling -> True, 
    EdgeLabeling -> True]];
  Print[Style[
    Row[{"3.1 FindPath from graphData: All paths from a to c: ", 
      FindPath[graphData[[2]], a, c, Infinity, All]}], Blue, Bold]];
  (* TreePlot and FindPath from graph *)
  Print[Style["\n3.2 TreePlot from graph", Blue, Bold]];
  Print[TreePlot[graph, Left, a,
    PlotLabel -> Style["3.2 TreePlot from graph", Blue, Bold],
    DirectedEdges -> True, VertexLabeling -> True, 
    EdgeLabeling -> True]];
  Print[Style[
    Row[{"3.2 FindPath from graph: All paths from a to c: ", 
      FindPath[graph, a, c, Infinity, All]}], Blue, Bold]];

  (* Define graphData as a labeled list of vertices and edges in a \
form suitable for Graph (using DirectedEdge). 
  Use Graph and TreeGraph for creation of suitable Graph-objects. *)
  Print[];
  Print[Style[
    "4 Defining a graph with vertex- and edge-labels by graphData \
suitable for Graph and TreeGraph", Red, Bold, Larger]];
  graphData = {
    {Labeled[a, "S=a"], b1, b2, Labeled[c, "E=c"]},
    {Labeled[a \[DirectedEdge] b1, "a,b1"], 
     Labeled[a \[DirectedEdge] b2, "a,b2"], b1 \[DirectedEdge] c, 
     b2 \[DirectedEdge] c}
    };
  Echo[graphData, "4 graphData: "];
  (* Make a Graph-object by Graph from graphData *)
  graph = Graph[graphData[[1]], graphData[[2]]];
  Echo[Row[{Head[graph], " ", graph}], 
   "4a make graph by Graph from graphData: "];
  (* Make a Graph-object by TreeGraph from graphData *)
  treeGraph = TreeGraph[graphData[[1]], graphData[[2]]];
  Echo[Row[{Head[treeGraph], " ", treeGraph, " is a tree: ", 
     TreeGraphQ[treeGraph]}], 
   "4b make treeGraph by TreeGraph from graphData: "];
  (* TreePlot and FindPath from Graph-objects *)
  Print[Style["\n4.2 TreePlot from treeGraph", Blue, Bold]];
  Print[TreePlot[treeGraph, Left, a,
    PlotLabel -> Style["4.2 TreePlot from treeGraph", Blue, Bold],
    DirectedEdges -> True, VertexLabeling -> True, 
    EdgeLabeling -> True]];
  Print[Style[
    Row[{"4.2 FindPath from graph: All paths from a to c: ", 
      FindPath[graph, a, c, Infinity, All]}], Blue, Bold]];

  (* Same as case 4, but with a true tree. 
  Define graphData as a labeled list of vertices and edges in a form \
suitable for Graph (using DirectedEdge). 
  Use Graph and TreeGraph for creation of suitable Graph-objects. *)
  Print[];
  Print[Style[
    "5 Defining a true tree graph with vertex- and edge-labels by \
graphData suitable for Graph and TreeGraph", Red, Bold, Larger]];
  graphData = {
    {Labeled[a, "S=a"], b1, b2, Labeled[c, "E=c"], 
     Labeled[c2, "E=c2"]},
    {Labeled[a \[DirectedEdge] b1, "a,b1"], 
     Labeled[a \[DirectedEdge] b2, "a,b2"], b1 \[DirectedEdge] c, 
     b2 \[DirectedEdge] c2}
    };
  Echo[graphData, "5 graphData: "];
  (* Make a Graph-object by Graph from graphData *)
  graph = Graph[graphData[[1]], graphData[[2]]];
  Echo[Row[{Head[graph], " ", graph}], 
   "5a make graph by Graph from graphData: "];
  (* Make a Graph-object by TreeGraph from graphData *)
  treeGraph = TreeGraph[graphData[[1]], graphData[[2]]];
  Echo[Row[{Head[treeGraph], " ", treeGraph, " is a tree: ", 
     TreeGraphQ[treeGraph]}], 
   "5b make treeGraph by TreeGraph from graphData: "];
  (* TreePlot and FindPath from Graph-objects *)
  Print[Style["\n5.2 TreePlot from treeGraph", Blue, Bold]];
  Print[TreePlot[treeGraph, Left, a,
    PlotLabel -> Style["5.2 TreePlot from treeGraph", Blue, Bold],
    DirectedEdges -> True, VertexLabeling -> True, 
    EdgeLabeling -> True]];
  Print[Style[
    Row[{"5.2.1 FindPath from graph: All paths from a to c: ", 
      FindPath[graph, a, c, Infinity, All]}
POSTED BY: Werner Geiger
Posted 7 years ago

@ Werner: "->" is not the same as \DirectedEdge, otherwise I would have no reason to changed it. Did you run the code with my corrections in it (as posted above)?

POSTED BY: Michael Helmle

Word "bug" should not be placed in the title unless it is proven to be a bug. Reading the "details" section for the functions will help your understanding.

Docs clearly say (details section):

TreePlot returns a Graphics object.

so how can you expect it to be a Graph object?

Also, if you need a Graph object, what is wrong with TreeGraph or general structured embeddings for layered graphs such as trees and directed acyclic graphs:

Graph[..., GraphLayout -> "LayeredEmbedding"]
Graph[..., GraphLayout -> "LayeredDigraphEmbedding"]
Graph[..., GraphLayout -> "RadialEmbedding"]
Graph[..., GraphLayout -> "BalloonEmbedding"]

Also docs clearly say (details section):

TreePlot generates a tree plot of the graph g.

And here it is:

TreePlot[TreeGraph[{1 -> 2, 1 -> 3, 1 -> 4}]]
TreePlot[RandomGraph[{15, 34}]]
POSTED BY: Sam Carrettie
Posted 7 years ago

I think you misunderstood my post and did not read it. I did not expect TreePlot to return a Graph-object. Why should I do that? I expected TreePlot to accept any general Graph-object AS INPUT as described in the documentation. But it doesn't, as you can see from my post and code above.

Me personally thinks that this is a bug, but I am not sure. Maybe I have some basic misunderstanding. This is why I posted that here as a question: "..... A bug?"

Probably the confusion comes from WL not clearly distinguishing between Graph-objects and the different kinds of data-lists defining those graphs. Which are incompatibly different for Graph/FindPath and TreePlot.

Anyway, your hint to TreeGraph told me, that this accepts the same defining data as Graph and returns a Graph-object which might be suitable for TreePlot and FindPath. Thanks! I will test that.

POSTED BY: Werner Geiger
Posted 7 years ago

I'm afraid the solution is to record the graphData in some totally abstract form like {vertices,edges}={{{vertex,label},...},{{edge,label},...}} and then convert this for TreePlot and Graph/FindPath as desired.

Pretty stupid.

POSTED BY: Werner Geiger
Posted 7 years ago

Hello Werner,

replace

graphData = {Labeled[a -> b1, "a,b1"], Labeled[a -> b2, "a,b2"], 
   b1 -> c, b2 -> c};

by

graphData = {Labeled[a \[DirectedEdge] b1, "a,b1"], 
   Labeled[a \[DirectedEdge] b2, "a,b2"], b1 \[DirectedEdge] c, 
   b2 \[DirectedEdge] c};

Treeplot requires a graph not just graphdata:

Print[TreePlot[Graph[graphData], 
   PlotLabel -> Style["1.1 TreePlot from graphData", Blue, Bold], 
   DirectedEdges -> True, VertexLabeling -> True, 
   EdgeLabeling -> True]];

Note that I also took out the "a". With these changes the 1st part should run.

I copied the changed version in below:

If[True,(*Test Graph (from Graph-Data)& TreePlot& FindPath*)
 Block[{a, b1, b2, c, graphData, 
   graph},(*Define graphData as a labeled list of edges in a form \
suitable for Graph*)
  Print[Style["1 Defining a graph by graphData suitable for Graph", 
    Red, Bold]];
  (* graphData={Labeled[a\[Rule]b1,"a,b1"],Labeled[a\[Rule]b2,"a,b2"],
  b1\[Rule]c,b2\[Rule]c};*)
  graphData = {Labeled[a \[DirectedEdge] b1, "a,b1"], 
    Labeled[a \[DirectedEdge] b2, "a,b2"], b1 \[DirectedEdge] c, 
    b2 \[DirectedEdge] c};
  Echo[graphData, "1 graphData: "];
  (*Make a Graph-object from graphData*)graph = Graph[graphData];
  Echo[Row[{Head[graph], " ", graph}], 
   "1 make graph from graphData: "];
  (*TreePlot and FindPath from graphData*)(* Print[TreePlot[graphData,
  Left,a,PlotLabel\[Rule]Style["1.1 TreePlot from graphData",Blue,
  Bold],DirectedEdges\[Rule]True,VertexLabeling\[Rule]True,
  EdgeLabeling\[Rule]True]];*)
  Print[TreePlot[Graph[graphData], 
    PlotLabel -> Style["1.1 TreePlot from graphData", Blue, Bold], 
    DirectedEdges -> True, VertexLabeling -> True, 
    EdgeLabeling -> True]];
  (* Print[Style[
  Row[{"1.1 FindPath from graphData: All paths from a to c: ",
  FindPath[graphData,a,c,Infinity,All]}],Blue,Bold]];*)
  Print[Style[
    Row[{"1.1 FindPath from graphData: All paths from a to c: ", 
      FindPath[Graph[graphData], a, c, Infinity, All]}], Blue, Bold]];
  (*TreePlot and FindPath from graph*)
  Print[TreePlot[graph, Left, 
    PlotLabel -> Style["1.2 TreePlot from graph", Blue, Bold], 
    DirectedEdges -> True, VertexLabeling -> True, 
    EdgeLabeling -> True]];
  Print[Style[
    Row[{"1.2 FindPath from graph: All paths from a to c: ", 
      FindPath[graph, a, c, Infinity, All]}], Blue, Bold]];
  (*Define graphData as a labeled list of edges in a Form suitable \
for TreePlot*)
  Print[Style["2 Defining a graph by graphData suitable for TreePlot",
     Red, Bold]];
  (* graphData={{a\[Rule]b1,"a,b1"},{a\[Rule]b2,"a,b2"},b1\[Rule]c,
  b2\[Rule]c};*)
  graphData = {Labeled[a \[DirectedEdge] b1, "a,b1"], 
    Labeled[a \[DirectedEdge] b2, "a,b2"], b1 \[DirectedEdge] c, 
    b2 \[DirectedEdge] c};
  Echo[graphData, "2 graphData: "];
  (*Make a Graph-object from graphData*)graph = Graph[graphData];
  Echo[Row[{Head[graph], " ", graph}], 
   "2 make graph from graphData: "];
  (*TreePlot and FindPath from graphData*)(* Print[TreePlot[graphData,
  Left,a,PlotLabel\[Rule]Style["2.1 TreePlot from graphData",Blue,
  Bold],DirectedEdges\[Rule]True,VertexLabeling\[Rule]True,
  EdgeLabeling\[Rule]True]];*)
  Print[TreePlot[Graph[graphData], 
    PlotLabel -> Style["2.1 TreePlot from graphData", Blue, Bold], 
    DirectedEdges -> True, VertexLabeling -> True, 
    EdgeLabeling -> True]];
  Print[Style[
    Row[{"2.1 FindPath from graphData: All paths from a to c: ", 
      FindPath[Graph[graphData], a, c, Infinity, All]}], Blue, Bold]];
  (*TreePlot and FindPath from graph*)
  Print[TreePlot[graph, Left, 
    PlotLabel -> Style["2.2 TreePlot from graph", Blue, Bold], 
    DirectedEdges -> True, VertexLabeling -> True, 
    EdgeLabeling -> True]];
  Print[Style[
    Row[{"2.2 FindPath from graph: All paths from a to c: ", 
      FindPath[graph, a, c, Infinity, All]}], Blue, Bold]];]]
POSTED BY: Michael Helmle
Posted 7 years ago

"replace""

graphData = {Labeled[a -> b1, "a,b1"], Labeled[a -> b2, "a,b2"], 
   b1 -> c, b2 -> c};

"by"

graphData = {Labeled[a \[DirectedEdge] b1, "a,b1"], 
   Labeled[a \[DirectedEdge] b2, "a,b2"], b1 \[DirectedEdge] c, 
   b2 \[DirectedEdge] c};

Isn't that exactly the same?

"Treeplot requires a graph not just graphData:"

I think, that unfortunately TreePlot does not accept a general Graph-object and only some kind of very special graphData..

POSTED BY: Werner Geiger
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract