2

What is the best way to generate a Directed Graph With Parallel Labelled Edges/Vertices in Python like the one in the Image below??

I have already tried networkx but it does not work with parallel edges.

enter image description here

This is the code I'm using to generate the data for the Graph.

from forex_python.converter import CurrencyRates
import pandas as pd

chosen_currencies = ['GBP', 'EUR', 'USD']

c = CurrencyRates()

rates = []


for currency_index in range(len(chosen_currencies)):
    temp_list = []
    for second_index in range(len(chosen_currencies)):
        temp_list.append(c.get_rate(chosen_currencies[currency_index], chosen_currencies[second_index]))
    rates.append(temp_list)

df = (pd.DataFrame.from_records(rates)).transpose()
df.columns = chosen_currencies
Matheus Torquato
  • 1,293
  • 18
  • 25

1 Answers1

2

You can use the dataframe to read the edges directly into a NetworkX graph using from_pandas_adjacency. In order to do that, lets set the index of the dataframe equal to chosen_currencies, to ensure that the edges are mapped correctly.

from forex_python.converter import CurrencyRates
import pandas as pd

chosen_currencies = ['GBP', 'EUR', 'USD']

c = CurrencyRates()

rates = []


for currency_index in range(len(chosen_currencies)):
    temp_list = []
    for second_index in range(len(chosen_currencies)):
        temp_list.append(c.get_rate(chosen_currencies[currency_index], chosen_currencies[second_index]))
    rates.append(temp_list)

df = (pd.DataFrame.from_records(rates)).transpose()
df.columns = chosen_currencies
#   GBP         EUR     USD
#0  1.000000    0.83238 0.768233
#1  1.201374    1.00000 0.922935
#2  1.301689    1.08350 1.000000

Now set the index

df.set_index([pd.Index(chosen_currencies)], inplace=True)
#       GBP         EUR     USD
#GBP    1.000000    0.83238 0.768233
#EUR    1.201374    1.00000 0.922935
#USD    1.301689    1.08350 1.000000

Now let's create the graph

import networkx as nx
import matplotlib.pyplot as plt

G = nx.from_pandas_adjacency(df, create_using=nx.DiGraph)

# Set the figure size
plt.figure(figsize=(8,8))

# Get the edge labels and round them to 3 decimal places
# for more clarity while drawing
edge_labels = dict([((u,v), round(d['weight'], 3))
             for u,v,d in G.edges(data=True)])

# Get the layout
pos = nx.spring_layout(G)

# Draw edge labels and graph
nx.draw_networkx_edge_labels(G,pos,edge_labels=edge_labels,
                             label_pos=0.15, font_size=10)
nx.draw(G, pos, with_labels=True,
        connectionstyle='arc3, rad = 0.15',
        node_size=800)

plt.show()

Currency Graph

Note: The number near the arrowhead is the edge weight.

You can also view this Google Colab Notebook with above working example.

You can adjust the font size, label position, etc. according to your requirements.

References:

Gambit1614
  • 8,547
  • 1
  • 25
  • 51
  • I'm trying to find which parameter puts the weights over the edges like [this](https://i.stack.imgur.com/cQqOQ.png). Have you got any idea? The Graph gets quite messy when I add more nodes. [This](https://ibb.co/VJhvqd3) Is what I generated and it does not look very readable. – Matheus Torquato Feb 18 '20 at 11:34
  • Dense graphs like that are better visualized using tables. – Björn Lindqvist Feb 17 '22 at 12:28