как рисовать направленные графики с помощью networkx в python?


У меня есть некоторые узлы, поступающие из сценария, который я хочу отобразить на график. В приведенном ниже примере я хочу использовать стрелку, чтобы перейти от A К D, и, вероятно, край тоже окрашен (красный или что-то еще). Это в основном, как путь от A до D, когда присутствуют все остальные узлы. вы можете представить себе, что каждый узел - это город, и путешествие от A до D требует направлений (с головками стрелок). Этот код, приведенный ниже, строит график

import networkx as nx
import numpy as np
import matplotlib.pyplot as plt

G = nx.Graph()
G.add_edges_from(
    [('A', 'B'), ('A', 'C'), ('D', 'B'), ('E', 'C'), ('E', 'F'),
     ('B', 'H'), ('B', 'G'), ('B', 'F'), ('C', 'G')])

val_map = {'A': 1.0,
           'D': 0.5714285714285714,
           'H': 0.0}

values = [val_map.get(node, 0.25) for node in G.nodes()]

nx.draw(G, cmap = plt.get_cmap('jet'), node_color = values)
plt.show()

но я хочу что-то, как показано в изображение.

стрелки первого изображения и края красного цвета на втором изображении..Спасибо

5 65

5 ответов:

полностью конкретизированный пример со стрелками только для красных краев:

import networkx as nx
import matplotlib.pyplot as plt

G = nx.DiGraph()
G.add_edges_from(
    [('A', 'B'), ('A', 'C'), ('D', 'B'), ('E', 'C'), ('E', 'F'),
     ('B', 'H'), ('B', 'G'), ('B', 'F'), ('C', 'G')])

val_map = {'A': 1.0,
           'D': 0.5714285714285714,
           'H': 0.0}

values = [val_map.get(node, 0.25) for node in G.nodes()]

# Specify the edges you want here
red_edges = [('A', 'C'), ('E', 'C')]
edge_colours = ['black' if not edge in red_edges else 'red'
                for edge in G.edges()]
black_edges = [edge for edge in G.edges() if edge not in red_edges]

# Need to create a layout when doing
# separate calls to draw nodes and edges
pos = nx.spring_layout(G)
nx.draw_networkx_nodes(G, pos, cmap=plt.get_cmap('jet'), 
                       node_color = values, node_size = 500)
nx.draw_networkx_labels(G, pos)
nx.draw_networkx_edges(G, pos, edgelist=red_edges, edge_color='r', arrows=True)
nx.draw_networkx_edges(G, pos, edgelist=black_edges, arrows=False)
plt.show()

Red edges

Я только положил это для полноты картины. Я многому научился у Мариуса и mdml. Вот веса ребер. Извините за стрелы. Похоже, я не единственный, кто говорит, что с этим ничего не поделаешь. Я не мог сделать это с помощью IPython notebook, мне пришлось идти прямо с python, что было проблемой с получением моих весов края раньше.

import networkx as nx
import numpy as np
import matplotlib.pyplot as plt
import pylab

G = nx.DiGraph()

G.add_edges_from([('A', 'B'),('C','D'),('G','D')], weight=1)
G.add_edges_from([('D','A'),('D','E'),('B','D'),('D','E')], weight=2)
G.add_edges_from([('B','C'),('E','F')], weight=3)
G.add_edges_from([('C','F')], weight=4)


val_map = {'A': 1.0,
                   'D': 0.5714285714285714,
                              'H': 0.0}

values = [val_map.get(node, 0.45) for node in G.nodes()]
edge_labels=dict([((u,v,),d['weight'])
                 for u,v,d in G.edges(data=True)])
red_edges = [('C','D'),('D','A')]
edge_colors = ['black' if not edge in red_edges else 'red' for edge in G.edges()]

pos=nx.spring_layout(G)
nx.draw_networkx_edge_labels(G,pos,edge_labels=edge_labels)
nx.draw(G,pos, node_color = values, node_size=1500,edge_color=edge_colors,edge_cmap=plt.cm.Reds)
pylab.show()

enter image description here

вы должны использовать ориентированный граф вместо графика, т. е.

G = nx.DiGraph()

затем создайте список цветов, которые вы хотите использовать и передавать их в nx.draw (как показано @Marius).

положить все это вместе, я получаю изображение ниже. Все еще не совсем другая картина, которую вы показываете (я не знаю, откуда берутся ваши весовые коэффициенты), но гораздо ближе! Если вы хотите больше контролировать, как выглядит ваш выходной график (например, получить стрелки, которые выглядят так стрелки), я бы проверил NetworkX с Graphviz.

enter image description here

вместо обычного nx.нарисуйте вы можете использовать:

nx.draw_networkx(G[, pos, arrows, with_labels])

например:

nx.draw_networkx(G, arrows=True, **options)

вы можете добавить параметры, инициализируя эту переменную * * следующим образом:

options = {
    'node_color': 'blue',
    'node_size': 100,
    'width': 3,
    'arrowstyle': '-|>',
    'arrowsize': 12,
}

также некоторые вспомогательные функции directed=True parameter В этом случае это состояние по умолчанию:

G = nx.DiGraph(directed=True)

ссылка на networkx найдена здесь.

Graph with arrows image

import networkx as nx
import matplotlib.pyplot as plt

g = nx.DiGraph()
g.add_nodes_from([1,2,3,4,5])
g.add_edge(1,2)
g.add_edge(4,2)
g.add_edge(3,5)
g.add_edge(2,3)
g.add_edge(5,4)

nx.draw(g,with_labels=True)
plt.draw()
plt.show()

Это просто, как рисовать ориентированный график с помощью python 3.x с помощью networkx. просто простое представление и может быть изменено и окрашено и т. д. Смотрите сгенерированный график здесь.

Примечание: это просто простое представление. Взвешенные края могут быть добавлены как

g.add_edges_from([(1,2),(2,5)], weight=2)

и поэтому снова строится график.