我想绘制 subgroups的晶格带有图形工具的离散空间组,例如 yed , graphviz , networkx ,...
一个示例输入文件
将遵循 graphml
二维空间组的文件 p4gm 到索引8(由 gaap ):
<?xml version='1.0' encoding='UTF-8'?>
<graphml
xmlns='http://graphml.graphdrawing.org/xmlns'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xsi:schemaLocation='http://graphml.graphdrawing.org/xmlns
http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd'>
<key id='idx' for='node' attr.name='index' attr.type='int' />
<key id='r' for='node' attr.name='radius' attr.type='double' />
<key id='idx' for='edge' attr.name='index' attr.type='int' />
<graph id='G' edgedefault='directed'>
<node id='01'> <data key='idx'>1</data> <data key='r'>0.</data> </node>
<node id='02'> <data key='idx'>2</data> <data key='r'>0.33333333333333337</data> </node>
<node id='03'> <data key='idx'>2</data> <data key='r'>0.33333333333333337</data> </node>
<node id='04'> <data key='idx'>2</data> <data key='r'>0.33333333333333337</data> </node>
<node id='05'> <data key='idx'>4</data> <data key='r'>0.66666666666666674</data> </node>
<node id='06'> <data key='idx'>4</data> <data key='r'>0.66666666666666674</data> </node>
<node id='07'> <data key='idx'>6</data> <data key='r'>0.8616541669070521</data> </node>
<node id='08'> <data key='idx'>4</data> <data key='r'>0.66666666666666674</data> </node>
<node id='09'> <data key='idx'>4</data> <data key='r'>0.66666666666666674</data> </node>
<node id='10'> <data key='idx'>4</data> <data key='r'>0.66666666666666674</data> </node>
<node id='11'> <data key='idx'>4</data> <data key='r'>0.66666666666666674</data> </node>
<node id='12'> <data key='idx'>4</data> <data key='r'>0.66666666666666674</data> </node>
<node id='13'> <data key='idx'>6</data> <data key='r'>0.8616541669070521</data> </node>
<node id='14'> <data key='idx'>8</data> <data key='r'>1.</data> </node>
<node id='15'> <data key='idx'>8</data> <data key='r'>1.</data> </node>
<node id='16'> <data key='idx'>8</data> <data key='r'>1.</data> </node>
<node id='17'> <data key='idx'>8</data> <data key='r'>1.</data> </node>
<node id='18'> <data key='idx'>8</data> <data key='r'>1.</data> </node>
<node id='19'> <data key='idx'>8</data> <data key='r'>1.</data> </node>
<node id='20'> <data key='idx'>8</data> <data key='r'>1.</data> </node>
<node id='21'> <data key='idx'>8</data> <data key='r'>1.</data> </node>
<node id='22'> <data key='idx'>8</data> <data key='r'>1.</data> </node>
<node id='23'> <data key='idx'>8</data> <data key='r'>1.</data> </node>
<node id='24'> <data key='idx'>8</data> <data key='r'>1.</data> </node>
<node id='25'> <data key='idx'>8</data> <data key='r'>1.</data> </node>
<node id='26'> <data key='idx'>8</data> <data key='r'>1.</data> </node>
<edge id='e01' target='02' source='01'> <data key='idx'>2</data> </edge>
<edge id='e02' target='03' source='01'> <data key='idx'>2</data> </edge>
<edge id='e03' target='04' source='01'> <data key='idx'>2</data> </edge>
<edge id='e04' target='05' source='02'> <data key='idx'>2</data> </edge>
<edge id='e05' target='06' source='02'> <data key='idx'>2</data> </edge>
<edge id='e06' target='07' source='02'> <data key='idx'>3</data> </edge>
<edge id='e07' target='06' source='03'> <data key='idx'>2</data> </edge>
<edge id='e08' target='08' source='03'> <data key='idx'>2</data> </edge>
<edge id='e09' target='06' source='04'> <data key='idx'>2</data> </edge>
<edge id='e10' target='10' source='04'> <data key='idx'>2</data> </edge>
<edge id='e11' target='11' source='04'> <data key='idx'>2</data> </edge>
<edge id='e12' target='09' source='04'> <data key='idx'>2</data> </edge>
<edge id='e13' target='12' source='04'> <data key='idx'>2</data> </edge>
<edge id='e14' target='13' source='04'> <data key='idx'>3</data> </edge>
<edge id='e15' target='14' source='05'> <data key='idx'>2</data> </edge>
<edge id='e16' target='15' source='05'> <data key='idx'>2</data> </edge>
<edge id='e17' target='14' source='06'> <data key='idx'>2</data> </edge>
<edge id='e18' target='16' source='06'> <data key='idx'>2</data> </edge>
<edge id='e19' target='17' source='06'> <data key='idx'>2</data> </edge>
<edge id='e20' target='18' source='06'> <data key='idx'>2</data> </edge>
<edge id='e21' target='16' source='08'> <data key='idx'>2</data> </edge>
<edge id='e22' target='19' source='08'> <data key='idx'>2</data> </edge>
<edge id='e23' target='18' source='09'> <data key='idx'>2</data> </edge>
<edge id='e24' target='20' source='09'> <data key='idx'>2</data> </edge>
<edge id='e25' target='14' source='10'> <data key='idx'>2</data> </edge>
<edge id='e26' target='16' source='11'> <data key='idx'>2</data> </edge>
<edge id='e27' target='21' source='11'> <data key='idx'>2</data> </edge>
<edge id='e28' target='22' source='11'> <data key='idx'>2</data> </edge>
<edge id='e29' target='23' source='11'> <data key='idx'>2</data> </edge>
<edge id='e30' target='18' source='12'> <data key='idx'>2</data> </edge>
<edge id='e31' target='21' source='12'> <data key='idx'>2</data> </edge>
<edge id='e32' target='24' source='12'> <data key='idx'>2</data> </edge>
<edge id='e33' target='25' source='12'> <data key='idx'>2</data> </edge>
<edge id='e34' target='26' source='12'> <data key='idx'>2</data> </edge>
</graph>
</graphml>
我将数据匿名为专注于图形图。
我正在寻找一个可以在径向布局上布局的图形绘图工具,类似于 radial树,但可以绘制非旋转边缘以避免边缘节点交叉。边缘交叉很好。但是,理想情况下,观看者可以遵循从源节点到目标节点的每个边缘。
yed (3.22)
提供一个 radial layout ,可以将边缘绘制为弧或弯曲以避免边缘节点交叉:
但是,节点放在同一同心圆上基于距中心的最短距离,以横穿边缘的数量来衡量。
但是我想根据节点的子组索引放置这些节点(确切地说是索引的对数)。在上图中,具有索引6的节点与索引4的节点在同一圆圈上,这不是我想要的。
NetworkX (2.8.4)
具有允许您手动分配节点为shells
import networkx as nx
import matplotlib.pyplot as plt
from math import log
G = nx.read_graphml("ITC_2_012_idx8.graphml")
indices = set([idx for n, idx in G.nodes.data('index')])
radii = [log(idx)/log(max(indices)) for n, idx in G.nodes.data('index')]
shells = [[n for n, idx in G.nodes.data('index') if idx == x] for x in indices]
pos = nx.shell_layout(G, shells)
plt.box(False) # remove box
nx.draw_networkx(G, pos,
node_color="white",
node_size=500,
edgecolors="black",
labels={n: idx for n, idx in G.nodes.data('index')},
)
但是,NetworkX仅绘制直边。
GraphViz或其他图形绘图工具可以做我想要的吗?
我已经开始创建一个自己的布局和边缘路由算法,该算法以以下绘图样式:
但是,这是未完成的,成为一个永无止境的故事。因此,我希望我已经忽略了一个工具,该工具可以自动提供所需的径向布局和合适的边路路线。
YED是我收到的最接近的工具(请参阅此问题的第一张图片)。
I want to draw the lattice of subgroups up to a finite subgroup index of an infinite, discrete space group with a graph drawing tool such as yEd, GraphViz, NetworkX, ...
An Example input file
would be following graphml
file for the two-dimensional space group p4gm up to index 8 (generated by self-written code in gap):
<?xml version='1.0' encoding='UTF-8'?>
<graphml
xmlns='http://graphml.graphdrawing.org/xmlns'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xsi:schemaLocation='http://graphml.graphdrawing.org/xmlns
http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd'>
<key id='idx' for='node' attr.name='index' attr.type='int' />
<key id='r' for='node' attr.name='radius' attr.type='double' />
<key id='idx' for='edge' attr.name='index' attr.type='int' />
<graph id='G' edgedefault='directed'>
<node id='01'> <data key='idx'>1</data> <data key='r'>0.</data> </node>
<node id='02'> <data key='idx'>2</data> <data key='r'>0.33333333333333337</data> </node>
<node id='03'> <data key='idx'>2</data> <data key='r'>0.33333333333333337</data> </node>
<node id='04'> <data key='idx'>2</data> <data key='r'>0.33333333333333337</data> </node>
<node id='05'> <data key='idx'>4</data> <data key='r'>0.66666666666666674</data> </node>
<node id='06'> <data key='idx'>4</data> <data key='r'>0.66666666666666674</data> </node>
<node id='07'> <data key='idx'>6</data> <data key='r'>0.8616541669070521</data> </node>
<node id='08'> <data key='idx'>4</data> <data key='r'>0.66666666666666674</data> </node>
<node id='09'> <data key='idx'>4</data> <data key='r'>0.66666666666666674</data> </node>
<node id='10'> <data key='idx'>4</data> <data key='r'>0.66666666666666674</data> </node>
<node id='11'> <data key='idx'>4</data> <data key='r'>0.66666666666666674</data> </node>
<node id='12'> <data key='idx'>4</data> <data key='r'>0.66666666666666674</data> </node>
<node id='13'> <data key='idx'>6</data> <data key='r'>0.8616541669070521</data> </node>
<node id='14'> <data key='idx'>8</data> <data key='r'>1.</data> </node>
<node id='15'> <data key='idx'>8</data> <data key='r'>1.</data> </node>
<node id='16'> <data key='idx'>8</data> <data key='r'>1.</data> </node>
<node id='17'> <data key='idx'>8</data> <data key='r'>1.</data> </node>
<node id='18'> <data key='idx'>8</data> <data key='r'>1.</data> </node>
<node id='19'> <data key='idx'>8</data> <data key='r'>1.</data> </node>
<node id='20'> <data key='idx'>8</data> <data key='r'>1.</data> </node>
<node id='21'> <data key='idx'>8</data> <data key='r'>1.</data> </node>
<node id='22'> <data key='idx'>8</data> <data key='r'>1.</data> </node>
<node id='23'> <data key='idx'>8</data> <data key='r'>1.</data> </node>
<node id='24'> <data key='idx'>8</data> <data key='r'>1.</data> </node>
<node id='25'> <data key='idx'>8</data> <data key='r'>1.</data> </node>
<node id='26'> <data key='idx'>8</data> <data key='r'>1.</data> </node>
<edge id='e01' target='02' source='01'> <data key='idx'>2</data> </edge>
<edge id='e02' target='03' source='01'> <data key='idx'>2</data> </edge>
<edge id='e03' target='04' source='01'> <data key='idx'>2</data> </edge>
<edge id='e04' target='05' source='02'> <data key='idx'>2</data> </edge>
<edge id='e05' target='06' source='02'> <data key='idx'>2</data> </edge>
<edge id='e06' target='07' source='02'> <data key='idx'>3</data> </edge>
<edge id='e07' target='06' source='03'> <data key='idx'>2</data> </edge>
<edge id='e08' target='08' source='03'> <data key='idx'>2</data> </edge>
<edge id='e09' target='06' source='04'> <data key='idx'>2</data> </edge>
<edge id='e10' target='10' source='04'> <data key='idx'>2</data> </edge>
<edge id='e11' target='11' source='04'> <data key='idx'>2</data> </edge>
<edge id='e12' target='09' source='04'> <data key='idx'>2</data> </edge>
<edge id='e13' target='12' source='04'> <data key='idx'>2</data> </edge>
<edge id='e14' target='13' source='04'> <data key='idx'>3</data> </edge>
<edge id='e15' target='14' source='05'> <data key='idx'>2</data> </edge>
<edge id='e16' target='15' source='05'> <data key='idx'>2</data> </edge>
<edge id='e17' target='14' source='06'> <data key='idx'>2</data> </edge>
<edge id='e18' target='16' source='06'> <data key='idx'>2</data> </edge>
<edge id='e19' target='17' source='06'> <data key='idx'>2</data> </edge>
<edge id='e20' target='18' source='06'> <data key='idx'>2</data> </edge>
<edge id='e21' target='16' source='08'> <data key='idx'>2</data> </edge>
<edge id='e22' target='19' source='08'> <data key='idx'>2</data> </edge>
<edge id='e23' target='18' source='09'> <data key='idx'>2</data> </edge>
<edge id='e24' target='20' source='09'> <data key='idx'>2</data> </edge>
<edge id='e25' target='14' source='10'> <data key='idx'>2</data> </edge>
<edge id='e26' target='16' source='11'> <data key='idx'>2</data> </edge>
<edge id='e27' target='21' source='11'> <data key='idx'>2</data> </edge>
<edge id='e28' target='22' source='11'> <data key='idx'>2</data> </edge>
<edge id='e29' target='23' source='11'> <data key='idx'>2</data> </edge>
<edge id='e30' target='18' source='12'> <data key='idx'>2</data> </edge>
<edge id='e31' target='21' source='12'> <data key='idx'>2</data> </edge>
<edge id='e32' target='24' source='12'> <data key='idx'>2</data> </edge>
<edge id='e33' target='25' source='12'> <data key='idx'>2</data> </edge>
<edge id='e34' target='26' source='12'> <data key='idx'>2</data> </edge>
</graph>
</graphml>
I have anonymous-ed the data to focus on the graph drawing.
I am looking for a graph drawing tool which can layout the nodes on a radial layout, similar to a radial tree but can draw non-straight edges to avoid edge-node crossings. Edge-edge crossing are fine. Ideally however, a viewer can follow each edge from source to target node.
yEd (3.22)
provides a radial layout which can draw edges as arcs or curved to avoid edge-node crossings:

