在 matplotlib、plotly 和 networkx 中绘制重复的 x 轴范围

问题描述 投票:0回答:1

我需要绘制一个x轴范围重复的networkx图,例如0-100、0-100、0-100等。节点沿着这些x轴域分布,不同域之间可以有连接节点的边。为了更容易理解,我在下面分享了一张与我希望的 x 轴相似的图片,但使用了 matplotlib 和/或 plotly。情节更重要。我在数据框列中用相应的域编号 12 或 13 标记每个节点。一个例子是

Node 1 | Node 2 | y axis | x1 | domain
1534   945             20    22803603   13
945    946             10    32494954   12
946    -               9     32530403   12

其中边用 Node1-Node2 表示,其余列属于 Node1。最后一行不连接到另一个节点。示例代码是

import networkx as nx
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(10,10))
ax = fig.add_subplot(111)

G = nx.DiGraph()
G.add_node(1534,pos=(22803603,20))
G.add_node(945,pos=(32494954,10))
G.add_node(946,pos=(32530403,9))
G.add_edge(1534,945)
G.add_edge(945,946)

pos=nx.get_node_attributes(G,'pos')

nx.draw_networkx(G,pos)
ax.tick_params(left=True, right=True, top=True, bottom=True, labelleft=True, labelbottom=True)

在情节上,我按照这里的例子只是用上面的 G 替换随机图:https://plotly.com/python/network-graphs/#color-node-points

这是示例图。我不关心节点的形状或边缘的曲率。我只关心 x 轴格式。

python matplotlib plotly networkx x-axis
1个回答
0
投票

我想你可以用下面的方法达到你想要的效果。它需要知道第二个(或更多)域何时开始。

  • 定义图表并添加域索引(从 0 开始)
G = nx.DiGraph()
G.add_node(1534, pos=(22803603, 20), domain=0)
G.add_node(945, pos=(32494954, 10), domain=1)
G.add_node(946, pos=(32530403, 9), domain=1)
G.add_edge(1534, 945)
G.add_edge(945, 946)
  • 定义从 X 位置开始的域
d_starts = [0, 140_000_000]
  • 获取节点相对于域的位置
positions = nx.get_node_attributes(G, "pos")
domains = nx.get_node_attributes(G, "domain")

final_positions = {}

for pos, dom in zip(positions.items(), domains.items()):
    label, (x, y) = pos
    _, d = dom
    final_positions[label] = [x + d_starts[d], y]
  • 最后,用
    ticklabels
    axvline
  • 在一个轴和“假”2轴上绘制图形
fig, ax = plt.subplots(figsize=(18,9))
nx.draw_networkx(G, final_positions, ax=ax)

# Works properly if d_starts values are modulo of the tick range step (here 10M)
max_xlim = int(ax.get_xlim()[1])
tick_range = range(0, max_xlim, 10_000_000)
labels = [f"{(i % d_starts[1]) / 1e6  :.0f}M" for i in tick_range]

ax.set_xlim(0, max_xlim)
ax.set_xticks(tick_range, labels , rotation=-45)
ax.tick_params(bottom=True, labelbottom=True)

for ypos in d_starts:
    ax.axvline(ypos, c="k")

将所有这些放在一起就是您获得的数字:

注意:如果需要,您可以轻松添加更多域。
对于您的标题,您需要域索引和域名之间的映射。

© www.soinside.com 2019 - 2024. All rights reserved.