Services & Resources / Wolfram Forums / MathGroup Archive
-----

MathGroup Archive 2008

[Date Index] [Thread Index] [Author Index]

Search the Archive

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


  • Prev by Date: Re: Re: Product
  • Next by Date: Re: EdgeRenderingFunction to produce edge labels in GraphPlot
  • Previous by thread: Re: EdgeRenderingFunction to produce edge labels in GraphPlot
  • Next by thread: Re: EdgeRenderingFunction to produce edge labels in GraphPlot