我正在努力制作我想要的情节。我用我的模型创建了一个 networkx
图。为了获得节点的分层显示,我使用了 graphviz_layout
。我设法按照自己的意愿对节点进行了颜色编码,但有些事情我无法开始工作:
- 我希望图形是水平的,因此节点 0 是左侧的原点。
- 我想操纵箭头的长度(减少它们)。
- 我想在所有节点之间有箭头,这些节点之间有边,所以在节点 3 和 5、5 和 7、7 和 8 等之间也有箭头(我检查了 G.edges() 并且它们存在,但是不要显示)
这是我的代码...
from networkx.drawing.nx_agraph import write_dot, graphviz_layout
G = model.block_tree.tree
write_dot(G,'test.dot')
pos = graphviz_layout(G, prog='dot', root=0)
plt.title("Some title")
nx.draw_networkx_nodes(G, pos, node_color=color_vector, node_shape='s', node_size=500)
nx.draw_networkx_edges(G, pos)
nx.draw_networkx_labels(G, pos, font_size=10, font_color="white")
plt.show()
如果有人能指出我正确的方向,我将不胜感激。非常感谢!!!
编辑1 多亏了一条评论,我现在在所有正确的节点之间有了箭头。事实证明节点太大并且重叠。现在它看起来像这样: .
我仍然想让它水平并以某种方式缩放箭头长度,如果有人知道的话......
编辑2
我现在设法让它正常工作。我通过图形大小压缩图来减少箭头长度(不是理想的解决方案,但完成了工作......)
在发现 root
和 graphviz_lazout 函数中传递的额外参数之间存在冲突后,我设法进行了水平翻转。我用了this documentation到那里。见下面的代码:
def blocktree_plot(model):
honest_blocks = []
selfish_blocks = []
for block in model.block_tree.tree.nodes():
if model.block_tree[block]["miner_is_selfish"] == True:
selfish_blocks.append(model.block_tree[block]["id"])
else:
honest_blocks.append(model.block_tree[block]["id"])
fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(6, 2), sharex=True, sharey=True)
G = model.block_tree.tree
H = G.reverse(copy=True)
pos = graphviz_layout(H, prog='dot', args='-Grankdir="RL"')
plt.title(r"Blockchain with Selfish Mining ($\alpha$ = {})".format(alpha))
nx.draw_networkx_nodes(H,pos=pos, nodelist=honest_blocks, node_color='green', label="Honest miner", node_shape='s', node_size=200)
nx.draw_networkx_nodes(H,pos=pos, nodelist=selfish_blocks, node_color='red', label="Selfish miner", node_shape='s', node_size=200)
nx.draw_networkx_nodes(H,pos=pos, nodelist=[0], node_color='blue', label="Genesis block", node_shape='s', node_size=200)
nx.draw_networkx_edges(H, pos, arrows=True)
nx.draw_networkx_labels(H, pos, font_size=10, font_color="white")
# plt.legend(labelspacing=0.8, fontsize=9, frameon=False, borderpad=0.1)
plt.show()
最佳答案
我不知道是否可以轻松缩放边长,所以我没有回答这部分,希望其他人有建议。
如果您基本上只想旋转图形,可以执行以下操作:
tmppos = graphviz_layout(G, prog='dot', root=0)
pos = {node: (-y, x) for node, x,y in tmppos.items()}
应该取原来的 x 和 y 坐标并翻转它们(并使原来的向下方向变成新的水平向右移动)。
关于python - 水平绘制具有层次结构的 networkx 图并操纵箭头的长度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65124349/