在networkx中绘制图形时,如何定义输出文件大小(),以及如何在节点之间显示周期(),我遇到了困难。
问题定义
我有一个节点列表,其中**可能**或**可能没有**,它们之间有循环。正如您在下面我提供的代码中所看到的,我使用两种颜色来区分两种不同的边缘(边缘的颜色决定了这种差异)。
现状
到目前为止,我还无法在边缘上显示不同的颜色(根据添加边缘时可以定义的文档颜色),也无法避免边缘重叠(当两个节点复合在一个周期中,一个边与另一个边重叠,因此只有一个是可见的)。
我还无法在绘图时设置图形的大小(或保存matplotlib的绘图匠)。我看到了一些关于输出大小的问题,但到目前为止,没有一个问题对我有用(代码中有一些例子,但我尝试了其他一些例子)。
def plot(self):
"""
plot graph
"""
nx.draw(self.G, with_labels = True)
#nx.draw_kamada_kawai(self.G, with_labels = True)
#plt.figure(1, figsize=(200, 80), dpi=60, font_weight='normal')
#plt.figure(figsize=(280,80))
plt.savefig("filename.png")
电流输出
期望输出
我需要相同的输出,但使用**弧边**,用**提供的颜色**绘制,这样它们就不会互相重叠**。我还需要最终的输出大小来适应图形的大小。正如您在图像中所看到的,**节点的名称是截止的,并且图形是明显的裁剪**。如果你试图改变number_of_nodes的值,你会发现一切都是截止的.请记住,这些图可以有25到100个节点,它们之间有多个边(包括循环)。
到目前为止我的代码
from tkinter.ttk import Notebook
import networkx as nx
import matplotlib.pyplot as plt
class Graph:
"""
create and visualize a graph using networkx
"""
def __init__(self):
"""
basic constructor
"""
self.G = nx.MultiDiGraph()
def addNodes(self,nodes, options = {'color' : 'blue'}):
"""
add nodes to the graph
"""
#asserts
assert(self.G is None, 'graph not created')
assert(options is None, 'options parameter is none type')
assert(not isinstance(nodes, list), 'nodes parameter must be a list')
#add nodes with options
for n in nodes:
opt = options
opt['label'] = n
self.G.add_nodes_from(
[(n, opt)]
)
def addEdges(self, edges, options = {'color' : 'green'}):
"""
add edges to the graph
"""
#asserts
assert(self.G is None, 'graph not created')
assert(options is None, 'options parameter is none type')
assert(not isinstance(edges, list), 'edges parameter must be a list')
#add edges with options
for n in edges:
opt = options
opt['label'] = n
self.G.add_edges_from(
[n + (options,)]
)
print([n + (options,)])
#self.G.add_edges_from(edges, options)
def removeNodes(self, nodes):
"""
remove nodes from graph
"""
assert(self.G is None, 'graph not created')
assert(not isinstance(nodes, list), 'nodes parameter must be a list')
self.G.remove_nodes_from(nodes)
def removeEdges(self,edges):
"""
remove edges from graph
"""
assert(self.G is None, 'graph not created')
assert(not isinstance(edges, list), 'edges parameter must be a list')
self.G.remove_edges_from(edges)
def plot(self):
"""
plot graph
"""
nx.draw(self.G, with_labels = True)
#nx.draw_kamada_kawai(self.G, with_labels = True)
#plt.figure(1, figsize=(200, 80), dpi=60, font_weight='normal')
#plt.figure(figsize=(280,80))
plt.savefig("filename.png")
def save_graph(self, filename):
"""
save graph to file
"""
pass
class CubeGraph(Graph):
"""
this class handles graphs for cubes
"""
def __init__(self, nodes, green_edges, red_edges):
"""
constructor for cube graph
"""
#asserts
assert(not isinstance(nodes, list), 'nodes parameter must be a list')
assert(not isinstance(green_edges, list), 'green_edges parameter must be a list')
assert(not isinstance(red_edges, list), 'red_edges parameter must be a list')
#assign variables
self._nodes = nodes
self._greenEdges = green_edges
self._redEdges = red_edges
#init parent object
super().__init__()
def createAll(self):
"""
create the graph with all the nodes and edges
"""
self.addNodes(self._nodes)
self.addEdges(self._greenEdges, {'color' : 'green'})
self.addEdges(self._redEdges, {'color' : 'red'})
def create(self, node):
"""
create a graph only with related node
"""
assert(node in self._nodes, 'node parameter is not nodes list provided at initialization')
#clean the graph
self.removeEdges(self._redEdges)
self.removeEdges(self._greenEdges)
self.removeNodes(self._nodes)
#make sure node is lower case
node = node.lower()
#filter only those edges matching the node
green_filtered = list(filter(lambda x : x[0] == node, self._greenEdges))
red_filtered = list(filter(lambda x : x[1] == node, self._redEdges))
#add nodes and edges to graph
self.addNodes(node)
self.addEdges(green_filtered, {'color' : 'green'})
self.addEdges(red_filtered, {'color' : 'red'})
number_of_nodes = 6
nodes = ['0000 very long and unique string number {}'.format(i) for i in range(0,number_of_nodes)]
green = []
red = []
green.append(('0000 very long and unique string number 0', '0000 very long and unique string number 1'))
red.append(('0000 very long and unique string number 1', '0000 very long and unique string number 0'))
green.append(('0000 very long and unique string number 2', '0000 very long and unique string number 3'))
red.append(('0000 very long and unique string number 3', '0000 very long and unique string number 2'))
green.append(('0000 very long and unique string number 4', '0000 very long and unique string number 5'))
red.append(('0000 very long and unique string number 5', '0000 very long and unique string number 4'))
net = CubeGraph(nodes, green, red)
net.createAll()
net.plot()
print('')
发布于 2022-02-23 02:55:16
在对边缘的形成进行了大量的猜测之后,我得到了我所需要的东西。毕竟,nx的绘制函数不是我所需要的抽签选项,因为为了实现我想要的结果,我需要创建一个布局,以便计算节点的位置。之后,函数draw_networkx_nodes和draw_networkx_edges提供了我正在寻找的实用程序。该函数如下所示:
def plot(self):
"""
plot graph
"""
fig = plt.figure(1, figsize=(self.IMAGE_WIDTH, self.IMAGE_HEIGHT), dpi=60)
# Compute position of nodes
pos = nx.kamada_kawai_layout(self.G)
# Draw nodes and edges
nx.draw_networkx_nodes(self.G, pos, labels = list(self.G.nodes))
nx.draw_networkx_labels(self.G, pos, {n: n for n in list(self.G.nodes)}, font_size=10)
nx.draw_networkx_edges(
self.G, pos,
connectionstyle="arc3,rad=0.1"
,edge_color = self.edgesColor
,arrowsize=20
)
#nx.draw_networkx_edge_labels(self.G, pos, {n: n for n in list(self.G.edges)}, font_size=6)
plt.show()
https://stackoverflow.com/questions/71197281
复制相似问题