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

t8e9dugd  于 2023-03-19  发布在  其他
关注(0)|答案(1)|浏览(206)

bounty将在6天后过期。回答此问题可获得+50的声誉奖励。mrq正在寻找来自声誉良好来源的答案

我需要画一个网络x图,x轴的范围是重复的,如0-100,0- 100,0 -100等。节点沿着这些x轴域分布,不同域之间的节点之间可以有连接的边。为了更容易理解,我分享了下面的图像,这是类似于我希望x轴是,但是使用matplotlib和/或plotly。Plotly更重要。我在dataframe列中用它们对应的域号12或13标记每个节点。

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

其中,边用Node 1-Node 2表示,其余列属于Node 1。最后一行不连接到其他节点。示例代码为

  1. import networkx as nx
  2. import matplotlib.pyplot as plt
  3. fig = plt.figure(figsize=(10,10))
  4. ax = fig.add_subplot(111)
  5. G = nx.DiGraph()
  6. G.add_node(1534,pos=(22803603,20))
  7. G.add_node(945,pos=(32494954,10))
  8. G.add_node(946,pos=(32530403,9))
  9. G.add_edge(1534,945)
  10. G.add_edge(945,946)
  11. pos=nx.get_node_attributes(G,'pos')
  12. nx.draw_networkx(G,pos)
  13. ax.tick_params(left=True, right=True, top=True, bottom=True, labelleft=True, labelbottom=True)

我按照这个例子,只是用上面的G替换了random graph:https://plotly.com/python/network-graphs/#color-node-points
这是一个示例图,我不关心节点的形状或边的曲率,我只关心x轴的格式。

omtl5h9j

omtl5h9j1#

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

  • 定义图形并添加域索引(从0开始)
  1. G = nx.DiGraph()
  2. G.add_node(1534, pos=(22803603, 20), domain=0)
  3. G.add_node(945, pos=(32494954, 10), domain=1)
  4. G.add_node(946, pos=(32530403, 9), domain=1)
  5. G.add_edge(1534, 945)
  6. G.add_edge(945, 946)
  • 定义域的起始X位置
  1. d_starts = [0, 140_000_000]
  • 获取节点相对于域的位置
  1. positions = nx.get_node_attributes(G, "pos")
  2. domains = nx.get_node_attributes(G, "domain")
  3. final_positions = {}
  4. for pos, dom in zip(positions.items(), domains.items()):
  5. label, (x, y) = pos
  6. _, d = dom
  7. final_positions[label] = [x + d_starts[d], y]
  • 最后,用ticklabelsaxvline在一个轴和“伪”2个轴上绘制图形
  1. fig, ax = plt.subplots(figsize=(18,9))
  2. nx.draw_networkx(G, final_positions, ax=ax)
  3. # Works properly if d_starts values are modulo of the tick range step (here 10M)
  4. max_xlim = int(ax.get_xlim()[1])
  5. tick_range = range(0, max_xlim, 10_000_000)
  6. labels = [f"{(i % d_starts[1]) / 1e6 :.0f}M" for i in tick_range]
  7. ax.set_xlim(0, max_xlim)
  8. ax.set_xticks(tick_range, labels , rotation=-45)
  9. ax.tick_params(bottom=True, labelbottom=True)
  10. for ypos in d_starts:
  11. ax.axvline(ypos, c="k")

把所有这些加在一起就是你得到的数字:

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

展开查看全部

相关问题