bnlearn + Rgraphviz:自定义图时双箭头而不是无向边
bnlearn + Rgraphviz: double arrows instead of undirected edges when customizing plots
我正在尝试使用 RGraphviz
自定义通过 bnlearn
学习的图形的绘图。当我有无向边时,当我尝试自定义图形的外观时,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 然后使用 plot)似乎改变了图形的外观。
您可以使用 graphviz.plot
的 highlight
参数更改一些属性,但是,它似乎不允许更改标签大小。您可以全局设置它,但这样做会失去控制。
par(cex=0.05)
graphviz.plot(res, highlight =
list(nodes=nodes(res), fill="lightgreen", col="black"))
如您的问题所示,您可以使用 attrs
参数作为 graphNEL 对象的 plot 方法的参数,但同样存在方向问题。
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)))
因此您可以使用函数 nodeRenderInfo
更改 graphviz.plot
返回的节点:
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)
我正在尝试使用 RGraphviz
自定义通过 bnlearn
学习的图形的绘图。当我有无向边时,当我尝试自定义图形的外观时,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 然后使用 plot)似乎改变了图形的外观。
您可以使用 graphviz.plot
的 highlight
参数更改一些属性,但是,它似乎不允许更改标签大小。您可以全局设置它,但这样做会失去控制。
par(cex=0.05)
graphviz.plot(res, highlight =
list(nodes=nodes(res), fill="lightgreen", col="black"))
如您的问题所示,您可以使用 attrs
参数作为 graphNEL 对象的 plot 方法的参数,但同样存在方向问题。
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)))
因此您可以使用函数 nodeRenderInfo
更改 graphviz.plot
返回的节点:
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)