# Changing the EdgeList of a Graph

I need to replace the EdgeList of a graph with a new list of edges generated by other code.

I use an hour glass display for vertices:

vf[{xc_, yc_}, name_, {w_, h_}] :=
Block[{xmin = xc - w, xmax = xc + w, ymin = yc - h, ymax = yc + h},
Polygon[{{xmin, ymin}, {xmax, ymax}, {xmin, ymax}, {xmax, ymin}}]];


The graph is of the following form:

    graph = Graph[List[1, 2, 3], List[DirectedEdge[1, 3], DirectedEdge[2, 3]],
List[Rule[ImageSize, List[240, 240]],
Rule[VertexCoordinates,
List[List[0., -1.], List[1., -1.], List[1., 0.]]],
Rule[VertexLabels,
List[Rule[3,
Placed[List[Style[3, RGBColor[1, 0, 0]],
Style[3, RGBColor[0, 0, 1]]], List[Before, After]]],
Rule[1, Placed[
List[Style[1, RGBColor[1, 0, 0]], Style[2, RGBColor[0, 0, 1]]],
List[Before, After]]],
Rule[2, Placed[
List[Style[2, RGBColor[1, 0, 0]], Style[1, RGBColor[0, 0, 1]]],
List[Before, After]]]]], Rule[VertexShapeFunction, List[vf]],
Rule[VertexWeight, List[1, 2, 3]]]]


Its edges are: {1 -> 3, 2 -> 3}

which I want to replace with: {2 -> 3, 1 -> 2}

(this is only an example, the solution needs to work on any replacing set of edges)

Without affecting any other aspects of the graph. I want to preserve all aspects of the graph as given in its definition, bar the edges. These can be changed. I.e. I want to preserve colours, vertices, weights and labels as specified in the graph.

The following approach:

 EdgeList[graph] = {2 -> 3, 1 -> 2}


Gives the error: Tag Edgelist in Edgelist[...] is Protected.

How do I change the EdgeList (without altering the other properties of a graph)?

• "Without affecting any other aspects of the graph." Can you please be specific about what other aspects you want to preserve and why Graph[VertexList[g], newEdges] doesn't work for you? Sep 27, 2022 at 20:39
• @Szabolcs I tried Graph[VertexList[g], newEdges] first. It produces an odd output. I don't know how to copy outputs into my question. But if you try it on the graph I specified, you should see that the end result is incorrect. Sep 27, 2022 at 21:24
• The expression you posted is incomplete, as vf is missing. Please be specific about what you mean by "the end result is incorrect". You did not respond about what aspects of the original graph you want to preserve. Sep 27, 2022 at 21:28
• I added the definition of the hour-glass vertices vf. The end result is incorrect in that it does not evaluate. Sep 27, 2022 at 21:31
• If what you want to preserve ends up being all about presentation, you might try doing all of your processing work (regenerating the Hasse diagram relations) in the raw, so to speak. Then apply all of your presentation options as a final step. So augmenting @Szabolcs suggestion like this: Graph[VertexList[graph], newEdges, displayOpts] (where you've defined displayOpts to be the whole sequence of options that you want). Sep 27, 2022 at 21:39

I think this might be what you want:

newEdges = {2 -> 3, 1 -> 2};


To be clear, this generates a new Graph object, it does not override the value of graph. If you want that you could do:

newEdges = {2 -> 3, 1 -> 2};

• This will preserve vertex and graph properties, at great cost to performance. It will not preserve edge properties, in case OP meant to replace each edge by another one without losing its properties. It is not possible to give a good answer unless the question is clarified. Sep 27, 2022 at 21:03
• @Szabolic The above solution works. I am concerned indeed about performance. In a nutshell: I extend a Hasse diagram by adding edges and want to create a new Hasse diagram, i..e get rid of transitive closures in the relationships caused by adding some of the new edges. Currently I do this by regenerating the Hasse diagram relations (after adding new edges), then replacing the old edges with the new ones. I could try to just use EdgeAdd, but then would need to weed you the relations that can be obtained by transitive closure. Sep 27, 2022 at 21:26
• To your question about rewriting the post: As long as the spirit of the question is the same, I think it's fine. A better description with better details might lead to better answers. Sep 27, 2022 at 21:31
• @lericr I accepted the answer. In relation to efficiency, raised by Szabolic: I need to carry out graph manipulations on graphs of size at most 7 nodes. However, I need to generate the graphs for 7!, i.e. 5040 cases. I did not use Mathematica in such a context before. I can aim to do your "raw" approach, but wonder if your solution may simply work for 5040 instances. I will carry out the experiment first using the method suggested in your answer (unless someone flags that it is clear from the start this won't work due to efficiency issues). Sep 28, 2022 at 9:22

The trouble is that a Graphics is considered an atomic object, where a user does not have any access.

However, you may use the utility of Carl Woll, that returns an inactive FullForm of the atomic object. You may then change this and re-activate. The code for this can be found at: How to extract parts from atomic expressions like DelaunayMesh and Graph?

For your example: You want to change the edge 1->3 into 1->2 and leave the edge 2->3 alone. This can be done after you loaded "Nucleus":

Before:

graph


Now we change the edge 1->3 to 1->2:

Nucleus[graph] /. {1, 3} -> {1, 2} // Activate


• Thank you! It is useful not to have to assign graph to take new edges and use replacement instead. Sep 28, 2022 at 9:40