Края Graphviz не различимы / метки краев перезаписываются

Я свел свою проблему к следующему простому примеру:

digraph {
subgraph {rank=same; 0 -> 1 -> 2;}
0 -> 2 [label="A"];
2 -> 0 [label="B"];
}

который производит

введите описание изображения здесь

Сохраняя 0, 1 и 2 в одном ранге (исходный пример находится в контексте большего графа), мне нужно, чтобы ребра A и B были различимы. то есть края должны четко совпадать с этикетками, и этикетки должны быть читаемыми.

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

0:ne -> 2:nw [label="A"];
2:sw -> 0:se [label="B"];

однако это производит

введите описание изображения здесь

Другие идеи? Я создаю более крупные графики с той же проблемой, поэтому лучшим решением не будет полностью специальное ручное размещение ребер / меток.

Изменить: (все еще упрощенный) пример большого сгенерированного графика следующий.

digraph {
size = "6,8.5";
ratio = "fill";
node [shape = circle];
node [fontsize = 24];
edge [fontsize = 24];
{graph [rank=same]; edge[color=invis];1;}
{graph [rank=same]; edge[color=invis];2 -> 0 -> 3 -> 4;}
0 -> 0 [label="6: 0.1764"];
0 -> 4 [label="4: 0.1304"];
0 -> 3 [label="5: 0.1551"];
0 -> 2 [label="7: 0.1489"];
0 -> 1 [label="Z: 0.3893"];
4 -> 0 [label="6: 0.1237"];
4 -> 3 [label="5: 0.05201"];
4 -> 2 [label="7: 0.15  "];
4 -> 1 [label="Z: 0.4585"];
3 -> 0 [label="6: 0.1658"];
3 -> 4 [label="4: 0.13  "];
3 -> 3 [label="5: 0.1038"];
3 -> 2 [label="7: 0.1616"];
3 -> 1 [label="Z: 0.4388"];
2 -> 0 [label="6: 0.1661"];
2 -> 4 [label="4: 0.1295"];
2 -> 3 [label="5: 0.2078"];
2 -> 2 [label="7: 0.1406"];
2 -> 1 [label="Z: 0.356 "];
1 -> 0 [label="6: 0.1103"];
1 -> 4 [label="4: 0.2591"];
1 -> 3 [label="5: 0.1382"];
1 -> 2 [label="7: 0.08581"];
1 -> 1 [label="Z: 0.1906"];
}

Это производит:

введите описание изображения здесь

который демонстрирует ту же проблему перекрытия края / метки в более простом примере выше.

Прочие примечания:

  • Эта проблема возникает, когда есть узел в середине двунаправленно связанной пары узлов в подграфе того же ранга. Это может быть подмножество условий, при которых обнаружена ошибка.
  • Эта проблема существует и для неориентированных графов.

person watsonic    schedule 26.04.2014    source источник


Ответы (3)


Первый пример явно является ошибкой; метки краев должны быть расположены в разных местах, которые затем разделяют края. (В общем, мы знаем, что в коде плоских краев есть дыры, особенно при работе с метками.) Одним из способов решения проблемы является обработка некоторых или всех меток краев как внешних меток:

digraph {
subgraph {rank=same; 0 -> 1 -> 2;}
0 -> 2 [xlabel="A"];
2 -> 0 [xlabel="B"];
}

Что касается проблемы изменения цвета шрифта для меток, упомянутых в предыдущем ответе, это можно сделать с помощью меток, подобных HTML:

0 -> 2 [dir="both", color="black:gray", labeldistance="2", 
  headlabel=<<font color="red">A</font>>, taillabel="B"];

Это можно использовать для любого текста вместо обычных строк в двойных кавычках.

person Emden    schedule 29.04.2014

Вы можете частично решить эту проблему с помощью dir="both" и colorList.

digraph {
    subgraph {rank=same; 0 -> 1 -> 2;}
    0 -> 2 [dir="both", color="black:gray", labeldistance="2", headlabel="A", taillabel="B"];
}

приводит к этому:

используя dir = both

Мне пришлось использовать labelDistance, чтобы метка «А» не отображалась поверх стрелки. К сожалению, я не мог понять, как изменить цвет шрифта индивидуально для метки головы и метки хвоста, чтобы было более понятно, какая метка применяется к какой стрелке.

person SSteve    schedule 28.04.2014

Ответы как от ssteve, так и от emden были очень полезны и получили одобрение. (Спасибо вам обоим!)

Я учитываю мнения обоих и отвечаю на этот вопрос в более сложной версии. Я все еще не считаю решение идеальным, но это лучшее, что я могу создать. Будущие ответы, которые улучшат это (см. Ниже, что, по-видимому, все еще отсутствует) и которые адресованы к более крупной версии графа (см. Вопрос) способом, который может быть автоматизирован, будут приняты вместо этого ответа.

Во-первых, лучшее решение на данный момент: превратить метки в xlabels для некоторых кромок (например, половины всех двунаправленных кромок, выбранных случайным образом) и случайным образом раскрасить кромки и соответствующие метки (через fontcolor).

В частности, вот пример этого решения, где края случайным образом имеют красный, зеленый или черный цвет:

