I have a pandas data frame with two columns: source and sink. In a simplified form, there are just 5 users (source column) that can owe money to any other user (sink column). I thought the following code would show the plot of user 1 owing to user 3 (yes arrow is correct, good), user 2 to 4 (good), 3 to 5 (good), 4 to 1 (wrong), 5 to 2 (wrong). What should I do to get the last two arrows to point in the right direction?
df = pd.DataFrame({'source': [1, 2, 3, 4, 5], 'sink': [3, 4, 5, 1, 2]})
G = nx.Graph()
for row in df.iterrows():
print(row[1]['source'], row[1]['sink'])
G.add_edge(row[1]['source'], row[1]['sink'])
pos = nx.spring_layout(G)
nodes = nx.draw_networkx_nodes(G, pos, node_color="orange")
nx.draw_networkx_labels(G, pos)
edges = nx.draw_networkx_edges(
G,
pos,
arrows=True,
arrowstyle="->",
arrowsize=10,
width=2,
)
That's due to the order of the users in the dataframe. If you look closely at your graph, the arrow always points from U
to V
where U < V
(in terms of the physical position). Actually, networkx uses a FancyArrowPatch(start, end, ...)
under the hood to make the arrows, like in this example :
import matplotlib.pyplot as plt
from matplotlib.patches import FancyArrowPatch
fig, ax = plt.subplots(figsize=(6, 1))
ax.add_patch(
FancyArrowPatch((0.2, 0.5), (0.8, 0.5), mutation_scale=30, arrowstyle="-|>")
)
What you want is a DiGraph
, where the arrows are supposed to work with :
DG = nx.from_pandas_edgelist(df, "source", "sink", create_using=nx.DiGraph)
nx.draw_networkx(
DG,
nx.spring_layout(DG, seed=0),
node_color="orange",
edgecolors="k",
arrowsize=20,
)