Как лучше всего нарисовать большой график с помощью graphvis?
Мне нужно нарисовать большой набор данных на изображении, я использовал командные строки graphvis со всеми доступными инструментами (точка, neato, twopi и т. Д.), Но результат не читается и содержит перекрытия.
Мне нужно отобразить узлы с метками по краям, с минимальным перекрытием, чтобы график можно было читать, а также печатать на бумаге формата А4 или А3.
Я использовал параметры overlap=false, splines=true в neato и тот же результат перекрытия.
Вот набор данных:
graph {
graph [ bgcolor=ivory2, overlap=false, splines=true, ranksep ="2.75"]
{node [width=1,height=1,shape=circle,style=filled,color=skyblue] "ECNY" }
edge [ len=2, sep=5]
"DANA" -- "HMRN" -- "ECNY" -- "NORI" -- "MAJZ" -- "RSFH" -- "DANA" [label ="LD1-25-A01", penwidth =3 , color="#156163"]
"DANA" -- "HMRN" -- "ECNY" -- "NORI" -- "MAJZ" -- "RSFH" -- "DANA" [label ="LD1-25-A02", penwidth =3 , color="#30a1f9"]
"DANA" -- "MAJZ" -- "ECNY" -- "HMRN" -- "DANA" [label ="LD1-25-A03", penwidth =3 , color="#ec591d"]
"DANA" -- "MAJZ" -- "ECNY" -- "HMRN" -- "DANA" [label ="LD1-25-A04", penwidth =3 , color="#263a5f"]
"DANA" -- "ECNY" -- "DANA" [label ="LD3-25-A02", penwidth =3 , color="#a3517c"]
"HMRN" -- "ECNY" -- "MAJZ" -- "DANA" -- "HMRN" [label ="LD1-25-H01", penwidth =3 , color="#800d83"]
"HMRN" -- "ECNY" -- "MAJZ" -- "DANA" -- "TWRN" -- "HMRN" [label ="LD1-25-H02", penwidth =3 , color="#89e15a"]
"HMRN" -- "ECNY" -- "MAJZ" -- "DANA" -- "TWRN" -- "HMRN" [label ="LD3-25-H03", penwidth =3 , color="#74ed0e"]
"HMRN" -- "ECNY" -- "HMRN" [label ="JED-10-H08", penwidth =3 , color="#e8e786"]
"HMRN" -- "ECNY" -- "MAJZ" -- "DANA" -- "HMRN" [label ="LD1-25-H04", penwidth =3 , color="#e1f559"]
"ECNY" -- "HMRN" -- "ECNY" [label ="JED-10-A02", penwidth =3 , color="#8f7964"]
"ECNY" -- "HMRN" -- "ECNY" [label ="JED-10-A03", penwidth =3 , color="#9058f0"]
"ECNY" -- "HMRN" -- "SBCB" -- "ECNY" [label ="JED-10-A04", penwidth =3 , color="#b537b7"]
"ECNY" -- "HMRN" -- "SBCB" -- "ECNY" [label ="JED-10-A05", penwidth =3 , color="#fc2c2a"]
"ECNY" -- "HMRN" -- "ECNY" [label ="JED-10-A06", penwidth =3 , color="#36309c"]
"ECNY" -- "HMRN" -- "ECNY" [label ="JED-10-A07", penwidth =3 , color="#25a571"]
"ECNY" -- "OBHR" -- "ECNY" [label ="JED-10-A26", penwidth =3 , color="#1a6077"]
"ECNY" -- "2820" -- "ECNY" [label ="JED-25-A03", penwidth =3 , color="#8bce8c"]
"ECNY" -- "2138" -- "2129" -- "ECNY" [label ="JED-25-A04", penwidth =3 , color="#9b9afa"]
"ECNY" -- "2017" -- "2013" -- "ECNY" [label ="JED-25-A05", penwidth =3 , color="#5ea9aa"]
"ECNY" -- "2027" -- "2128" -- "ECNY" [label ="JED-25-A22", penwidth =3 , color="#c0c4d4"]
"ECNY" -- "2130" -- "2137" -- "ECNY" [label ="JED-25-A27", penwidth =3 , color="#781ce0"]
"ECNY" -- "DANA" -- "ECNY" [label ="LD3-25-A01", penwidth =3 , color="#fd5c5a"]
"ECNY" -- "HMRN" -- "ZJ01" -- "ECNY" [label ="JED-10-H03", penwidth =3 , color="#32e13b"]
"ECNY" -- "HMRN" -- "ECNY" [label ="JED-10-H04", penwidth =3 , color="#487f94"]
"ECNY" -- "2341" -- "2235" -- "2233" -- "ECNY" [label ="JED-10-H05", penwidth =3 , color="#82ae2d"]
"ECNY" -- "HMRN" -- "SBCB" -- "ECNY" [label ="JED-10-H06", penwidth =3 , color="#f4651c"]
"ECNY" -- "HMRN" -- "SBCB" -- "ECNY" [label ="JED-10-H07", penwidth =3 , color="#23dd41"]
"ECNY" -- "HMRN" -- "OBHR" -- "ECNY" [label ="JED-10-H37", penwidth =3 , color="#521f43"]
"ECNY" -- "PROJECT" -- "ECNY" [label ="JED-10-H49", penwidth =3 , color="#0a4bf1"]
"ECNY" -- "2234" -- "2246" -- "2245" -- "2320" -- "ECNY" [label ="JED-25-H01", penwidth =3 , color="#6127e4"]
"ECNY" -- "2842" -- "2030" -- "ECNY" [label ="JED-25-H03", penwidth =3 , color="#ce1f98"]
"ECNY" -- "2170" -- "2166" -- "ECNY" [label ="JED-25-H06", penwidth =3 , color="#aeb0ce"]
"ECNY" -- "2158" -- "2144" -- "ECNY" [label ="JED-25-H11", penwidth =3 , color="#9ef618"]
"ECNY" -- "5824" -- "2011" -- "ECNY" [label ="JED-25-H15", penwidth =3 , color="#b2d524"]
"ECNY" -- "2010" -- "2830" -- "2198" -- "ECNY" [label ="JED-25-H16", penwidth =3 , color="#53e7ae"]
"ECNY" -- "2179" -- "ECNY" [label ="JED-25-H17", penwidth =3 , color="#149169"]
"ECNY" -- "2211" -- "ECNY" [label ="JED-25-H19", penwidth =3 , color="#15a51b"]
"ECNY" -- "2316" -- "ECNY" [label ="JED-25-H20", penwidth =3 , color="#e91d18"]
"ECNY" -- "2203" -- "ECNY" [label ="JED-25-H22", penwidth =3 , color="#38a23a"]
"ECNY" -- "SBCB" -- "JFCC" -- "ECNY" [label ="JED-25-H33", penwidth =3 , color="#a1abf4"]
"ECNY" -- "HMRN" -- "ECNY" [label ="JED-25-H41", penwidth =3 , color="#c14ff8"]
"ECNY" -- "TAIF" -- "SNFN" -- "NORI" -- "ECNY" [label ="LD1-10-H04", penwidth =3 , color="#75fb4f"]
"ECNY" -- "MAJZ" -- "DANA" -- "TWRN" -- "HMRN" -- "ECNY" [label ="LD1-25-H03", penwidth =3 , color="#52d1c8"]
"ECNY" -- "DANA" -- "ECNY" [label ="LD3-25-H01", penwidth =3 , color="#498a16"]
"ECNY" -- "DANA" -- "ECNY" [label ="LD3-25-H02", penwidth =3 , color="#70f831"]
"ECNY" -- "2310" -- "5880" -- "5301" -- "2248" -- "ECNY" [label ="JED-10-H17", penwidth =3 , color="#ebb4e1"]
"SBCB" -- "ECNY" -- "HMRN" -- "JELS" -- "ROMN" -- "OBHR" -- "SAFA" -- "SBCB" [label ="JED-W40-A01", penwidth =3 , color="#7ff59c"]
"SBCB" -- "SAFA" -- "OBHR" -- "HMRN" -- "ECNY" -- "SBCB" [label ="JED-10-H35", penwidth =3 , color="#e817b9"]
"2171" -- "ECNY" -- "2171" [label ="JED-10-H19", penwidth =3 , color="#bf1252"]
"ABHA" -- "ECNY" -- "DANA" -- "ABHA" [label ="LD3-10-H01", penwidth =3 , color="#8b60ae"]
"MAJZ" -- "ECNY" -- "DANA" -- "2510" -- "MAJZ" [label ="LD1-10-H02", penwidth =3 , color="#1e3c55"]
"2209" -- "2206" -- "ECNY" -- "2209" [label ="JED-25-H02", penwidth =3 , color="#1b6092"]
}
это один из выводов при использовании этих опций (в neato):
graph [bgcolor = ivory2, overlap=false, splines=true, ranksep = "2.75"]
{узел [ширина =1, высота =1, форма = круг, стиль = заполненный, цвет = небесно-голубой] "ECNY" }
край [ len=2, sep=5]
также это когда make overlap=scale, но изображение не читается!
перекрытие = масштаб, sep=\"+25,25\", сплайны =true, rankdir=\"TB\"
так какие еще атрибуты могут улучшить этот график?
4 ответа
Неизбежно, когда число узлов и ребер увеличивается, мы в конечном итоге останемся без достаточного пространства, чтобы иметь компактный, но тем не менее четкий граф. Тем не менее, я думаю, что есть некоторые вещи, которые мы можем улучшить. В этом случае мы можем воспользоваться тем фактом, что все последовательности ребер образуют петли, которые возвращаются к "ECNY".
Сначала я взвесил ребра, которые ближе к "ECNY" (чтобы они были более эластичными), и сделал их длиннее по умолчанию (чтобы середина графика была более разложенной), и наоборот, с ребрами, которые расположены дальше. от "ECNY".
Во-вторых, я пометил каждую петлю только один раз, причем метка находилась на краю настолько далеко от "ECNY" в петле, насколько я мог получить.
Я сделал эти изменения программно с помощью скрипта Python adjweight.py
следующее:
import sys, re, math
for line in sys.stdin:
line = line.rstrip()
if re.match(' +"',line):
loop, attr = line.split(" [")
loopli = loop.split(" -- ")[1:]
# We take all but the first node, to eliminate repeats
# then we put the list of edges together with "ECNY" first and last.
i = loopli.index('"ECNY"')
loopli = loopli[i:] + loopli[:i] + [loopli[i]]
n = len(loopli)
# Now we write the multi-edge lines as individual lines so that we can
# give each edge an individual weight and length
for i in range(n-1):
# We weight edges that are furthest from the center (i.e. those with
# numbers closest to n/2) highest and those that are closest to the
# center are weighted lowest.
wt = (n/2)/(abs(n/2 - (i+1))+1)
edgelength = 1/wt
if i - n//2 + 1 != 0:
# This edge is the furthest from the center in this loop, so we
# label this edge (but not the other edges in the loop)
attr = ",".join(attr.split(",")[1:])
# We raise the weights and edge lengths to different powers to adjust
# the distribution of nodes across the "diameter" of the graph
print (" %s -- %s [weight = %f, len = %f, %s" % (
loopli[i],loopli[i+1],wt**3,edgelength**2,attr))
else:
print (line)
... который может быть запущен с python adjweight.py <large.dot >large3.dot
, где large.dot
это .dot
файл показан в вопросе.
Изменение размера шрифта для краев до 10 (по сравнению со значением по умолчанию 14) и запуск large3.dot
через neato
дал мне следующий график:
Это распределяет узлы более равномерно по всей странице, и это намного менее загромождается краевыми метками, поэтому мне кажется, что это улучшение. Пограничные метки по-прежнему перекрывают несколько узлов и (особенно в правом верхнем углу графика) другие пограничные метки, потому что overlap
Параметр влияет только на узлы и линии ребер, а не на метки ребер.
Изменение относительной длины и веса ребер в зависимости от расстояния от "ECNY" может помочь немного улучшить график.
Мне нужно визуализировать весь путь от определенного узла к другим узлам, поэтому моя проблема с визуализацией узлов не в упрощении.Хорошо, вы уже визуализируете весь путь от определенного узла к другим узлам. Но, как вы сказали, ** результат не читается и содержит перекрытие **. я думаю, что вам нужно, чтобы сделать это визуализирующим, мой следующий совет, чтобы вы попытались визуализировать свой график вручную на небольших данных, используя (3-мерный график), затем закодируйте его или попробуйте найти атрибуты для визуализации его на 3D, если он хорошо работает на малых данные.
я просто пытаюсь думать, как помочь в этой проблеме, так что все это всего лишь предложения и открытые вопросы, чтобы вы могли найти ответ на свой вопрос.
Почему бы вам сначала не попытаться уменьшить данные на вашем графике (т. Е. Даже если вы получили свою реализацию - трудно следить за графиком), а основная идея представления данных на графике - это упрощение, и вы потеряете его) ПОПРОБУЙТЕ УМЕНЬШИТЬ ДАННЫЕ НА ГРАФЕ.
Я рекомендую использовать программное обеспечение / фреймворк, в котором используются популярные алгоритмы силового макета ( http://en.wikipedia.org/wiki/Force-directed_graph_drawing), наиболее популярными из которых являются Fruchterman-Reingold и Kamada-Kawai. Я использовал R ( http://www.r-project.org/) с пакетом igraph. Я знаю, что это своего рода не ответ на ваш вопрос, поскольку вы сказали, что используете graphvis, но использование силовых алгоритмов - ваш лучший выбор.