问题:跨网络显示算法的迭代提供了每个节点的 XYZ 坐标的更新。尝试以平滑的方式绘制图表似乎无法避免线框重新加载,从而导致频闪效果。附上代码库和视频。
描述:
当前的例子是一个环形网络,意味着一个邻接矩阵,其中每个节点都连接到前后两个节点。节点从 (0,0,0) 一致半径的随机 XYZ 坐标开始,然后经历更新每个节点的 xyz 位置的排序算法。
当前最佳解决方案:
使用 RGL 包,network_plot3d 函数会小心地只打开一个 RGL 对象,并且不会清除整个图形。选项是使用 [rgl.pop3d(type="shapes") 尝试在不重新加载线框的情况下清除图形,或者使用已弃用的 rgl.clear() 并抑制警告。
有没有办法平滑地只更新屏幕上的对象而不更新线框?还有另外的套餐吗
附上代码和视频。
视频 - https://youtu.be/0EAFZiIyRXg
Network_plot3d<-function(attr, edgelist, layout.par = "layout.par") {
# This function will use 'plot3d' to display networks.
# First, it plots the points as spheres. Radius of
# spheres can be related to the number of links (hubs are big)
# The 'natural' sphere size is '3' or 1/20th of the plot.
# df<-update_vertex_count(df,layout.par) #sets size according to degree distribution
lines <- layout.par["lines"]
if (rgl.cur() == 0) {
open3d() # opens the rgl window the first time.
} else {
if (nrow(rgl.ids()) > 0) {
#print("deleting stuff")
rgl.clear()
#print(nrow(rgl.ids(type="shapes")))
}
}
plot3d(attr[, 1:3],
col = attr[, 7],
type = "s",
size = attr[, 8],
xlim = c(-layout.par["xlim"], layout.par["xlim"]),
ylim = c(-layout.par["ylim"], layout.par["ylim"]),
zlim = c(-layout.par["zlim"], layout.par["zlim"])
)
# Now that the points are graphed, we need to get an edgelist
if (lines == TRUE) {
edges <- edge_locations(attr, edgelist)
lines3d(edges)
}
}
sort.surface.sort <- function(attr,edges,layout.par,mod=0){ #This is the original. All nodes go to the average of their neighbors,
#then the nodes blow out from the geometric mean of the network. Result is always a full sphere.
if (mod==0){mod<-layout.par["iterations"]+1} #This sets the mods to the layout.par value, if nothing is given. This controls how often in the iterations to graph.
iterations<-layout.par["iterations"] #sets how many times to run the algorithm
lines<-layout.par["lines"] #should it include lines or only nodes in the final graph?
layout.par["lines"]<-FALSE #turns off lines during the intermediate graphs
nw<-network(edges, directed = layout.par["directed"]) #Uses the provided edgelist, and network package to interpret the edgelist.
hood_list<-get_neighborhoods(nw) #Generates a neighborhood list for all nodes. This happens inside the sort command to allow for network manipulations to exist later -
loud <-layout.par["verbose"] #turns on or off most print messages.
#sort will automatically regenerate from a newly provided edgelist.
attr<-degree_scaler(attr,layout.par) #degree_scaler generates a radius number, with major hubs getting close to zero. however, I'm not sure THIS script actually uses this.
if (loud == 1) # note that TRUE was stored in layout.par["verbose"] as a 1
(print("first it recenters and normalizes everyone to their proper radius"))
attr<-recenter(attr)
attr<-normalize_subjective(attr,target_list=1:nrow(attr),layout.par)
if (loud == 1) (print("Then it moves everyone to their geometric mean - do in order by hubs?"))
for (i in 1:iterations){
if (loud == 1) (print(i))
attr<-geo_mean(hood_list,attr,batch=TRUE,target_list=1:nrow(attr))
attr<-recenter(attr)
attr<-normalize_subjective(attr,target_list=1:nrow(attr),layout.par)
if (i%%mod==0){network_plot3d(attr,edges,layout.par)}
}
#df<-pendulums(df,layout.par,FALSE)
layout.par["lines"]<-lines
pop3d(type="shapes")
#resize(attr,layout.par)
network_plot3d(attr,edges,layout.par)
return(attr)
}
为避免频闪,请在任何更改之前使用
save <- par3d(skipRedraw = TRUE)
,并在完成后使用 par3d(save)
。那么唯一的更新将是从旧显示到新显示,中间不绘制任何内容。