bnlearn + Rgraphviz: двойные стрелки вместо ненаправленных краев при настройке графиков

Я пытаюсь настроить график графика с bnlearn с помощью RGraphviz, Когда у меня есть ненаправленные края, RGraphviz превращает их в направленные ребра в обоих направлениях, когда я пытаюсь настроить внешний вид графика.

Воспроизводимым примером может быть:

set.seed(1)
x1 = rnorm(50, 0, 1)
x2 = rnorm(50, 0, 1)
x3 = x2 + rnorm(50, 0, 1)
x4 = -2*x1 + x3 + rnorm(50, 0, 1)
graph = data.frame(x1, x2, x3, x4)

library(bnlearn)
library(Rgraphviz)

res = gs(graph)
options(repr.plot.width=3, repr.plot.height=3)
g1 <- graphviz.plot(res)

График не настроен:

Все идет нормально. Но если я попытаюсь настроить это:

plot(g1, attrs = list(node = list(fontsize=4, fillcolor = "lightgreen")))

Индивидуальный график

Ненаправленный край преобразуется.

Я получаю эту проблему, даже если я просто использую plot(g1). Проблема в том, что это (сохранение g1 и затем использование графика), похоже, меняет внешний вид графиков.

1 ответ

Решение

Вы можете изменить некоторые атрибуты, используя highlight аргумент graphviz.plotоднако, похоже, что размер метки не может быть изменен. Вы можете установить это глобально, но при этом происходит потеря контроля.

par(cex=0.05)
graphviz.plot(res, highlight = 
                list(nodes=nodes(res), fill="lightgreen", col="black"))

Как показано в вашем вопросе, вы можете получить немного больше контроля, используя attrs аргумент для метода plot для объекта graphNEL, но опять же возникает проблема направления.

g <- bnlearn::as.graphNEL(res) # use this to avoid printing of graphviz.plot
plot(g,  attrs=list(node = list(fillcolor = "lightgreen", fontsize=4)))

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

graph.par(list(nodes=list(fill="lightgreen", fontsize=10)))
renderGraph( Rgraphviz::layoutGraph(bnlearn::as.graphNEL(res)))

Таким образом, вы можете изменить узлы, возвращаемые graphviz.plot используя функцию nodeRenderInfo:

g1 <- graphviz.plot(res)
graph::nodeRenderInfo(g1) <- list(fill="lightgreen", fontsize=8)
Rgraphviz::renderGraph(g1)

Это, однако, построить график сети при назначении graphviz.plot, Так что в качестве альтернативы вы можете изменить graphNEL объект (возвращается graphviz.plot). По умолчанию graphNEL Объект является либо полностью направленным, либо полностью ненаправленным, однако вы можете настроить края вручную. Это то, что graphviz.plot делает. Глядя на код bnlearn:::graphviz.backend, он идентифицирует ненаправленные ребра и отображает их, используя graph::edgeRenderInfo(graph.plot), Вы можете использовать аналогичные методы, чтобы делать то, что вы хотите - используйте функцию nodeRenderInfo обновить атрибуты узла.

Итак, все вместе:

# this sets all edges to directed
g <- Rgraphviz::layoutGraph(bnlearn::as.graphNEL(res))

# set undirected edges
u <- names(which(graph::edgeRenderInfo(g)[["direction"]] == "both"))
graph::edgeRenderInfo(g)[["arrowhead"]][u] = "none"
graph::edgeRenderInfo(g)[["arrowtail"]][u] = "none"

# update node attributes: fill colour and label fontsize
graph::nodeRenderInfo(g) <- list(fill="lightgreen", fontsize=8)

# render
Rgraphviz::renderGraph(g)
Другие вопросы по тегам