Skip to main content
added 111 characters in body
Source Link
Sjoerd Smit
  • 24.8k
  • 48
  • 80

Here's a simple function that can convert Graphics to a graph. With this, you can draw a simple graph with the Drawing Tools palette (http://reference.wolfram.com/language/tutorial/InteractiveGraphicsPalette.html) and then copy the graphics into this function:

graphicsToGraph[gr : _Graphics | _Graphics3D] := Module[{
    pts = Join @@ Cases[gr,
        Point[arg_] :> Replace[Setting[arg], lst : {__?NumericQ} :> {lst}],
        DirectedInfinity[1]
    ],
    edges1 = Cases[gr,
        Line[lst_] :> UndirectedEdge @@ Setting[lst][[{1, -1}]],
        DirectedInfinity[1]
    ],
    edges2 = Cases[gr,
        Arrow[lst_] :> DirectedEdge @@ Setting[lst][[{1, -1}]],
        DirectedInfinity[1]
    ],
    nf, vertices
},
    vertices = Range[Length[pts]];
    
    Condition[
        nf = Nearest[pts -> "Index"];
        Graph[
            vertices,
            Map[First @ nf[#, 1]&, Join[edges1, edges2], {2}],
            VertexCoordinates -> Thread[vertices -> pts]
        ]
        ,
        Length[pts] > 0
    ]
];

enter image description here

The function will look for Point, Line and Arrow primitives and then join them up in the most sensible way it can to make a graph. Only the begin and end points of lines/arrows will be kept, so you can draw segmented lines to avoid spaghetti.

Getting the adjacency matrix, vertex list and edge lists is easy from that point:

AdjacencyMatrix[graph]
VertexList[graph]
EdgeList[graph]

Here's a simple function that can convert Graphics to a graph. With this, you can draw a simple graph with the Drawing Tools palette (http://reference.wolfram.com/language/tutorial/InteractiveGraphicsPalette.html) and then copy the graphics into this function:

graphicsToGraph[gr : _Graphics | _Graphics3D] := Module[{
    pts = Join @@ Cases[gr,
        Point[arg_] :> Replace[Setting[arg], lst : {__?NumericQ} :> {lst}],
        DirectedInfinity[1]
    ],
    edges1 = Cases[gr,
        Line[lst_] :> UndirectedEdge @@ Setting[lst][[{1, -1}]],
        DirectedInfinity[1]
    ],
    edges2 = Cases[gr,
        Arrow[lst_] :> DirectedEdge @@ Setting[lst][[{1, -1}]],
        DirectedInfinity[1]
    ],
    nf, vertices
},
    vertices = Range[Length[pts]];
    
    Condition[
        nf = Nearest[pts -> "Index"];
        Graph[
            vertices,
            Map[First @ nf[#, 1]&, Join[edges1, edges2], {2}],
            VertexCoordinates -> Thread[vertices -> pts]
        ]
        ,
        Length[pts] > 0
    ]
];

enter image description here

The function will look for Point, Line and Arrow primitives and then join them up in the most sensible way it can to make a graph.

Getting the adjacency matrix, vertex list and edge lists is easy from that point:

AdjacencyMatrix[graph]
VertexList[graph]
EdgeList[graph]

Here's a simple function that can convert Graphics to a graph. With this, you can draw a simple graph with the Drawing Tools palette (http://reference.wolfram.com/language/tutorial/InteractiveGraphicsPalette.html) and then copy the graphics into this function:

graphicsToGraph[gr : _Graphics | _Graphics3D] := Module[{
    pts = Join @@ Cases[gr,
        Point[arg_] :> Replace[Setting[arg], lst : {__?NumericQ} :> {lst}],
        DirectedInfinity[1]
    ],
    edges1 = Cases[gr,
        Line[lst_] :> UndirectedEdge @@ Setting[lst][[{1, -1}]],
        DirectedInfinity[1]
    ],
    edges2 = Cases[gr,
        Arrow[lst_] :> DirectedEdge @@ Setting[lst][[{1, -1}]],
        DirectedInfinity[1]
    ],
    nf, vertices
},
    vertices = Range[Length[pts]];
    
    Condition[
        nf = Nearest[pts -> "Index"];
        Graph[
            vertices,
            Map[First @ nf[#, 1]&, Join[edges1, edges2], {2}],
            VertexCoordinates -> Thread[vertices -> pts]
        ]
        ,
        Length[pts] > 0
    ]
];

enter image description here

The function will look for Point, Line and Arrow primitives and then join them up in the most sensible way it can to make a graph. Only the begin and end points of lines/arrows will be kept, so you can draw segmented lines to avoid spaghetti.

Getting the adjacency matrix, vertex list and edge lists is easy from that point:

AdjacencyMatrix[graph]
VertexList[graph]
EdgeList[graph]
Source Link
Sjoerd Smit
  • 24.8k
  • 48
  • 80

Here's a simple function that can convert Graphics to a graph. With this, you can draw a simple graph with the Drawing Tools palette (http://reference.wolfram.com/language/tutorial/InteractiveGraphicsPalette.html) and then copy the graphics into this function:

graphicsToGraph[gr : _Graphics | _Graphics3D] := Module[{
    pts = Join @@ Cases[gr,
        Point[arg_] :> Replace[Setting[arg], lst : {__?NumericQ} :> {lst}],
        DirectedInfinity[1]
    ],
    edges1 = Cases[gr,
        Line[lst_] :> UndirectedEdge @@ Setting[lst][[{1, -1}]],
        DirectedInfinity[1]
    ],
    edges2 = Cases[gr,
        Arrow[lst_] :> DirectedEdge @@ Setting[lst][[{1, -1}]],
        DirectedInfinity[1]
    ],
    nf, vertices
},
    vertices = Range[Length[pts]];
    
    Condition[
        nf = Nearest[pts -> "Index"];
        Graph[
            vertices,
            Map[First @ nf[#, 1]&, Join[edges1, edges2], {2}],
            VertexCoordinates -> Thread[vertices -> pts]
        ]
        ,
        Length[pts] > 0
    ]
];

enter image description here

The function will look for Point, Line and Arrow primitives and then join them up in the most sensible way it can to make a graph.

Getting the adjacency matrix, vertex list and edge lists is easy from that point:

AdjacencyMatrix[graph]
VertexList[graph]
EdgeList[graph]