Suppose I plot a graph using the following specifications:


Suppose I am happy with the automatic coordinates chosen by the system except for one and I want to translate that by say +{1,2}.

GraphPlot has an option called VertexCoordinates but it requires me to give all the coordinates explicitly but I just want to modify one of them.

One way I found was to Sow the automatically chosen coordinates using Sow[#1] in option VertexShapeFunction then Reap them out to a variable then perform the translation I want to the coordinates outside then rerun the GraphPlot with modified VertexCoordinates.

This is cumbersome there must be a better way to accept all automatically generated coordinates but translate some of them to the better location. Please help.

  • 1
    $\begingroup$ Why do you want to use GraphPlot instead of Graph? $\endgroup$
    – Szabolcs
    Dec 19 '19 at 16:52
  • 2
    $\begingroup$ Make a Graph, extract coordinates with GraphEmbedding, modify the one you want, re-insert with the VertexCoordinates option. $\endgroup$
    – Szabolcs
    Dec 19 '19 at 16:53
  • $\begingroup$ @Szabolcs I am using complex EdgeShapeFunction & VertexShapeFunction conditions and there is an Epilog as well. I don't think I can have all this flexibility with a basic Graph. I am basically building a complex flowchart. Moreover If I have to exact the coordinates and reinsert them, then this is precisely what I am trying to avoid. Is there a coordinate modification function of some sort? $\endgroup$
    – user13892
    Dec 19 '19 at 17:18
  • $\begingroup$ "I don't think I can have all this flexibility with a basic Graph." This is not true. You should use Graph unless you actually found (rather than merely suspected) a reason why it is not suitable. $\endgroup$
    – Szabolcs
    Dec 19 '19 at 17:31

You should use Graph, not GraphPlot, unless there is a very good reason not to. Graph stores an actual graph, with metadata, in a structured way. GraphPlot merely produces graphics, with all structures information getting lost.

You can manipulate the metadata in a graph using the Property* functions such as PropertyValue. These functions tend to be tricky to use and (unfortunately) often inconsistent. But for this purpose, they work straightforwardly.

The following example makes use of my IGraph/M package for convenience, but you do not need to rely on it.

We generate a random tree, and set our preferred layout method:


g = IGTreeGame[6, DirectedEdges -> True, GraphStyle -> "DiagramGold", 
  GraphLayout -> {"LayeredDigraphEmbedding", "Orientation" -> Left}]

enter image description here

There are no stored vertex coordinates in this graph right now. They are computed, not stored, therefore they cannot be modified. To modify them, we must store them first. With IGraph/M, I'd do:

g = IGVertexMap[# &, VertexCoordinates, g]

but without it you can also do:

g = Graph[g, VertexCoordinates -> GraphEmbedding[g]]

Now we can modify the coordinate of a single vertex:

PropertyValue[{g, 3}, VertexCoordinates] += {-1, 2}

Show the graph:


enter image description here

  • 1
    $\begingroup$ Thank you Graph is working fine. Just I had to change the $edge format from {{"v1"->"v2","label"}, ...} to Labeled@@@{{"v1"->"v2","label"}, ...}. I just hope I will be able to get a high quality eps file in the end from the Graph object just like I can get it from the Graphics generated by GraphPlot. $\endgroup$
    – user13892
    Dec 19 '19 at 19:31
  • $\begingroup$ @Szabolcs: In the graph above g, after you find the coordinates of the vertices; (1) fix the coordinates of g, (2) delete vertex 2 from g; (3) get the new graph without 2 while keeping the vertex coordinates unchanged. This will allow me to compare two graphs: before and after vertex deletion. How do you do that? $\endgroup$ Aug 3 '20 at 14:54
  • $\begingroup$ @TugrulTemel You mean how to compare? You can set the same PlotRange on both and use FlipView? Maybe I misunderstood. I may not be logged in much, so if I don't respond, please ping me in a few days. $\endgroup$
    – Szabolcs
    Aug 3 '20 at 15:19
  • 1
    $\begingroup$ @TugrulTemel That's exactly what is shown in my answer above. Just forget about this line: PropertyValue[{g, 3}, VertexCoordinates] += {-1, 2} and use only the rest. $\endgroup$
    – Szabolcs
    Aug 3 '20 at 18:24
  • 1
    $\begingroup$ @TugrulTemel The graph functionality in Mathematica is still quite buggy. In 11.3, it's no exaggeration to say that it's unusable. As you can see a simple deletion of a vertex will mess everything up. Now you know why my fuse blew at some point and made me write this: community.wolfram.com/groups/-/m/t/1321057 $\endgroup$
    – Szabolcs
    Aug 3 '20 at 20:11

Update for Mathematica 12.1+: If you want to fix positions of some vertices and have the rest positioned automatically, we can now use VertexCoordinates, e.g.

  {1 <-> 2, 2 <-> 3, 3 <-> 1}, 
  VertexCoordinates -> {1 -> {0, 0}, 2 -> {1, 1}}

See documentation

  • 1
    $\begingroup$ Major versions of Mathematica are (effectively) of the form x.y, not of the form x. Please avoid using the latter, as it regularly confuses people. This works in 12.1 and does not work in 12.0. I am not even sure why Wolfram still uses the x.y form since I don't see a much bigger difference between e.g. 11.3 and 12.0 than 12.0 and 12.1. (Otherwise +1 for pointing out this useful feature.) $\endgroup$
    – Szabolcs
    Oct 21 at 15:09
  • $\begingroup$ I went ahead and changed 12 to 12.1 in your answer. I hope that's okay with you. $\endgroup$
    – Szabolcs
    Oct 22 at 9:35
  • $\begingroup$ @Szabolcs Nobody seems to care for Semantic Versioning these days and everything is driven by Marketing. At least with v13.0 coming up we are obviously spared irrational superstitious versioning. ;-) $\endgroup$
    – gwr
    Oct 22 at 12:53

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.