VertexCoordinate Rules и VertexList из GraphPlot Graphic - PullRequest
5 голосов
/ 22 ноября 2010

Есть ли способ абстрагировать порядок вершин, который GraphPlot применяет к правилам VertexCoordinate из (FullForm или InputForm) графики, созданной GraphPlot? Я не хочу использовать функцию GraphUtilities VertexList. Я также знаю о GraphCoordinates, но обе эти функции работают с графиком, а НЕ с графическим выводом GraphPlot.

Например,

gr1 = {1 -> 2, 2 -> 3, 3 -> 4, 4 -> 5, 5 -> 6, 6 -> 1};
gp1 = GraphPlot[gr1, Method -> "CircularEmbedding", 
   VertexLabeling -> True];

Last@(gp1 /. Graphics[Annotation[x___], ___] :>  {x})

дает следующий список из шести пар координат:

VertexCoordinateRules -> {{2., 0.866025}, {1.5, 1.73205}, {0.5, 1.73205}, {0., 0.866025}, {0.5, 1.3469 * 10 ^ -10}, {1.5, 0.}}

Как узнать, какое правило относится к какой вершине, и могу ли я быть уверен, что это то же самое, что дано VertexList [gr1]?

Например

 Needs["GraphUtilities`"];
gr2 = SparseArray@ 
      Map[# -> 1 &, EdgeList[{2 -> 3, 3 -> 4, 4 -> 5, 5 -> 6}]];

    VertexList[gr2]

дает {1, 2, 3, 4, 5}

Но ....

    gp2 = GraphPlot[gr2, VertexLabeling -> True, 
      VertexCoordinateRules -> 
       Thread[VertexList[gr1] -> 
         Last@(gp1 /. Graphics[Annotation[x___], ___] :>  {x})[[2]]]];
Last@(gp2 /. Graphics[Annotation[x___], ___] :>  {x})

дает шесть наборов координат:

VertexCoordinateRules -> {{2., 0.866025}, {1.5, 1.73205}, {0.5, 1.73205}, {0., 0.866025}, {0.5, 1.3469 * 10 ^ -10}, {1.5, 0.}}

Как я могу абстрагировать правильный VertexList для VertexCoordinateRules для gr2, например?

(я знаю, что могу исправить ситуацию, взяв VertexList после генерации gr2, например, следующим образом)

VertexList@
 SparseArray[
  Map[# -> 1 &, EdgeList[{2 -> 3, 3 -> 4, 4 -> 5, 5 -> 6}]], {6, 6}]

{1, 2, 3, 4, 5, 6}

но необходимая мне информация, по-видимому, присутствует в графике GraphPlot: как ее получить?

(Причина, по которой я преобразую граф в матрицу смежности, заключается в том, что, как указал Карл Волл из Wolfram, он позволяет мне включить «сиротский» узел, как в gp2)

alt text

Ответы [ 2 ]

5 голосов
/ 22 ноября 2010

При маркировке вершин одним из способов является получение координат меток.Обратите внимание, что вывод GraphPlot находится в GraphicsComplex, где координаты псевдонимов координат являются первой меткой, вы можете получить его как

points = Cases[gp1, GraphicsComplex[points_, __] :> points, Infinity] // First

Глядя на FullForm, вы увидите, что метки находятся в текстовых объектах, извлеките ихкак

labels = Cases[gp1, Text[___], Infinity]

Фактическая метка имеет глубину в два уровня, поэтому вы получаете

actualLabels = labels[[All, 1, 1]];

Псевдоним координаты - второй параметр, поэтому вы получаете их как

 coordAliases = labels[[All, 2]]

Фактические координаты были указаны в GraphicsComplex, поэтому мы получаем их как

 actualCoords = points[[coordAliases]]

Между списком координат и списком меток имеется соответствие 1-1, поэтому вы можете использовать Thread, чтобы вернуть их как список меток."-> пары координат.

вот функция, которая все это вместе

getLabelCoordinateMap[gp1_] := 
 Module[{points, labels, actualLabels, coordAliases, actualCoords},
  points = 
   Cases[gp1, GraphicsComplex[points_, __] :> points, Infinity] // 
    First;
  labels = Cases[gp1, Text[___], Infinity];
  actualLabels = labels[[All, 1, 1]];
  coordAliases = labels[[All, 2]];
  actualCoords = points[[coordAliases]];
  Thread[actualLabels -> actualCoords]
  ];
getLabelCoordinateMap[gp1]

Не то, что это работает только с помеченным GraphPlot.Для объектов без меток вы можете попытаться извлечь из других графических объектов, но вы можете получить разные результаты в зависимости от того, из каких объектов вы извлекаете отображение, потому что, кажется, есть ошибка, которая иногда назначает конечные точки линий и метки вершин различным вершинам.Я сообщил об этом.Способ обойти эту ошибку - либо всегда использовать явную спецификацию вершины-> координаты для VertexCoordinateList, либо всегда использовать представление «матрицы смежности».Вот пример несоответствия

graphName = {"Grid", {3, 3}};
gp1 = GraphPlot[Rule @@@ GraphData[graphName, "EdgeIndices"], 
  VertexCoordinateRules -> GraphData[graphName, "VertexCoordinates"], 
  VertexLabeling -> True]
gp2 = GraphPlot[GraphData[graphName, "AdjacencyMatrix"], 
  VertexCoordinateRules -> GraphData[graphName, "VertexCoordinates"], 
  VertexLabeling -> True]

Кстати, кроме этого, вот функции полезности, которые я использую для преобразования между матрицей смежности и представлением правила ребра

edges2mat[edges_] := Module[{a, nodes, mat, n},
   (* custom flatten to allow edges be lists *)

   nodes = Sequence @@@ edges // Union // Sort;
   nodeMap = (# -> (Position[nodes, #] // Flatten // First)) & /@ 
     nodes;
   n = Length[nodes];
   mat = (({#1, #2} -> 1) & @@@ (edges /. nodeMap)) // 
     SparseArray[#, {n, n}] &
   ];
mat2edges[mat_List] := Rule @@@ Position[mat, 1];
mat2edges[mat_SparseArray] := 
 Rule @@@ (ArrayRules[mat][[All, 1]] // Most)
4 голосов
/ 22 ноября 2010

Если вы выполните FullForm[gp1], вы получите кучу выходных данных, которые я не буду публиковать здесь.Рядом с началом вывода вы найдете GraphicsComplex[].По сути, это список точек, а затем список их использования.Итак, для вашей графики gp1 начало графического комплекса:

GraphicsComplex[
 List[List[2., 0.866025], List[1.5, 1.73205], List[0.5, 1.73205], 
  List[0., 0.866025], List[0.5, 1.3469*10^-10], List[1.5, 0.]], 
 List[List[RGBColor[0.5, 0., 0.], 
   Line[List[List[1, 2], List[2, 3], List[3, 4], List[4, 5], 
     List[5, 6], List[6, 1]]]],

Первый самый внешний список определяет позиции 6 точек.Второй крайний список определяет связку линий между этими точками, используя номера точек в первом списке.Вероятно, легче понять, если вы поиграете с этим.

РЕДАКТИРОВАТЬ: В ответ на комментарий ОП, если я выполню:

FullForm[GraphPlot[{3 -> 4, 4 -> 5, 5 -> 6, 6 -> 3}]]

Я получу

    Graphics[Annotation[GraphicsComplex[List[List[0.`,0.9997532360813222`],
List[0.9993931236462025`,1.0258160108662504`],List[1.0286626995939243`,
0.026431169015735057`],List[0.02872413637035287`,0.`]],List[List[RGBColor[0.5`,0.`,0.`],
Line[List[List[1,2],List[2,3],List[3,4],List[4,1]]]],List[RGBColor[0,0,0.7`],
Tooltip[Point[1],3],Tooltip[Point[2],4],Tooltip[Point[3],5],Tooltip[Point[4],6]]],
List[]],Rule[VertexCoordinateRules,List[List[0.`,0.9997532360813222`],
List[0.9993931236462025`,1.0258160108662504`],
List[1.0286626995939243`,0.026431169015735057`],List[0.02872413637035287`,0.`]]]],
Rule[FrameTicks,None],Rule[PlotRange,All],Rule[PlotRangePadding,Scaled[0.1`]],
Rule[AspectRatio,Automatic]]

Список позиций вершин является первым списком внутри GraphicsComplex.Позже в FullForm вы увидите список, в котором Mathematica добавляет всплывающие подсказки для обозначения вершин идентификаторами, которые вы указали в исходном списке ребер.Поскольку то, на что вы сейчас смотрите, это код, описывающий графику, то между вашими вершинами и тем, что будет отображаться, есть только косвенная связь;информация там есть, но распаковать ее не совсем просто.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...