networkx 边缘权重未正确映射到箭头宽度?
networkx edge weights not mapping to arrow width properly?
我正在尝试使用以下代码绘制图形:
import networkx as nx
import matplotlib.pyplot as plt
u = ['SAC', 'SAC', 'SAC', 'SAC', 'SAC', 'SAC', 'SAC', 'REDES SOCIAIS', 'REDES SOCIAIS',
'REDES SOCIAIS', 'PROCON', 'PROCON', 'PROCON', 'BACEN', 'BACEN', 'BACEN', 'BACEN',
'OUVIDORIA', 'OUVIDORIA', 'OUVIDORIA', 'OUVIDORIA', 'OUVIDORIA', 'CHAT', 'CHAT',
'CHAT']
v = ['RECLAME AQUI', 'SAC', 'REDES SOCIAIS', 'PROCON', 'BACEN', 'OUVIDORIA', 'CHAT',
'RECLAME AQUI', 'SAC', 'REDES SOCIAIS', 'RECLAME AQUI', 'SAC', 'PROCON',
'RECLAME AQUI', 'SAC', 'BACEN', 'OUVIDORIA', 'RECLAME AQUI', 'SAC',
'REDES SOCIAIS', 'BACEN', 'OUVIDORIA', 'RECLAME AQUI', 'SAC', 'REDES SOCIAIS']
w = [437, 207, 13, 1, 7, 13, 2, 70, 10, 12, 5,
1, 2, 23, 1, 4, 2, 16, 2, 2, 2, 4, 4, 1, 1]
G = nx.DiGraph()
for ui, vi, wi in zip(u, v, w):
G.add_edges_from([(ui, vi)], weight=wi)
pos = nx.circular_layout(G)
edge_labels = dict([((u, v,), d['weight']) for u, v, d in G.edges(data=True)])
weights = [G[u][v]['weight'] for u, v in G.edges()]
weights = list(map(lambda x: (x - min(weights)) /
(max(weights) - min(weights)), weights))
weights = list(map(lambda x: (x * 4) + 1, weights))
i = 0
for u, v in G.edges():
print(u, v, G[u][v]['weight'], weights[i])
i += 1
fig = plt.figure(figsize=(25, 15))
plt.axis('off')
nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels)
nx.draw_networkx_nodes(G, pos,
nodelist=G.nodes(),
node_color='r',
node_size=500)
nx.draw_networkx_edges(G, pos,
edgelist=G.edges(),
alpha=0.5, edge_color='#5cce40', width=weights)
nx.draw_networkx_labels(G, pos, font_size=16, font_color='white')
fig.set_facecolor("#262626")
plt.show()
它从 pandas 数据框创建了一个边字典,但重要的部分在我声明 G = nx.DiGraph()
时开始。在这一点上,我拥有所有加权边,并在 [1, 5] 之间对它们进行归一化。
打印语句给了我这个:
SAC RECLAME AQUI 437 5.0
SAC SAC 207 2.8899082568807337
SAC REDES SOCIAIS 13 1.110091743119266
SAC PROCON 1 1.0
SAC BACEN 7 1.0550458715596331
SAC OUVIDORIA 13 1.110091743119266
SAC CHAT 2 1.0091743119266054
REDES SOCIAIS RECLAME AQUI 70 1.6330275229357798
REDES SOCIAIS SAC 10 1.0825688073394495
REDES SOCIAIS REDES SOCIAIS 12 1.1009174311926606
PROCON RECLAME AQUI 5 1.036697247706422
PROCON SAC 1 1.0
PROCON PROCON 2 1.0091743119266054
BACEN RECLAME AQUI 23 1.2018348623853212
BACEN SAC 1 1.0
BACEN BACEN 4 1.0275229357798166
BACEN OUVIDORIA 2 1.0091743119266054
OUVIDORIA RECLAME AQUI 16 1.1376146788990826
OUVIDORIA SAC 2 1.0091743119266054
OUVIDORIA REDES SOCIAIS 2 1.0091743119266054
OUVIDORIA BACEN 2 1.0091743119266054
OUVIDORIA OUVIDORIA 4 1.0275229357798166
CHAT RECLAME AQUI 4 1.0275229357798166
CHAT SAC 1 1.0
CHAT REDES SOCIAIS 1 1.0
即
- SAC -> RECLAME AQUI 可能的最高权重为 5.0
- 下面的高权重边(不是自循环,我没找到怎么画)是 REDES SOCIAIS -> RECLAME AQUI with 1.6330275229357798.
不过,这是我的剧情:
可以看出,第二大宽度的边是SAC -> REDES SOCIAIS
,而REDES SOCIAIS -> RECLAME AQUI
,原始权重为70,比第一个更薄。我不明白为什么。打印显示我的映射是正确的。我是否将错误的参数传递给了某些函数?
nx.draw_networkx_edges
does not draw arrows for self-loops。
所以当有向图包含自环时,传递给 nx.draw_networkx_edges
的权重必须跳过自环权重。否则,权重将与绘制的边不同步。
因此,如果您更改
weights = [G[u][v]['weight'] for u, v in G.edges()]
至
weights = [G[u][v]['weight'] for u, v in G.edges() if u != v]
然后
import networkx as nx
import matplotlib.pyplot as plt
u = ['SAC', 'SAC', 'SAC', 'SAC', 'SAC', 'SAC', 'SAC', 'REDES SOCIAIS', 'REDES SOCIAIS',
'REDES SOCIAIS', 'PROCON', 'PROCON', 'PROCON', 'BACEN', 'BACEN', 'BACEN', 'BACEN',
'OUVIDORIA', 'OUVIDORIA', 'OUVIDORIA', 'OUVIDORIA', 'OUVIDORIA', 'CHAT', 'CHAT',
'CHAT']
v = ['RECLAME AQUI', 'SAC', 'REDES SOCIAIS', 'PROCON', 'BACEN', 'OUVIDORIA', 'CHAT',
'RECLAME AQUI', 'SAC', 'REDES SOCIAIS', 'RECLAME AQUI', 'SAC', 'PROCON',
'RECLAME AQUI', 'SAC', 'BACEN', 'OUVIDORIA', 'RECLAME AQUI', 'SAC',
'REDES SOCIAIS', 'BACEN', 'OUVIDORIA', 'RECLAME AQUI', 'SAC', 'REDES SOCIAIS']
w = [437, 207, 13, 1, 7, 13, 2, 70, 10, 12, 5,
1, 2, 23, 1, 4, 2, 16, 2, 2, 2, 4, 4, 1, 1]
G = nx.DiGraph()
for ui, vi, wi in zip(u, v, w):
G.add_edges_from([(ui, vi)], weight=wi)
pos = nx.circular_layout(G)
edge_labels = dict([((u, v,), d['weight']) for u, v, d in G.edges(data=True)])
weights = [G[u][v]['weight'] for u, v in G.edges() if u != v]
weights = list(map(lambda x: (x - min(weights)) /
(max(weights) - min(weights)), weights))
weights = list(map(lambda x: (x * 4) + 1, weights))
i = 0
for u, v in G.edges():
if u != v:
print(u, v, G[u][v]['weight'], weights[i])
i += 1
fig = plt.figure(figsize=(25, 15))
plt.axis('off')
nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels)
nx.draw_networkx_nodes(G, pos,
nodelist=G.nodes(),
node_color='r',
node_size=500)
nx.draw_networkx_edges(G, pos,
edgelist=G.edges(),
alpha=0.5, edge_color='#5cce40', width=weights)
nx.draw_networkx_labels(G, pos, font_size=16, font_color='white')
fig.set_facecolor("#262626")
plt.show()
产量
有向图中箭头的形状和粗细目前由 this code 设置。要用尖箭头替换矩形 "arrows" 需要用自定义 draw_networkx_edges_with_arrows
函数替换 nx.draw_networkx_edges
:
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
def draw_networkx_edges_with_arrows(G, pos,
edgelist=None,
width=1.0,
edge_color='k',
style='solid',
alpha=1.0,
edge_cmap=None,
edge_vmin=None,
edge_vmax=None,
ax=None,
arrows=True,
label=None,
arrow_width=1.0,
**kwds):
"""
Most of this code comes from https://github.com/networkx/networkx/blob/master/networkx/drawing/nx_pylab.py#L575, except that the arrow LineCollection
has been replaced by mpatches.Arrows below.
"""
try:
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.cbook as cb
from matplotlib.colors import colorConverter, Colormap
from matplotlib.collections import LineCollection
import matplotlib.patches as mpatches
import numpy
import itertools as IT
except ImportError:
raise ImportError("Matplotlib required for draw()")
except RuntimeError:
print("Matplotlib unable to open display")
raise
if ax is None:
ax = plt.gca()
if edgelist is None:
edgelist = G.edges()
if not edgelist or len(edgelist) == 0: # no edges!
return None
# set edge positions
edge_pos = numpy.asarray([(pos[e[0]], pos[e[1]]) for e in edgelist])
if not cb.iterable(width):
lw = (width,)
else:
lw = width
if not cb.is_string_like(edge_color) \
and cb.iterable(edge_color) \
and len(edge_color) == len(edge_pos):
if numpy.alltrue([cb.is_string_like(c)
for c in edge_color]):
# (should check ALL elements)
# list of color letters such as ['k','r','k',...]
edge_colors = tuple([colorConverter.to_rgba(c, alpha)
for c in edge_color])
elif numpy.alltrue([not cb.is_string_like(c)
for c in edge_color]):
# If color specs are given as (rgb) or (rgba) tuples, we're OK
if numpy.alltrue([cb.iterable(c) and len(c) in (3, 4)
for c in edge_color]):
edge_colors = tuple(edge_color)
else:
# numbers (which are going to be mapped with a colormap)
edge_colors = None
else:
raise ValueError('edge_color must consist of either color names or numbers')
else:
if cb.is_string_like(edge_color) or len(edge_color) == 1:
edge_colors = (colorConverter.to_rgba(edge_color, alpha), )
else:
raise ValueError('edge_color must be a single color or list of exactly m colors where m is the number or edges')
edge_collection = LineCollection(edge_pos,
colors=edge_colors,
linewidths=lw,
antialiaseds=(1,),
linestyle=style,
transOffset = ax.transData,
)
edge_collection.set_zorder(1) # edges go behind nodes
edge_collection.set_label(label)
ax.add_collection(edge_collection)
# Note: there was a bug in mpl regarding the handling of alpha values for
# each line in a LineCollection. It was fixed in matplotlib in r7184 and
# r7189 (June 6 2009). We should then not set the alpha value globally,
# since the user can instead provide per-edge alphas now. Only set it
# globally if provided as a scalar.
if cb.is_numlike(alpha):
edge_collection.set_alpha(alpha)
if edge_colors is None:
if edge_cmap is not None:
assert(isinstance(edge_cmap, Colormap))
edge_collection.set_array(numpy.asarray(edge_color))
edge_collection.set_cmap(edge_cmap)
if edge_vmin is not None or edge_vmax is not None:
edge_collection.set_clim(edge_vmin, edge_vmax)
else:
edge_collection.autoscale()
arrow_collection = None
if G.is_directed() and arrows:
# a directed graph hack
# draw thick line segments at head end of edge
# waiting for someone else to implement arrows that will work
arrow_colors = edge_colors
# a_pos = []
p = 1.0-0.25 # make head segment 25 percent of edge length
for (src, dst), lwi, color in zip(edge_pos, lw, IT.cycle(arrow_colors)):
x1, y1 = src
x2, y2 = dst
dx = x2-x1 # x offset
dy = y2-y1 # y offset
d = numpy.sqrt(float(dx**2 + dy**2)) # length of edge
if d == 0: # source and target at same position
continue
if dx == 0: # vertical edge
xa = x2
ya = dy*p+y1
if dy == 0: # horizontal edge
ya = y2
xa = dx*p+x1
else:
theta = numpy.arctan2(dy, dx)
xa = p*d*numpy.cos(theta)+x1
ya = p*d*numpy.sin(theta)+y1
dx, dy = x2-xa, y2-ya
patch = mpatches.Arrow(xa, ya, dx, dy,
width=arrow_width,
color=color,
transform=ax.transData)
ax.add_patch(patch)
# update view
minx = numpy.amin(numpy.ravel(edge_pos[:, :, 0]))
maxx = numpy.amax(numpy.ravel(edge_pos[:, :, 0]))
miny = numpy.amin(numpy.ravel(edge_pos[:, :, 1]))
maxy = numpy.amax(numpy.ravel(edge_pos[:, :, 1]))
w = maxx-minx
h = maxy-miny
padx, pady = 0.05*w, 0.05*h
corners = (minx-padx, miny-pady), (maxx+padx, maxy+pady)
ax.update_datalim(corners)
ax.autoscale_view()
return edge_collection
u = ['SAC', 'SAC', 'SAC', 'SAC', 'SAC', 'SAC', 'SAC', 'REDES SOCIAIS', 'REDES SOCIAIS',
'REDES SOCIAIS', 'PROCON', 'PROCON', 'PROCON', 'BACEN', 'BACEN', 'BACEN', 'BACEN',
'OUVIDORIA', 'OUVIDORIA', 'OUVIDORIA', 'OUVIDORIA', 'OUVIDORIA', 'CHAT', 'CHAT',
'CHAT']
v = ['RECLAME AQUI', 'SAC', 'REDES SOCIAIS', 'PROCON', 'BACEN', 'OUVIDORIA', 'CHAT',
'RECLAME AQUI', 'SAC', 'REDES SOCIAIS', 'RECLAME AQUI', 'SAC', 'PROCON',
'RECLAME AQUI', 'SAC', 'BACEN', 'OUVIDORIA', 'RECLAME AQUI', 'SAC',
'REDES SOCIAIS', 'BACEN', 'OUVIDORIA', 'RECLAME AQUI', 'SAC', 'REDES SOCIAIS']
w = [437, 207, 13, 1, 7, 13, 2, 70, 10, 12, 5,
1, 2, 23, 1, 4, 2, 16, 2, 2, 2, 4, 4, 1, 1]
G = nx.DiGraph()
for ui, vi, wi in zip(u, v, w):
G.add_edges_from([(ui, vi)], weight=wi)
pos = nx.circular_layout(G)
edge_labels = dict([((u, v,), d['weight']) for u, v, d in G.edges(data=True)])
weights = [G[u][v]['weight'] for u, v in G.edges()]
weights = np.log(weights)
weights = list(map(lambda x: (x - min(weights)) /
(max(weights) - min(weights)), weights))
weights = list(map(lambda x: (x * 10) + 1, weights))
fig = plt.figure(figsize=(25, 15))
plt.axis('off')
nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels)
nx.draw_networkx_nodes(G, pos,
nodelist=G.nodes(),
node_color='r',
node_size=500)
draw_networkx_edges_with_arrows(G, pos,
width=weights, arrow_width=0.05,
alpha=0.5, edge_color='#5cce40')
nx.draw_networkx_labels(G, pos, font_size=16, font_color='white')
fig.set_facecolor("#262626")
plt.savefig('/tmp/out.pdf', format='pdf', facecolor=fig.get_facecolor(),
bbox_inches='tight')
产量
我正在尝试使用以下代码绘制图形:
import networkx as nx
import matplotlib.pyplot as plt
u = ['SAC', 'SAC', 'SAC', 'SAC', 'SAC', 'SAC', 'SAC', 'REDES SOCIAIS', 'REDES SOCIAIS',
'REDES SOCIAIS', 'PROCON', 'PROCON', 'PROCON', 'BACEN', 'BACEN', 'BACEN', 'BACEN',
'OUVIDORIA', 'OUVIDORIA', 'OUVIDORIA', 'OUVIDORIA', 'OUVIDORIA', 'CHAT', 'CHAT',
'CHAT']
v = ['RECLAME AQUI', 'SAC', 'REDES SOCIAIS', 'PROCON', 'BACEN', 'OUVIDORIA', 'CHAT',
'RECLAME AQUI', 'SAC', 'REDES SOCIAIS', 'RECLAME AQUI', 'SAC', 'PROCON',
'RECLAME AQUI', 'SAC', 'BACEN', 'OUVIDORIA', 'RECLAME AQUI', 'SAC',
'REDES SOCIAIS', 'BACEN', 'OUVIDORIA', 'RECLAME AQUI', 'SAC', 'REDES SOCIAIS']
w = [437, 207, 13, 1, 7, 13, 2, 70, 10, 12, 5,
1, 2, 23, 1, 4, 2, 16, 2, 2, 2, 4, 4, 1, 1]
G = nx.DiGraph()
for ui, vi, wi in zip(u, v, w):
G.add_edges_from([(ui, vi)], weight=wi)
pos = nx.circular_layout(G)
edge_labels = dict([((u, v,), d['weight']) for u, v, d in G.edges(data=True)])
weights = [G[u][v]['weight'] for u, v in G.edges()]
weights = list(map(lambda x: (x - min(weights)) /
(max(weights) - min(weights)), weights))
weights = list(map(lambda x: (x * 4) + 1, weights))
i = 0
for u, v in G.edges():
print(u, v, G[u][v]['weight'], weights[i])
i += 1
fig = plt.figure(figsize=(25, 15))
plt.axis('off')
nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels)
nx.draw_networkx_nodes(G, pos,
nodelist=G.nodes(),
node_color='r',
node_size=500)
nx.draw_networkx_edges(G, pos,
edgelist=G.edges(),
alpha=0.5, edge_color='#5cce40', width=weights)
nx.draw_networkx_labels(G, pos, font_size=16, font_color='white')
fig.set_facecolor("#262626")
plt.show()
它从 pandas 数据框创建了一个边字典,但重要的部分在我声明 G = nx.DiGraph()
时开始。在这一点上,我拥有所有加权边,并在 [1, 5] 之间对它们进行归一化。
打印语句给了我这个:
SAC RECLAME AQUI 437 5.0
SAC SAC 207 2.8899082568807337
SAC REDES SOCIAIS 13 1.110091743119266
SAC PROCON 1 1.0
SAC BACEN 7 1.0550458715596331
SAC OUVIDORIA 13 1.110091743119266
SAC CHAT 2 1.0091743119266054
REDES SOCIAIS RECLAME AQUI 70 1.6330275229357798
REDES SOCIAIS SAC 10 1.0825688073394495
REDES SOCIAIS REDES SOCIAIS 12 1.1009174311926606
PROCON RECLAME AQUI 5 1.036697247706422
PROCON SAC 1 1.0
PROCON PROCON 2 1.0091743119266054
BACEN RECLAME AQUI 23 1.2018348623853212
BACEN SAC 1 1.0
BACEN BACEN 4 1.0275229357798166
BACEN OUVIDORIA 2 1.0091743119266054
OUVIDORIA RECLAME AQUI 16 1.1376146788990826
OUVIDORIA SAC 2 1.0091743119266054
OUVIDORIA REDES SOCIAIS 2 1.0091743119266054
OUVIDORIA BACEN 2 1.0091743119266054
OUVIDORIA OUVIDORIA 4 1.0275229357798166
CHAT RECLAME AQUI 4 1.0275229357798166
CHAT SAC 1 1.0
CHAT REDES SOCIAIS 1 1.0
即
- SAC -> RECLAME AQUI 可能的最高权重为 5.0
- 下面的高权重边(不是自循环,我没找到怎么画)是 REDES SOCIAIS -> RECLAME AQUI with 1.6330275229357798.
不过,这是我的剧情:
可以看出,第二大宽度的边是SAC -> REDES SOCIAIS
,而REDES SOCIAIS -> RECLAME AQUI
,原始权重为70,比第一个更薄。我不明白为什么。打印显示我的映射是正确的。我是否将错误的参数传递给了某些函数?
nx.draw_networkx_edges
does not draw arrows for self-loops。
所以当有向图包含自环时,传递给 nx.draw_networkx_edges
的权重必须跳过自环权重。否则,权重将与绘制的边不同步。
因此,如果您更改
weights = [G[u][v]['weight'] for u, v in G.edges()]
至
weights = [G[u][v]['weight'] for u, v in G.edges() if u != v]
然后
import networkx as nx
import matplotlib.pyplot as plt
u = ['SAC', 'SAC', 'SAC', 'SAC', 'SAC', 'SAC', 'SAC', 'REDES SOCIAIS', 'REDES SOCIAIS',
'REDES SOCIAIS', 'PROCON', 'PROCON', 'PROCON', 'BACEN', 'BACEN', 'BACEN', 'BACEN',
'OUVIDORIA', 'OUVIDORIA', 'OUVIDORIA', 'OUVIDORIA', 'OUVIDORIA', 'CHAT', 'CHAT',
'CHAT']
v = ['RECLAME AQUI', 'SAC', 'REDES SOCIAIS', 'PROCON', 'BACEN', 'OUVIDORIA', 'CHAT',
'RECLAME AQUI', 'SAC', 'REDES SOCIAIS', 'RECLAME AQUI', 'SAC', 'PROCON',
'RECLAME AQUI', 'SAC', 'BACEN', 'OUVIDORIA', 'RECLAME AQUI', 'SAC',
'REDES SOCIAIS', 'BACEN', 'OUVIDORIA', 'RECLAME AQUI', 'SAC', 'REDES SOCIAIS']
w = [437, 207, 13, 1, 7, 13, 2, 70, 10, 12, 5,
1, 2, 23, 1, 4, 2, 16, 2, 2, 2, 4, 4, 1, 1]
G = nx.DiGraph()
for ui, vi, wi in zip(u, v, w):
G.add_edges_from([(ui, vi)], weight=wi)
pos = nx.circular_layout(G)
edge_labels = dict([((u, v,), d['weight']) for u, v, d in G.edges(data=True)])
weights = [G[u][v]['weight'] for u, v in G.edges() if u != v]
weights = list(map(lambda x: (x - min(weights)) /
(max(weights) - min(weights)), weights))
weights = list(map(lambda x: (x * 4) + 1, weights))
i = 0
for u, v in G.edges():
if u != v:
print(u, v, G[u][v]['weight'], weights[i])
i += 1
fig = plt.figure(figsize=(25, 15))
plt.axis('off')
nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels)
nx.draw_networkx_nodes(G, pos,
nodelist=G.nodes(),
node_color='r',
node_size=500)
nx.draw_networkx_edges(G, pos,
edgelist=G.edges(),
alpha=0.5, edge_color='#5cce40', width=weights)
nx.draw_networkx_labels(G, pos, font_size=16, font_color='white')
fig.set_facecolor("#262626")
plt.show()
产量
有向图中箭头的形状和粗细目前由 this code 设置。要用尖箭头替换矩形 "arrows" 需要用自定义 draw_networkx_edges_with_arrows
函数替换 nx.draw_networkx_edges
:
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
def draw_networkx_edges_with_arrows(G, pos,
edgelist=None,
width=1.0,
edge_color='k',
style='solid',
alpha=1.0,
edge_cmap=None,
edge_vmin=None,
edge_vmax=None,
ax=None,
arrows=True,
label=None,
arrow_width=1.0,
**kwds):
"""
Most of this code comes from https://github.com/networkx/networkx/blob/master/networkx/drawing/nx_pylab.py#L575, except that the arrow LineCollection
has been replaced by mpatches.Arrows below.
"""
try:
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.cbook as cb
from matplotlib.colors import colorConverter, Colormap
from matplotlib.collections import LineCollection
import matplotlib.patches as mpatches
import numpy
import itertools as IT
except ImportError:
raise ImportError("Matplotlib required for draw()")
except RuntimeError:
print("Matplotlib unable to open display")
raise
if ax is None:
ax = plt.gca()
if edgelist is None:
edgelist = G.edges()
if not edgelist or len(edgelist) == 0: # no edges!
return None
# set edge positions
edge_pos = numpy.asarray([(pos[e[0]], pos[e[1]]) for e in edgelist])
if not cb.iterable(width):
lw = (width,)
else:
lw = width
if not cb.is_string_like(edge_color) \
and cb.iterable(edge_color) \
and len(edge_color) == len(edge_pos):
if numpy.alltrue([cb.is_string_like(c)
for c in edge_color]):
# (should check ALL elements)
# list of color letters such as ['k','r','k',...]
edge_colors = tuple([colorConverter.to_rgba(c, alpha)
for c in edge_color])
elif numpy.alltrue([not cb.is_string_like(c)
for c in edge_color]):
# If color specs are given as (rgb) or (rgba) tuples, we're OK
if numpy.alltrue([cb.iterable(c) and len(c) in (3, 4)
for c in edge_color]):
edge_colors = tuple(edge_color)
else:
# numbers (which are going to be mapped with a colormap)
edge_colors = None
else:
raise ValueError('edge_color must consist of either color names or numbers')
else:
if cb.is_string_like(edge_color) or len(edge_color) == 1:
edge_colors = (colorConverter.to_rgba(edge_color, alpha), )
else:
raise ValueError('edge_color must be a single color or list of exactly m colors where m is the number or edges')
edge_collection = LineCollection(edge_pos,
colors=edge_colors,
linewidths=lw,
antialiaseds=(1,),
linestyle=style,
transOffset = ax.transData,
)
edge_collection.set_zorder(1) # edges go behind nodes
edge_collection.set_label(label)
ax.add_collection(edge_collection)
# Note: there was a bug in mpl regarding the handling of alpha values for
# each line in a LineCollection. It was fixed in matplotlib in r7184 and
# r7189 (June 6 2009). We should then not set the alpha value globally,
# since the user can instead provide per-edge alphas now. Only set it
# globally if provided as a scalar.
if cb.is_numlike(alpha):
edge_collection.set_alpha(alpha)
if edge_colors is None:
if edge_cmap is not None:
assert(isinstance(edge_cmap, Colormap))
edge_collection.set_array(numpy.asarray(edge_color))
edge_collection.set_cmap(edge_cmap)
if edge_vmin is not None or edge_vmax is not None:
edge_collection.set_clim(edge_vmin, edge_vmax)
else:
edge_collection.autoscale()
arrow_collection = None
if G.is_directed() and arrows:
# a directed graph hack
# draw thick line segments at head end of edge
# waiting for someone else to implement arrows that will work
arrow_colors = edge_colors
# a_pos = []
p = 1.0-0.25 # make head segment 25 percent of edge length
for (src, dst), lwi, color in zip(edge_pos, lw, IT.cycle(arrow_colors)):
x1, y1 = src
x2, y2 = dst
dx = x2-x1 # x offset
dy = y2-y1 # y offset
d = numpy.sqrt(float(dx**2 + dy**2)) # length of edge
if d == 0: # source and target at same position
continue
if dx == 0: # vertical edge
xa = x2
ya = dy*p+y1
if dy == 0: # horizontal edge
ya = y2
xa = dx*p+x1
else:
theta = numpy.arctan2(dy, dx)
xa = p*d*numpy.cos(theta)+x1
ya = p*d*numpy.sin(theta)+y1
dx, dy = x2-xa, y2-ya
patch = mpatches.Arrow(xa, ya, dx, dy,
width=arrow_width,
color=color,
transform=ax.transData)
ax.add_patch(patch)
# update view
minx = numpy.amin(numpy.ravel(edge_pos[:, :, 0]))
maxx = numpy.amax(numpy.ravel(edge_pos[:, :, 0]))
miny = numpy.amin(numpy.ravel(edge_pos[:, :, 1]))
maxy = numpy.amax(numpy.ravel(edge_pos[:, :, 1]))
w = maxx-minx
h = maxy-miny
padx, pady = 0.05*w, 0.05*h
corners = (minx-padx, miny-pady), (maxx+padx, maxy+pady)
ax.update_datalim(corners)
ax.autoscale_view()
return edge_collection
u = ['SAC', 'SAC', 'SAC', 'SAC', 'SAC', 'SAC', 'SAC', 'REDES SOCIAIS', 'REDES SOCIAIS',
'REDES SOCIAIS', 'PROCON', 'PROCON', 'PROCON', 'BACEN', 'BACEN', 'BACEN', 'BACEN',
'OUVIDORIA', 'OUVIDORIA', 'OUVIDORIA', 'OUVIDORIA', 'OUVIDORIA', 'CHAT', 'CHAT',
'CHAT']
v = ['RECLAME AQUI', 'SAC', 'REDES SOCIAIS', 'PROCON', 'BACEN', 'OUVIDORIA', 'CHAT',
'RECLAME AQUI', 'SAC', 'REDES SOCIAIS', 'RECLAME AQUI', 'SAC', 'PROCON',
'RECLAME AQUI', 'SAC', 'BACEN', 'OUVIDORIA', 'RECLAME AQUI', 'SAC',
'REDES SOCIAIS', 'BACEN', 'OUVIDORIA', 'RECLAME AQUI', 'SAC', 'REDES SOCIAIS']
w = [437, 207, 13, 1, 7, 13, 2, 70, 10, 12, 5,
1, 2, 23, 1, 4, 2, 16, 2, 2, 2, 4, 4, 1, 1]
G = nx.DiGraph()
for ui, vi, wi in zip(u, v, w):
G.add_edges_from([(ui, vi)], weight=wi)
pos = nx.circular_layout(G)
edge_labels = dict([((u, v,), d['weight']) for u, v, d in G.edges(data=True)])
weights = [G[u][v]['weight'] for u, v in G.edges()]
weights = np.log(weights)
weights = list(map(lambda x: (x - min(weights)) /
(max(weights) - min(weights)), weights))
weights = list(map(lambda x: (x * 10) + 1, weights))
fig = plt.figure(figsize=(25, 15))
plt.axis('off')
nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels)
nx.draw_networkx_nodes(G, pos,
nodelist=G.nodes(),
node_color='r',
node_size=500)
draw_networkx_edges_with_arrows(G, pos,
width=weights, arrow_width=0.05,
alpha=0.5, edge_color='#5cce40')
nx.draw_networkx_labels(G, pos, font_size=16, font_color='white')
fig.set_facecolor("#262626")
plt.savefig('/tmp/out.pdf', format='pdf', facecolor=fig.get_facecolor(),
bbox_inches='tight')
产量