3

Say I have a Graph with some labels, and I want to change one of the labels. For example

graph = Graph[
    {1, 2, 3},
    {1 \[UndirectedEdge] 2, 2 \[UndirectedEdge] 3, 3 \[UndirectedEdge] 1},
    VertexLabels -> {1 -> "someLabel"}
];

I now want to change the label from "someLabel" to "someOtherLabel".

Naively, I would do this by simply using ReplaceAll: graph /. "someLabel" -> "someOtherLabel".

However, this doesn't seem to work for Graph expressions, I guess because they are treated as atomic by Mathematica. How can I do this? More generally, is there an easy way to convert a Graph object into its generating expression, so that I can modify it?

glS
  • 7,623
  • 1
  • 21
  • 61

2 Answers2

5

Following a suggestion in the comments, one way to do this is with SetProperty and PropertyValue, of which I was not aware:

replaceInVertexLabels[graph_, replacementRules_] := SetProperty[graph,
    VertexLabels -> (PropertyValue[graph, VertexLabels] /. replacementRules)
];

replaceInVertexLabels[graph, "someLabel" -> "someOtherLabel"]

I still find this method a bit weird, and wouldn't mind a way to directly convert into the Graph into a "normal" expression, but nevertheless this does the job.

glS
  • 7,623
  • 1
  • 21
  • 61
  • 3
    As of Version 12.1, SetProperty has been superseded by Annotate. – Bob Hanlon May 17 '20 at 19:32
  • @BobHanlon thank you for the comment. I still have v11.3, so can't test it. Could you add an example of how Annotate would work here? – glS May 17 '20 at 19:34
  • 3
    For version 12.1 use Annotate and AnnotationValue, e.g., replaceInVertexLabels[graph_, replacementRules_] := Annotate[graph, VertexLabels -> (AnnotationValue[graph, VertexLabels] /. replacementRules)]; – Bob Hanlon May 17 '20 at 19:46
  • 2
    @BobHanlon SetProperty, etc. still work fine in 12.1. If they didn't, that would be a very serious compatibility break for zero benefit. As far as I can tell, these functions were simply renamed without any change in functionality. – Szabolcs May 18 '20 at 09:29
2

With IGraph/M, you can simply do

g = Graph[{1 <-> 2, 2 <-> 3, 3 <-> 4}, 
      VertexLabels -> {1 -> "foo", 2 -> "baz", 3 -> "ping", "pong"}]

IGVertexMap[ Replace[{"foo" -> "bar", "baz" -> "boo"}], VertexLabels, g]

IGVertexMap[f, property, graph] will map the function f to each vertex property value stored in graph.

Szabolcs
  • 234,956
  • 30
  • 623
  • 1,263