python-3.x - 将 Matplotlib 和 Networkx/Pygraphviz 单位转换为通用单位
问题描述
我正在尝试根据节点数以及是否有节点在水平方向或垂直方向上重叠(即,如果所有节点都在同一条线上,它们会相交)来自动缩放 networkx 图。为此,我查看每个节点的位置并检查位置加上节点大小是否在任何其他节点坐标加上节点大小之间。为了获得节点位置,我使用networkx.nx_agraph.graphviz_layout
. 问题是位置和节点大小不是同一个单位。
Networkx 在底层调用pyplot.scatter
(来源:) https://networkx.github.io/documentation/networkx-1.10/_modules/networkx/drawing/nx_pylab.html#draw_networkx_nodes
,它将节点大小作为像素区域(来源:) https://stackoverflow.com/questions/14827650/pyplot-scatter-plot-marker-size
。
Networkx 使用圆形节点绘制图形,因此基于此将节点大小转换为英寸是有意义的,我会在node_size * 4 / (math.pi * DPI)
哪里做DPI
Matplotlib 使用的 DPI。在我的代码中,这似乎不起作用。我也尝试过取节点大小的平方根并将其除以 DPI,但这似乎也不起作用。
目前的问题是我无法检测到哪些节点重叠。
总之:如果我正在绘制一个带有圆形节点的 networkx 图,如何将节点大小和/或 Pygraphviz 位置转换为一个通用单位?
也可能是我的代码错误,所以这里有一个简短的可重现示例:
NODE_SIZE = 300
DPI = 100
mpl.rcParams['figure.dpi'] = DPI
G = nx.gnp_random_graph(50, 0)
pos = nx.nx_agraph.graphviz_layout(G)
tmp_pos = sorted(pos.items(), key=lambda x: x[1][0]) # Sort it by x value so you only have to check to the right of the node in the list of positions
node_size_inches = NODE_SIZE * 4 / (math.pi * DPI) # This is my attempt at getting the height/width of the nodes
i = 0
for key, xy in tmp_pos:
x = xy[0]
overlapping = []
# Since list is sorted by x, you only need to check nodes to the right
for k, xyt in tmp_pos[i+1:]:
xt = xyt[0]
# Check for overlapping nodes to the right
if x <= xt <= x + node_size_inches:
overlapping.append(k)
# Since list is sorted by x, if the previous condition fails, nothing after can be applicable
else:
break
if overlapping: print("{}:{}".format(key, overlapping))
i += 1
nx.draw(G, pos=pos, with_labels=True)
解决方案
推荐阅读
- plc - B&R Automation Studio 避免在不同位置或机器上构建相同源代码时重新启动 PLC
- android - Kotlin .let {} 空安全
- browserstack - 在 BrowserStack 上使用 nightwatch 运行自动化脚本时如何关闭 safari 弹出对话框?
- python - scikit中混淆矩阵的正确命名
- sql-server - 如何临时填充包含两个日期参数之间的日期的表格?
- java - 来自arraylist列表的Google guva过滤器
- laravel - 使用 Laravel 作为后端开发 SPA、移动应用程序时使用哪个 OAuth2 授权。不会使用第三方登录
- python - 使用 LSTM 进行序列分类,检查输入时出错
- php - laravel 多对多关系枢轴数据保存为空
- javascript - 如何删除textarea中的自定义文本?