igraph: позиционирование меток и удаление пустого пространства в сетке

Я хочу создать функцию, которая строит ориентированные графы с выровненными вершинами и добавляет некоторый текст под каждой вершиной, то есть что-то вроде приведенного ниже примера графика. Функция построения графика должна иметь возможность обрабатывать круговые диаграммы как вершины, поэтому я использовал пакет igraph в R.

adjm <- matrix(c(0,1,0,1,
                 0,0,1,1,
                 0,0,0,1,
                 0,0,0,0), nrow=4, byrow=TRUE)

g1 <- graph.adjacency(adjm, mode="directed")

values <- lapply(1:4, function(x) sample(1:4,4))

windows(width=7, height=3.5)

plot(g1, layout=layout.grid(g1, width=4), 
     vertex.shape="pie", vertex.pie=values,
     vertex.pie.color=list(heat.colors(4)),
     edge.curved=TRUE,
     vertex.label=LETTERS[1:4], vertex.size=50,
     vertex.label.dist=5, vertex.label.degree=pi/2, 
     edge.label=1:5, rescale=FALSE, 
     xlim=c(-0.2,3.5), ylim=c(0,0.5))

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

У меня две проблемы.

  1. Почему чем длиннее метка вершины, тем больше расстояние до центра вершины, как в следующем примере? Могу ли я заставить их появляться на одном уровне, не находя и не определяя для них правильное расстояние вручную?

    windows(width=7, height=3.5)
    
    plot(g1, layout=layout.grid(g1, width=4), 
         vertex.shape="pie", vertex.pie=values,
         vertex.pie.color=list(heat.colors(4)),
         edge.curved=TRUE,
         vertex.label=c("A", "AA", "AAAA", "AAAAAA"), vertex.size=50,
         vertex.label.dist=5, vertex.label.degree=pi/2, 
         edge.label=1:5, rescale=FALSE, 
         xlim=c(-0.2,3.5), ylim=c(0,0.5))
    

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

  2. Как удалить пустое пространство при построении выровненных участков? Если я сделаю горизонтальный график, он будет размещен внизу окна с большим количеством пустого пространства. Чем более плоское изображение, тем меньше график, как на третьем графике. (Кажется, размер графика определен таким образом, чтобы график помещался в любом положении, вертикальном или горизонтальном.)

    plot(g1, layout=layout.grid(g1, width=4), 
         vertex.shape="pie", vertex.pie=values,
         vertex.pie.color=list(heat.colors(4)),
         edge.curved=TRUE,
         vertex.label=c("A", "AA", "AAAA", "AAAAAA"), vertex.size=20,
         vertex.label.dist=2, vertex.label.degree=pi/2, edge.label=1:5)
    

    введите описание изображения здесьЯ могу написать аргумент asp=0, чтобы сохранить правильный размер вершин в более плоском окне, но автоматические кривизны и положение меток вершин меняется. Я могу вручную настроить отрицательное верхнее поле, расстояния между метками и кривизну краев, но, конечно, это не решение для универсальной функции. До сих пор лучшим результатом был результат rescale=FALSE, как в коде для первого графика, но кривизна краев все еще слишком мала, и с большими вершинами они полностью отстают от вершин. (Кроме того, проблема с различными расстояниями между метками вершин все еще остается.) Прямое использование autocurve.edges не дает мне никакой кривизны. Любые идеи о том, что попробовать дальше?


person Satu    schedule 16.02.2015    source источник


Ответы (1)


Чтобы исправить это, вы можете немного изменить функцию plot.igraph. Для этого можно поэкспериментировать с trace(plot.igraph,edit=TRUE) и модифицировать код функции.

Несколько советов, чтобы получить то, что вы хотите: Для меток строка 319 функции:

y <- layout[, 2] + label.dist * sin(-label.degree) * (vertex.size + 6 * 8 * log10(nchar(labels) + 1))/200

Таким образом, размещение меток y пропорционально количеству символов метки, просто удалите log10(nchar(labels) + 1), и метки останутся на том же уровне.

Что касается проблемы с размером, если вы хотите сохранить rescale, позиция y на графике определяется строкой 55.

layout <- layout.norm(layout, -1, 1, -1, 1)

Вы можете изменить третье число на любое другое, и график будет выше (например, настройки layout <- layout.norm(layout, -1, 1, 0, 1) will center the vertexes on 0). You can also change the margins by changing thepar`. Например, вы можете сделать:

oldMargins<-par("mar")
par(mar=c(10,4,4,4))

и после сюжета par(mar=oldMargins)

Это график, который я получаю, используя этот код после корректировок:

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

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

oldMargins<-par("mar")
par(mar=c(10,4,4,4))
plot(g1, layout=layout.grid(g1, width=4),
     vertex.pie.color=list(heat.colors(4)),
     edge.curved=TRUE,
     vertex.label=c("A", "AA", "AAAA", "AAAAAA"), vertex.size=20,
     vertex.label.dist=1, vertex.label.degree=pi/2, edge.label=1:5,axes=TRUE,
     ylim=c(-0.5,0.5),xlim=c(-1,1))
par(mar=oldMargins)

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

person NicE    schedule 16.02.2015