How can I automatically avoid vertex labels overlapping with edges?

Graph[{1 \[UndirectedEdge] 2, 2 \[UndirectedEdge] 3, 
  3 \[DirectedEdge] 1}, VertexLabels -> "Name"]

enter image description here

For example, I'd like to avoid using manually tuned parameters e.g. using Placed[].

  • 1
    $\begingroup$ I do not think it can do that. $\endgroup$ – Szabolcs Nov 15 '18 at 20:50
  • 1
    $\begingroup$ I always place names inside vertices to avoid this problem. $\endgroup$ – David G. Stork Nov 15 '18 at 20:53
  • 1
    $\begingroup$ @DavidG.Stork can you show how to? Without rendering text as label (e.g. Rasterise) $\endgroup$ – user305883 Dec 26 '18 at 0:40

I do not think the system supports this.

Here's a hack to try to emulate it. We will connect a dummy node to each existing node, and use it as a label. We lay out the graph using "SpringElectricalEmbedding".

I assume that the graph was unweighted, set small weights to the edges of the dummy nodes, and set the layout to take weights into account. This way the dummy nodes will be closed to their connected node than the other nodes are to each other.

g = RandomGraph[{10, 20}]

newEdges = 
   Thread[VertexList[g] \[UndirectedEdge] wrap /@ VertexList[g]];

 EdgeAdd[g, newEdges],
 {EdgeWeight -> Thread[newEdges -> 0.2 (* this controls the label distance *)], 
  GraphLayout -> {"SpringElectricalEmbedding", "EdgeWeighted" -> True},
  VertexShapeFunction -> Thread[(wrap /@ VertexList[g]) -> None],
  EdgeShapeFunction -> Thread[newEdges -> None],
  VertexLabels -> Thread[wrap /@ VertexList[g] -> (Placed[#, Center] & /@ VertexList[g])]}

enter image description here

The output is not bad, but the problem is that this method will not work if you do not want to use SpringElectricalEmbedding, but set your own coordinates instead.

  • $\begingroup$ This is a valuable hack (+1), but it employs Placed which the OP explicitly sought to avoid. $\endgroup$ – David G. Stork Nov 15 '18 at 21:18
  • $\begingroup$ @DavidG.Stork Using Placed here is not a problem because @Szabolcs doesn't use it manually $\endgroup$ – andre314 Nov 15 '18 at 21:22
  • $\begingroup$ what is wraphere? $\endgroup$ – user305883 Dec 26 '18 at 0:39
  • $\begingroup$ @user305883 An arbitrary head used to create dummy nodes that will later be set to invisible. You can call it whatever you please. The node wrap[1] is simply used to display the label 1. $\endgroup$ – Szabolcs Dec 26 '18 at 7:13
  • $\begingroup$ @Szabolcs thank you - it seems to work weel to avoid overlapping of labels on edges, do you have suggestions to avoid overlapping labels with labels ? Imagine two nodes are close and textual labels are of arbitrary length. I tried to wrap within the node, but could not work out, maybe need to make it parametric in function of graph layout... may you have worked with this problem, suggestions are welcome! and happy holiday time to you:) $\endgroup$ – user305883 Dec 26 '18 at 10:26

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.