- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想创建一个多层图(如附图所示),通过使用 networkx
连接用以下代码编写的两个图
#Graph1
g1 = nx.read_edgelist('sample.txt', nodetype=str)
pos = nx.shell_layout(g)
plt.figure(figsize=(10, 10))
nx.draw_networkx_edges(g, pos, edge_color='khaki', alpha=1)
nx.draw_networkx_nodes(g,pos,node_color='r',alpha=0.5,node_size=1000)
nx.draw_networkx_labels(g, pos, font_size=10,font_family='IPAexGothic')
plt.axis('off')
#Graph2
g2 = nx.read_edgelist('sample2.txt', nodetype=str)
pos = nx.shell_layout(g)
plt.figure(figsize=(10, 10))
nx.draw_networkx_edges(g, pos, edge_color='khaki', alpha=1)
nx.draw_networkx_nodes(g,pos,node_color='r',alpha=0.5,node_size=1000)
nx.draw_networkx_labels(g, pos, font_size=10,font_family='IPAexGothic')
plt.axis('off')
最佳答案
networkx
内没有任何功能目前支持分层布局,更不用说如图所示的可视化。所以我们需要自己滚动。
以下实现 LayeredNetworkGraph
假设您有一个图表列表 [g1, g2, ..., gn]
代表不同的层。在一个层内,相应的(子)图定义了连通性。层与层之间,如果后续层中的节点具有相同的节点ID,则它们是连接的。
由于没有布局函数 (AFAIK) 可以在三个维度上计算节点位置,并对层内的节点施加平面性约束,因此我们使用了一个小技巧:我们创建一个跨所有层的图形组合,计算二维位置,然后将这些位置应用到所有层中的节点。可以使用平面性约束计算真正的力导向布局,但这需要大量工作,而且由于您的示例仅使用了 shell 布局(不会受到影响),因此我没有打扰。在许多情况下,差异很小。
如果您想更改可视化的各个方面(大小、宽度、颜色),请查看 draw
方法。您可能需要的大多数更改都可以在那里进行。
#!/usr/bin/env python
"""
Plot multi-graphs in 3D.
"""
import numpy as np
import matplotlib.pyplot as plt
import networkx as nx
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Line3DCollection
class LayeredNetworkGraph(object):
def __init__(self, graphs, node_labels=None, layout=nx.spring_layout, ax=None):
"""Given an ordered list of graphs [g1, g2, ..., gn] that represent
different layers in a multi-layer network, plot the network in
3D with the different layers separated along the z-axis.
Within a layer, the corresponding graph defines the connectivity.
Between layers, nodes in subsequent layers are connected if
they have the same node ID.
Arguments:
----------
graphs : list of networkx.Graph objects
List of graphs, one for each layer.
node_labels : dict node ID : str label or None (default None)
Dictionary mapping nodes to labels.
If None is provided, nodes are not labelled.
layout_func : function handle (default networkx.spring_layout)
Function used to compute the layout.
ax : mpl_toolkits.mplot3d.Axes3d instance or None (default None)
The axis to plot to. If None is given, a new figure and a new axis are created.
"""
# book-keeping
self.graphs = graphs
self.total_layers = len(graphs)
self.node_labels = node_labels
self.layout = layout
if ax:
self.ax = ax
else:
fig = plt.figure()
self.ax = fig.add_subplot(111, projection='3d')
# create internal representation of nodes and edges
self.get_nodes()
self.get_edges_within_layers()
self.get_edges_between_layers()
# compute layout and plot
self.get_node_positions()
self.draw()
def get_nodes(self):
"""Construct an internal representation of nodes with the format (node ID, layer)."""
self.nodes = []
for z, g in enumerate(self.graphs):
self.nodes.extend([(node, z) for node in g.nodes()])
def get_edges_within_layers(self):
"""Remap edges in the individual layers to the internal representations of the node IDs."""
self.edges_within_layers = []
for z, g in enumerate(self.graphs):
self.edges_within_layers.extend([((source, z), (target, z)) for source, target in g.edges()])
def get_edges_between_layers(self):
"""Determine edges between layers. Nodes in subsequent layers are
thought to be connected if they have the same ID."""
self.edges_between_layers = []
for z1, g in enumerate(self.graphs[:-1]):
z2 = z1 + 1
h = self.graphs[z2]
shared_nodes = set(g.nodes()) & set(h.nodes())
self.edges_between_layers.extend([((node, z1), (node, z2)) for node in shared_nodes])
def get_node_positions(self, *args, **kwargs):
"""Get the node positions in the layered layout."""
# What we would like to do, is apply the layout function to a combined, layered network.
# However, networkx layout functions are not implemented for the multi-dimensional case.
# Futhermore, even if there was such a layout function, there probably would be no straightforward way to
# specify the planarity requirement for nodes within a layer.
# Therefor, we compute the layout for the full network in 2D, and then apply the
# positions to the nodes in all planes.
# For a force-directed layout, this will approximately do the right thing.
# TODO: implement FR in 3D with layer constraints.
composition = self.graphs[0]
for h in self.graphs[1:]:
composition = nx.compose(composition, h)
pos = self.layout(composition, *args, **kwargs)
self.node_positions = dict()
for z, g in enumerate(self.graphs):
self.node_positions.update({(node, z) : (*pos[node], z) for node in g.nodes()})
def draw_nodes(self, nodes, *args, **kwargs):
x, y, z = zip(*[self.node_positions[node] for node in nodes])
self.ax.scatter(x, y, z, *args, **kwargs)
def draw_edges(self, edges, *args, **kwargs):
segments = [(self.node_positions[source], self.node_positions[target]) for source, target in edges]
line_collection = Line3DCollection(segments, *args, **kwargs)
self.ax.add_collection3d(line_collection)
def get_extent(self, pad=0.1):
xyz = np.array(list(self.node_positions.values()))
xmin, ymin, _ = np.min(xyz, axis=0)
xmax, ymax, _ = np.max(xyz, axis=0)
dx = xmax - xmin
dy = ymax - ymin
return (xmin - pad * dx, xmax + pad * dx), \
(ymin - pad * dy, ymax + pad * dy)
def draw_plane(self, z, *args, **kwargs):
(xmin, xmax), (ymin, ymax) = self.get_extent(pad=0.1)
u = np.linspace(xmin, xmax, 10)
v = np.linspace(ymin, ymax, 10)
U, V = np.meshgrid(u ,v)
W = z * np.ones_like(U)
self.ax.plot_surface(U, V, W, *args, **kwargs)
def draw_node_labels(self, node_labels, *args, **kwargs):
for node, z in self.nodes:
if node in node_labels:
ax.text(*self.node_positions[(node, z)], node_labels[node], *args, **kwargs)
def draw(self):
self.draw_edges(self.edges_within_layers, color='k', alpha=0.3, linestyle='-', zorder=2)
self.draw_edges(self.edges_between_layers, color='k', alpha=0.3, linestyle='--', zorder=2)
for z in range(self.total_layers):
self.draw_plane(z, alpha=0.2, zorder=1)
self.draw_nodes([node for node in self.nodes if node[1]==z], s=300, zorder=3)
if self.node_labels:
self.draw_node_labels(self.node_labels,
horizontalalignment='center',
verticalalignment='center',
zorder=100)
if __name__ == '__main__':
# define graphs
n = 5
g = nx.erdos_renyi_graph(4*n, p=0.1)
h = nx.erdos_renyi_graph(3*n, p=0.2)
i = nx.erdos_renyi_graph(2*n, p=0.4)
node_labels = {nn : str(nn) for nn in range(4*n)}
# initialise figure and plot
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
LayeredNetworkGraph([g, h, i], node_labels=node_labels, ax=ax, layout=nx.spring_layout)
ax.set_axis_off()
plt.show()
关于python - networkx 中的多层图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60392940/
我正在尝试对网络上的投票动态进行建模,并希望能够在 NetworkX 中创建一个图表,在其中我可以在节点上迭代投票过程,让它们的颜色变化对应于它们的投票“标签”。 我已设法获得此代码以查看每个节点的属
我无法计算简单 NetworkX 加权图的中心性。 这是正常的还是我做错了什么? 我使用简单的 add_edge(c[0],c[1],weight = my_values) 添加边,其中c[0],c[
我想在函数调用 d(n) 之前比较 networkx.Graph 对象 n 的状态(有副作用)之后与国家合作。 有一些可变的对象节点属性,例如 n.node[0]['attribute'],我想对其进
我正在使用 NetworkX 生成一些噪声数据的图表。我想通过删除虚假分支来“清理”图表,并希望避免重新发明轮子。 例如,链接的图片显示了一组示例图形,作为由灰线连接的彩色节点。我想修剪白框指示的节点
我目前正在尝试制定一种算法来在图中查找派系,幸运的是我从 Networkx 找到了一个函数的文档,该函数就是这样做的。不幸的是,变量名有点简洁,我很难理解代码的每一部分的作用。 这里是 find_cl
我正在尝试使用 NetworkX 在两个节点之间添加平行边,但由于以下错误而失败。我究竟做错了什么? import networkx as nx import graphviz g1 = nx.Mul
我希望将 Pajek 数据集转换为 networkx Graph()。数据集来自哥斯达黎加Family Ties 。我正在使用非常方便的 networkx.read_pajek(pathname) 函
我在networkx中有一个巨大的图,我想从每个节点获取深度为2的所有子图。有没有一种好的方法可以使用networkx中的内置函数来做到这一点? 最佳答案 正如我在评论中所说,networkx.ego
我希望将 Pajek 数据集转换为 networkx Graph()。数据集来自哥斯达黎加Family Ties 。我正在使用非常方便的 networkx.read_pajek(pathname) 函
我在使用以下代码时遇到问题。边连接节点。但是是否有可能有一个定向网络,如果一个“人”跟随一个“人”,但它只是一种方式,在边缘有箭头或方向。 plt.figure(figsize=(12, 12)) #
我正在 Windows 机器上使用 Python 3,尽管付出了很多努力,但仍未能安装 pygraphviz。单独讨论。 我有networkx和graphviz模块...是否有一个范例可以在netwo
我正在使用《Python 自然语言处理》一书(“www.nltk.org/book”)自学 Python 和 NLTK。 我在 NetworkX 上被困在第 4 章第 4 部分第 8 部分。当我尝试运
下面是我的代码: import networkx as nx for i in range(2): G = nx.DiGraph() if i==0: G.add_ed
我正在使用 deap 符号回归示例问题中的这段代码,图形显示正常,但我希望节点扩展为圆角矩形以适合文本 自动 . (我不想只是通过反复试验来指定节点大小)。我该怎么做? # show tree imp
我正在尝试使用 networkx 读取 gml 文件(很简单吧?),除非我尝试读取文件时出现错误“networkx.exception.NetworkXError: cannot tokenize u
如何按厚度在networkx中绘制N> 1000个节点的加权网络?如果我有一个源、目标节点和每个边的权重的 .csv 列表,我正在考虑使用该方法: for i in range(N) G.add_ed
我希望 networkx 在我的定向中找到绝对最长的路径, 无环图。 我知道 Bellman-Ford,所以我否定了我的图长度。问题: networkx 的 bellman_ford() 需要一个源节
我在图中有一个节点,它充当一种“临时连接器”节点。我想删除该节点并更新图中的边,以便其所有直接前辈都指向其直接后继者。 在 networkx 中是否有内置功能可以做到这一点,还是我需要推出自己的解决方
我有两张彩色图表。我想确定它们是否同构,条件是同构必须保留顶点颜色。 networkx 中是否有算法可以做到这一点? 这些图是无向且简单的。 最佳答案 检查documentation对于is_isom
我有一组起点-终点坐标,我想计算它们之间的最短路径。 我的起点-终点坐标有时位于一条长直线道路的中间。但是,OSMnx/networkx 计算的最短路径不会考虑中间边到最近节点的路径。 OSMnx 或
我是一名优秀的程序员,十分优秀!