0
$\begingroup$

Is it possible to make Mathematica make a connection to p2 from both SysVar 2 and SysVar3 like I drawn ?

enter image description here

Code:

listNodesSubsystemView = Join[{ "xxx" -> "SubSystems"}, 
   Reverse[{"SubSystems" -> "SysVar1", "SubSystems" -> "SysVar2", 
     "SubSystems" -> "SysVar3"}],
    Reverse[{"SysVar1" -> "p1", "SysVar2" -> "p2", "SysVar3" -> "p3", 
     "SysVar3" -> "p2"}],
   Reverse[{{"p1" -> "Sp11", "value set"}, {"p1" -> "Sp12", 
      "value set"}, {"p3" -> "Sp31", "value set"}, {"p3" -> "Sp32", 
      "value set"}}], {{"p2" -> "Sp21", "value set"}}];
TreeSubSystem = 
  TreePlot[listNodesSubsystemView, Left, 
   First[ First[listNodesSubsystemView]], VertexLabeling -> True, 
   DirectedEdges -> True];

I used the solution of renaming after the tree was created but it gets out of hand quickly : enter image description here

listNodesSubsystemView = Join[{ "xxx" -> "SubSystems"}, 
   Reverse[{"SubSystems" -> "SysVar1", "SubSystems" -> "SysVar2", 
     "SubSystems" -> "SysVar3"}],
   Reverse[
    {"SysVar1" -> "p1S1", "SysVar1" -> "p2S1", "SysVar1" -> "p3S1",
     "SysVar2" -> "p1S2", "SysVar2" -> "p2S2", "SysVar2" -> "p3S2",
     "SysVar3" -> "p3S3", "SysVar3" -> "p2S3"}],
   Reverse[{"p1S1" -> "Sp11", "p1S1" -> "Sp12", "p2S1" -> "Sp21", 
     "p2S1" -> "Sp22",(*in system variant S1*)
     "p1S2" -> "Sp11", "p2S2" -> "Sp21", "p3S2" -> "Sp31", 
     "p3S2" -> "Sp32",(*in system variant S2*)
     "p3S3" -> "Sp31"}]];
TreeSubSystem = 
  TreePlot[listNodesSubsystemView, Left, 
      First[ First[listNodesSubsystemView]], VertexLabeling -> True, 
      DirectedEdges -> True] /. "p2S1" | "p2S2" | "p2S3" -> "p2" /. 
    "p3S1" | "p3S2" | "p3S3" -> "p3" /. 
   "p1S1" | "p1S2" | "p1S3" -> "p1";
$\endgroup$
1
  • 1
    $\begingroup$ What about providing code to generate the graph? $\endgroup$ – Yves Klett Nov 23 '14 at 20:01
3
$\begingroup$

Let's start by changing the edge definitions so that the vertex "p2" is split into two vertices, "p2a" and "p2b".

$edges =
  { "Mystery" -> "SubSystems"
  , "SubSystems" -> "SysVar3"
  , "SubSystems" -> "SysVar2"
  , "SubSystems" -> "SysVar1"
  , "SysVar1" -> "p1"
  , {"p1" -> "Sp12", "value set"}
  , {"p1" -> "Sp11", "value set"}
  , "SysVar2" -> "p2a"
  , "SysVar3" -> "p2b"
  , "SysVar3" -> "p3"
  , {"p2b" -> "Sp21", "value set"}
  };

This will cause TreePlot to separate the two vertices, but give them different labels:

TreePlot[$edges, Left, "Mystery", VertexLabeling -> True, DirectedEdges -> True]

treeplot

What follows are various ways to restore the original labels while retaining the tree structure.

Transform the Output of TreePlot

The simplest way to give the same label to "p2a" and "p2b" is to transform the output of TreePlot:

TreePlot[$edges, Left, "Mystery", VertexLabeling -> True, DirectedEdges -> True] /.
  "p2a"|"p2b" -> "p2"

treeplot

It is important that the transformation happens after the TreePlot has been generated. If we had just transformed the edge list, we would have gotten the plot from the question.

Use a Custom Vertex Rendering Function

Another way to relabel the relevant vertices is to define our own VertexRenderingFunction:

render[p_, v_] := Inset[Framed[label@v, Background -> LightYellow], p]
label["p2a" | "p2b"] := "p2"
label[v_] := v

TreePlot[$edges, Left, "Mystery"
, VertexLabeling -> True, DirectedEdges -> True
, VertexRenderingFunction -> render
]

treeplot

Adjust the colour scheme to suit your taste.

Transform the Edge List

A third way to achieve the goal is to transform the edges before plotting. We need to change "p2a" and "p2b" to something that displays as "p2", and yet remains distinctive. Interpretation is intended for such purposes:

$edges2 = $edges /. p2:"p2a"|"p2b" :> Interpretation["p2", p2];

TreePlot[$edges2, Left, "Mystery", VertexLabeling -> True, DirectedEdges -> True]

treeplot

$\endgroup$
4
  • $\begingroup$ The solution is also a dirty hack because I have to maintain by hand each instance of p2 by making it p2a,p2b p2c and so on...bascically when I add a new copy of p2 I have to analyze the last name given and then increment accordingly , and when the letters finish I am screwed p2a ..p2z and then ? My hack is better by just adding a space before p2 for each instance :))) I consider this the answer although I am not satisfied :( $\endgroup$ – TraceKira Nov 23 '14 at 21:02
  • $\begingroup$ In the desired plot mock-up, the upper "p2" node is terminal while the lower "p2" node has an edge to "Sp21". There is not enough information from the edge list alone to infer this output. In order to produce the output automatically, we will either need access to the required additional information, or we must adjust the desired output so that the edge between "p2" and "Sp21` is repeated in both locations. $\endgroup$ – WReach Nov 23 '14 at 21:16
  • $\begingroup$ Now I am scrwed, I need also multiple copies of p3 ....How do I do It ? This fails with error: TreeSubSystem = TreePlot[listNodesSubsystemView, Left, First[ First[listNodesSubsystemView]], VertexLabeling -> True, DirectedEdges -> True] /. {"p2a" | "p2b" | "p2c" -> "p2"}, {"p3a" | "p3b" -> "p3"} $\endgroup$ – TraceKira Nov 23 '14 at 21:30
  • $\begingroup$ You have some extra braces in your replacement rules. Try this instead: {"p2a" | "p2b" | "p2c" -> "p2", "p3a" | "p3b" -> "p3"} $\endgroup$ – WReach Nov 23 '14 at 21:43
3
$\begingroup$

I think I found an easy solution :

TreeForm[Root["S1", "S2", S3["wtf", NewLol["S1", "f2"]]], 

DirectedEdges -> True]

As you can see S1 is repeated without any issue. The only thing I don't know is how to rotate the tree on the Left side ...

enter image description here

$\endgroup$
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.