However, the nodes are placed on the same concentric circle based on the shortest distance to the center, measured by number of traversed edges.
But I want to place the nodes based on their subgroup index (to be precise the logarithm of the index). In the above picture the nodes with index 6 are on the same circle as the nodes with index 4 which is not what I want.
NetworkX (2.8.4)
has the shell layout which allows you to assign manually the nodes to the shells
import networkx as nx
import matplotlib.pyplot as plt
from math import log
G = nx.read_graphml("ITC_2_012_idx8.graphml")
indices = set([idx for n, idx in G.nodes.data('index')])
radii = [log(idx)/log(max(indices)) for n, idx in G.nodes.data('index')]
shells = [[n for n, idx in G.nodes.data('index') if idx == x] for x in indices]
pos = nx.shell_layout(G, shells)
plt.box(False) # remove box
nx.draw_networkx(G, pos,
node_color="white",
node_size=500,
edgecolors="black",
labels={n: idx for n, idx in G.nodes.data('index')},
)

However, NetworkX draws only straight edges.
Can GraphViz or another graph drawing tool do what I want?
I have started to create an own layouting and edge routing algorithm which results in following style of drawing:

However, this is unfinished and becomes a never ending story. So I am hoping that I have overlooked a tool which can give automatically the desired radial layout and suitable edge routes.
yEd is the closest tool I have come by (see the first picture of this question).
发布评论
评论(3)
首先,我喜欢您对边缘路由的解决方案,并希望为此看到代码。
其次,以下是我使用NetGraph的尝试,这是我编写(并维护)的网络可视化库。
NetGraph很容易安装(
pip internetgraph
),并且接受graph
来自各种网络分析库(NetworkX,igraph,Graph-tool)的对象,因此不应该有任何摩擦。shell
节点布局使用所谓的中位启发式层中的节点以减少边缘交叉点。弯曲
边缘布局使用Fruchterman-Reingold算法的变体来分发边缘控制点,以便在可能的情况下避免边缘避免节点(彼此)。First of all, I love your solution to the edge routing, and would love to see the code for that.
Secondly, below is my attempt using netgraph, which is a network visualisation library I wrote (and maintain).
Netgraph is easily installable (
pip install netgraph
), and acceptsGraph
objects from various network analysis libraries (networkx, igraph, graph-tool), so there shouldn't be any friction.The
shell
node layout uses the so-called median heuristic to order the nodes within a layer to reduce edge crossings.The
curved
edge layout uses a variant of the Fruchterman-Reingold algorithm to distribute the edge control points such that edges avoid nodes (and each other) -- where possible.NetworkX
shell_layout
用于节点位置&amp; 选择了graphVizneato
用于边路路由neato
之所以选择,因为它尊重graphviz节点属性pos
与pin> pin
。使用
splines edge edge and attribute and attribute
esep
可以避免边缘节点交叉。边缘节点交叉点已经消失。
但是,该解决方案尚未像我想拥有的那样:
我更喜欢入站和出站边缘在相对站点的节点上停靠(根节点除外)。
带有边路路由的YED径向布局可以做到这一点,或者查看我的低分辨率自制布局和路由。
更新:Enforce
tailport
但是,以imho可视化并不清楚(易于掌握连接性),因为某些高度弯曲引入边缘(例如红色),并存在平行边缘重叠(例如蓝色和橙色)。
NetworkX
shell_layout
for node positions & GraphVizneato
for edge routingNeato
is chosen because it respects the graphviz node attributepos
in combination withpin
.With
splines
edge routing and the attributeesep
, edge-node crossings can be avoided.The edge-node crossings are gone.
However, this solution is not yet as I would like to have it:
I would prefer inbound and outbound edges are docked at the nodes on opposite sites (except root node).
yEd radial layout with edge routing does this or see my low-res self-made layout and routes.
Update: Enforce
tailport
However, IMHO the visualisation does not become clearer (easy to grasp the connectivity) since some highly curved edges (e.g. red one) are introduced and there are parallel edge overlaps (e.g. blue and orange).
GraphViz具有两个径向形式的布局引擎:Circo&amp; Twopi。两者都允许使用 len 属性设置所需的边缘长度。
Graphviz has two radial-ish layout engines: circo & twopi. Both allow desired edge length to be set using the len attribute.