首页 > 解决方案 > 来自数据框的 Python networkx 绘图,线宽取决于列值

问题描述

我正在研究不同机场之间航线的表示,并希望使用 networkx 图来表示它们。

输入数据是一个数据框,例如:

from, to, airline, trip_number
Paris, New York, Air France, AF001
Paris, Munich, Air France, AF002
Paris, New York, Air France, AF003
Toronto, Paris, Air Canada, AC001
Toronto, Munich, Air Canada, AC002
Munich, New York, Lufthansa, LF001
Franfort, Los Angeles, Lufthansa, LF002
Francfort, Paris, Lufthansa, LF003
Paris, Francfort, Lufthansa, LF004
Paris, Francfort, Air France, AF004
Paris, Francfort, Air Berlin, AB001

我设法获得了网络表示,但我缺少两个项目:

当前最小代码, df 是数据框:

import pandas as pd
import networkx as nx
import matplotlib.pyplot as plt
from nxviz.plots import CircosPlot

G = nx.from_pandas_edgelist(df, 'from', 'to')
nx.draw(G, node_size=5, node_color='red')
plt.show()

谢谢你的手

标签: pythonplotlabelnetworkx

解决方案


以下应该做的工作:

import pandas as pd
from io import StringIO
import networkx as nx
import matplotlib.pyplot as plt

data = ('from, to, airline, trip_number\n'
        'Paris, New York, Air France, AF001\n'
        'Paris, Munich, Air France, AF002\n'
        'Paris, New York, Air France, AF003\n'
        'Toronto, Paris, Air Canada, AC001\n'
        'Toronto, Munich, Air Canada, AC002\n'
        'Munich, New York, Lufthansa, LF001\n'
        'Franfort, Los Angeles, Lufthansa, LF002\n'
        'Francfort, Paris, Lufthansa, LF003\n'
        'Paris, Francfort, Lufthansa, LF004\n'
        'Paris, Francfort, Air France, AF004\n'
        'Paris, Francfort, Air Berlin, AB001')

df = pd.read_csv(StringIO(data), sep=", ")

# see https://stackoverflow.com/a/10374456
short_df = pd.DataFrame({'count': df.groupby(["from", "to"]).size()}).reset_index()

G = nx.from_pandas_edgelist(short_df, source='from', target='to', edge_attr="count")

# edge size, see https://stackoverflow.com/a/25651827
weights = [G[u][v]['count'] for u,v in G.edges()]

nx.draw(G, node_size=5, node_color='red', with_labels=True, width=weights)
plt.show()

解释

您首先需要检索航班数量,这pandas很容易做到。有了这里的答案,我创建了一个只有三列(“from”、“to”、“count”)的新数据框。之后,您需要在创建图形时包含边缘属性,即 add edge_attr="count"。然后,我按照这个答案来控制边缘宽度。

最后,将标签添加到图中with_labels=Truedraw. 您可以使用 的所有参数draw_networkx


推荐阅读