digraph {
size = "6,10.5";
ratio = "fill";
node [shape = circle];
node [fontsize = 24];
edge [fontsize = 24];
{graph [rank=same]; edge[color=invis];1;}
{graph [rank=same]; edge[color=invis];2 -> 0 -> 3 -> 4;}
0 -> 0 [label="6: 0.1764"];
0 -> 4 [xlabel="4: 0.1304" color=blue fontcolor=blue];
0 -> 3 [xlabel="5: 0.1551" color=green fontcolor=green];
0 -> 2 [label="7: 0.1489" color=red fontcolor=red];
0 -> 1 [label="Z: 0.3893"];
4 -> 0 [xlabel="6: 0.1237" color=green fontcolor=green];
4 -> 3 [xlabel="5: 0.05201 " color=green fontcolor=green];
4 -> 2 [xlabel="7: 0.15" color=blue fontcolor=blue];
4 -> 1 [label="Z: 0.4585" color=red fontcolor=red];
3 -> 0 [xlabel="6: 0.1658"];
3 -> 4 [xlabel="4: 0.13" color=red fontcolor=red];
3 -> 3 [label="5: 0.1038" color=blue fontcolor=blue];
3 -> 2 [xlabel="7: 0.1616"];
3 -> 1 [label="Z: 0.4388"];
2 -> 0 [label="6: 0.1661" color=blue fontcolor=blue];
2 -> 4 [xlabel="4: 0.1295" color=red fontcolor=red];
2 -> 3 [label="5: 0.2078" color=green fontcolor=green];
2 -> 2 [label="7: 0.1406"];
2 -> 1 [label="Z: 0.356 "];
1 -> 0 [label="6: 0.1103" color=red fontcolor=red];
1 -> 4 [label="4: 0.2591" color=blue fontcolor=blue];
1 -> 3 [label="5: 0.1382" color=green fontcolor=green];
1 -> 2 [label="7: 0.08581 "];
1 -> 1 [label="Z: 0.1906"];
}  

Это дает: введите описание изображения здесь

Это все еще не совсем удовлетворительно, потому что:

  1. Хотя теперь легче отследить метки до их краев, некоторые метки появляются в странных местах при использовании xlabel. (например, над меткой 2 -> 4)
  2. Случайный выбор ярлыков, которые станут xlables, кажется произвольным. Также нет способа (я знаю) гарантировать, что это всегда сработает.

Другие вещи, которые я пробовал:

  • Сделайте каждый ярлык xlabel. Результат: все уплотняется, надписи накладываются друг на друга и закрывают друг друга.
  • Используйте xlabel для всех двунаправленных краев. Результат: та же проблема, что и выше.
  • Используйте xlabels без цветов. Результат: сложно отследить, какой лейбл чему принадлежит.
  • Используйте решение ssteve. Цвет краев случайный. И установите labeldistance случайным образом между 3 и 11 для заголовков и хвостовых меток, чтобы избежать перекрытия меток в узлах. Результат: это сложнее автоматизировать, и это по-прежнему приводит как к перекрытию меток кромок, так и к меткам, которые трудно отследить до кромок, которым они соответствуют. (увидеть ниже)

Вот пример последнего пункта в списке решений «Другие вещи, которые я пробовал» выше.

size = "6,8.5";
ratio = "fill";
node [shape = circle];
node [fontsize = 24];
edge [fontsize = 24];
{graph [rank=same]; edge[color=invis];1;}
{graph [rank=same]; edge[color=invis];2 -> 0 -> 3 -> 4;}
0 -> 0 [label="6: 0.1764"];
0 -> 4 [dir="both", color="yellow:blue", labeldistance="5", headlabel=<<font color="yellow">4: 0.1304</font>>, taillabel=<<font color="blue">6: 0.1237</font>>];
0 -> 3 [dir="both", color="blue:black", labeldistance="8", headlabel=<<font color="blue">5: 0.1551</font>>, taillabel=<<font color="black">6: 0.1658</font>>];
0 -> 1 [label="Z: 0.3893"];
4 -> 1 [label="Z: 0.4585"];
3 -> 4 [dir="both", color="green:red", labeldistance="5", headlabel=<<font color="green">4: 0.13</font>>, taillabel=<<font color="red">5: 0.05201</font>>];
3 -> 3 [label="5: 0.1038"];
3 -> 1 [label="Z: 0.4388"];
2 -> 0 [dir="both", color="yellow:blue", labeldistance="11", headlabel=<<font color="yellow">6: 0.1661</font>>, taillabel=<<font color="blue">7: 0.1489</font>>];
2 -> 4 [dir="both", color="black:red", labeldistance="5", headlabel=<<font color="black">4: 0.1295</font>>, taillabel=<<font color="red">7: 0.15</font>>];
2 -> 3 [dir="both", color="blue:green", labeldistance="8", headlabel=<<font color="blue">5: 0.2078</font>>, taillabel=<<font color="green">7: 0.1616</font>>];
2 -> 2 [label="7: 0.1406"];
2 -> 1 [label="Z: 0.356 "];
1 -> 0 [label="6: 0.1103"];
1 -> 4 [label="4: 0.2591"];
1 -> 3 [label="5: 0.1382"];
1 -> 2 [label="7: 0.08581 "];
1 -> 1 [label="Z: 0.1906"];
}

Это производит:

введите описание изображения здесь

Запрошены другие идеи / улучшения ...

person watsonic    schedule 06.05.2014