Re: EdgeRenderingFunction to produce edge labels in GraphPlot

*To*: mathgroup at smc.vnet.net*Subject*: [mg87679] Re: [mg87549] EdgeRenderingFunction to produce edge labels in GraphPlot*From*: Murray Eisenberg <murray at math.umass.edu>*Date*: Tue, 15 Apr 2008 05:54:40 -0400 (EDT)*Organization*: Mathematics & Statistics, Univ. of Mass./Amherst*References*: <200804141914.m3EJEAKH027602@rcf1537-4.math.umass.edu> <4803F86D.1020603@wolfram.com>*Reply-to*: murray at math.umass.edu

Thank you for the invaluable assistance here. For a Graph[...] object created within Combinatorica (e.g., Cycle[3], Wheel[4], etc., and graphs derived from them by adding or removing edges or vertices), if one want to retain their vertices' coordinates in the plane when displaying with GraphPlot, then Method->None is used. The complexity of the methods you proposed to work around the additional difficulties I raised will likely scare the daylights out of the undergraduates in my Discrete Structures course! And that complexity suggests the need for further development of Combinatorica and/or GraphPlot so as to allow the two to coexist more comfortably. Obviously one of the core difficulties now is the different structure for graphs that Combinatorica, and its ShowGraph function, expect, on the one hand, and the vertex-coordinate-free structure for graphs fed to GraphPlot, on the other hand. Vertex coordinates are part of a Combinatorica-type graph. I'd sure hate to see that additional structure disappear in any effort to bridge the gap. For many graphs, the way vertex coordinates are chosen automatically by Combinatorica functions often leads to much more attractive disposition of vertices and edges. Yet GraphPlot ofen provides more flexible control over over vertex and edge labeling than does Combinatorica`ShowGraph. One thing that neither method seems to do nicely is to give complete, easy flexibility over placement of vertex or edge labels so that these labels don't lie on top of the vertices or edges, respectively, and at the same time have positions individually controllable so as to keep the labels from being partly obscured by edges (or vertices). Overall, then, I would conclude that the language design issues of handling of graphs is not yet sufficiently understood, or at least if it is sufficiently understood, then the implementation is at a suboptimal intermediate stage right now. That's my two cents. Carl Woll wrote: > Murray Eisenberg wrote: > >> But... >> >> (1) The first method you suggest -- to use SetEdgeLabels to build the >> labels into the Graph object -- does not seem to allow the option >> Method->None in GraphPlot: >> >> g=Cycle[3]; >> g=SetEdgeLabels[g,{"a","b","c"}]; >> GraphPLot[g,Method->None] >> >> This produces a GraphPlot::mthd error saying that None is not a >> permissible method. Why not? I do NOT want GraphPlot to relocate the >> vertices in the plane drawing, but to maintain their location; that's >> the purpose of Method->None, after all. Method->Automatic moves >> vertices and creates an unpleasnt skewing of the eges away from their >> original positions. (This becomes more evident with more complicated >> graphs, e.g., those having horizontal or vertical egdes.) >> >> > I don't know anything about Method->None. > > If you want to use my first method and maintain the vertex locations, > then you need to include that information in the call to GraphPlot. > > Here is a function that creates the usual rule structure that GraphPlot > expects from a Combinatorica graph (with vertex and edge labels): > > torules[Graph[edges_, vertices_, ___]] := Module[ > {vrules}, > vrules = DeleteCases[ > Thread[Range[Length[vertices]] -> (VertexLabel /. vertices[[All,2 > ;;]])], > _ -> VertexLabel > ]; > Replace[ > Transpose[{Rule @@@ (edges[[All,1]] /. vrules), EdgeLabel /. > edges[[All,2 ;;]]}], > {a_, EdgeLabel} -> a, > {1} > ] > ] > > Here is a function that extracts coordinates from a Combinatorica graph: > > getcoords[Graph[edges_, vertices_, ___]] := > Thread[Rule[Range[Length[vertices]], vertices[[All, 1]]]] > > So, let's create a graph with edge and vertex labels: > > g = SetEdgeLabels[SetVertexLabels[Cycle[3], {a, b, c}], {x, y, z}]; > > Now, we'll use GraphPlot to view the graph: > > GraphPlot[torules[g], EdgeLabeling->True, VertexLabeling->True, > VertexCoordinateRules->getcoords[g]] > >> (2) My graphs are UNdirected. I don't readily see how to adapt the >> second method -- using an EdgeRenderingFunction building upon an >> edgeLabelFunction -- to undirected graphs. >> Am I missing something "obvious" here with method (2)? >> >> > If you don't want to use Directed graphs, you'll just need to have your > edgeLabelFunction create the same label for both directions, i.e., {1,2} > and {2,1}. This is because GraphPlot will try to give labels to both > 1->2 and 2->1 if the graph is undirected. Here is an example: > > g = Cycle[3]; > labels = Characters["abc"]; > edgeLabelFunction[{u_, v_}] := > labels[[First@Flatten@Position[Edges[Cycle[3]], {u, v} | {v, u}]]] > > GraphPlot[g, EdgeRenderingFunction -> ({RGBColor[0.5, 0, 0], > Arrowheads[{{0.5, 0.5, > Graphics[{Black, Inset[Style[edgeLabelFunction[#2]], {0, 0}, > ImageScaled[{0.5, 0.5}], Automatic, None, Background -> White]}]}}], > Arrow[#1]} &)] > > Carl Woll > Wolfram Research > >> >> >> >>> Murray Eisenberg wrote: >>> >>> >>>> I'm having trouble fathoming from the documentation how >>>> EdgeRenderingFunction works. In a display produced by GraphPlot, >>>> applied to a graph that's a Graph object created with >>>> Combinatorica, I want to be able to put distinct labels on the edges. >>>> >>>> For example, take something very simple: >>>> >>>> g = Cycle[3]; >>>> >>>> I'd like to put labels "a", "b", "c" on the three {1,2}, {2,3}, >>>> {3,1}, respectively. >>>> >>>> Here's what I tried finally: >>>> >>>> labels = Characters["abc"]; >>>> edgeLabelFunction[{u_, v_}] := >>>> labels[[First@Flatten@Position[Edges[Cycle[3]], {u, v}]]] >>>> >>>> offset={0.05,0.05}; (* to move labels away from edges *) >>>> >>>> GraphPlot[g, Method -> None, >>>> EdgeRenderingFunction -> ({ >>>> Line[#1], >>>> Inset[edgeLabelFunction[#2], Mean[#1] + offset] >>>> ]} &) >>>> ] >>>> >>>> This does not work. How, exactly, do I index into the list of edges... >>>> >>>> Edges[g] >>>> {{1,2},{2,3},{1,3}} >>>> >>>> .. so as to select the labels. From the reference page on >>>> EdgeRenderingFunction, it seems to me that argument #2 is supposed >>>> to be the length 2 list {u,v} of vertices with which the edge is >>>> incident. >>>> >>>> >>>> >>>> >>> It seems that GraphPlot conversions of Combinatorica graphs with edge >>> labels isn't working. Otherwise you could use the Combinatorica >>> function SetEdgeLabels on the graph and then display using >>> EdgeLabeling->True. >>> >>> One possibility is to manipulate the Graph object produced by >>> Combinatorica into a form suitable for GraphPlot. Here is an example: >>> >>> g = SetEdgeLabels[Cycle[3], {a, b, c}]; >>> g = Replace[First@g, {{a_, b_}, opts___} :> (If[MatchQ[#, EdgeLabel], >>> a -> b, {a -> b, #}] &[EdgeLabel /. {opts}]), {1}]; >>> >>> GraphPlot[g, EdgeLabeling -> True] >>> >>> The alternative as you tried to do, is to add the edge labels using >>> EdgeRenderingFunction >>> >>> First, here's a close facsimile to the default EdgeRenderingFunction: >>> >>> EdgeRenderingFunction -> ({ >>> RGBColor[0.5, 0, 0], >>> Arrowheads[{{0.5, 0.5, Graphics[{Black, Inset[Style[#3], {0, 0}, >>> ImageScaled[{0.5, 0.5}], Automatic, None, Background -> White]}]}, >>> {0.03, 0.8}}], >>> Arrow[#1] >>> }&) >>> >>> Now, it's best if the Combinatorica graph is directed (otherwise >>> GraphPlot will try to label it in both directions). So, >>> >>> g = Cycle[3, Type -> Directed]; >>> >>> labels = Characters["abc"]; >>> edgeLabelFunction[{u_, v_}] := >>> labels[[First@Flatten@Position[Edges[Cycle[3, Type -> Directed]], {u, >>> v}]]] >>> >>> GraphPlot[g, EdgeRenderingFunction -> ({RGBColor[0.5, 0, 0], >>> Arrowheads[{{0.5, 0.5, >>> Graphics[{Black, Inset[Style[edgeLabelFunction[#2]], {0, 0}, >>> ImageScaled[{0.5, 0.5}], Automatic, None, >>> Background -> White]}]}, {0.03, 0.8}}], Arrow[#1]} &)] >>> >>> Carl Woll >>> Wolfram Research >>> >>> >> >> >> >> > -- Murray Eisenberg murray at math.umass.edu Mathematics & Statistics Dept. Lederle Graduate Research Tower phone 413 549-1020 (H) University of Massachusetts 413 545-2859 (W) 710 North Pleasant Street fax 413 545-1801 Amherst, MA 01003-9305