-1

My dictionary is large basically some dictionary values intersect and I would like to represent that in form of a graph.

My_dictionary = { A : {1 , 2, 4 }, B : {1,3}, C : {5} ..... etc}

The desired outcome is a diagram that links the nodes A, B, C to these endpoints the dictionary values. I tried a tree diagram and graphviz and still can't figure out how to automate this process. I even tried to create a heatmap by making the endpoints into a diagonal and the populated the dataframe with cosine similarity. please help

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
FalconX
  • 53
  • 7
  • What have you tried? SO is not a coding service. Please read the following documentation, then [edit], and rephrase the question. [Take the Tour](https://stackoverflow.com/tour), [How to ask a good question](https://stackoverflow.com/help/how-to-ask), & [On Topic](https://stackoverflow.com/help/on-topic). Always provide a [mre] with **code, data, errors, current & expected output, as [formatted text](https://stackoverflow.com/help/formatting)** & **you're expected to [try to solve the problem first](https://meta.stackoverflow.com/questions/261592) and show your effort**. – Trenton McKinney Oct 13 '22 at 21:07
  • Why are you looking at tree diagrams? In what way is the diagram that you want to draw a "tree"? – Ben Grossmann Oct 13 '22 at 23:07

1 Answers1

3

Here's my best guess at what you're looking for.

import networkx as nx

my_dictionary = { 'A' : {1 , 2, 4 }, 'B' : {1,3}, 'C' : {5}}
G = nx.Graph()
G.add_edges_from([k,x] for k,v in my_dictionary.items() for x in v)
nx.draw(G, pos = nx.bipartite_layout(G,my_dictionary.keys()), 
        with_labels = True, node_color = 'orange')

The result:

enter image description here


Only using the one-edge nodes:

import networkx as nx
import matplotlib.pyplot as plt
from collections import defaultdict

my_dictionary = { 'A' : {1 , 2, 4 }, 'B' : {1,3}, 'C' : {5}}
G = nx.Graph()
G.add_edges_from([k,x] for k,v in my_dictionary.items() for x in v)

pos = nx.bipartite_layout(G,my_dictionary.keys())
nx.draw(G, pos = pos,with_labels = True, node_color = 'orange')
plt.show()

one_link_nodes = [n for n,k in G.degree if k==1]
G.remove_nodes_from(one_link_nodes)
# pos = nx.bipartite_layout(G,my_dictionary.keys()) # if you don't want to reuse the layout above
nx.draw(G, pos=pos, with_labels = True, node_color = 'orange')
plt.show()

Resulting images:

enter image description here

enter image description here


Another alternative to consider:

import networkx as nx
import matplotlib.pyplot as plt

my_dictionary = { 'A' : {1 , 2, 4 }, 'B' : {1,3}, 'C' : {5}}
G = nx.Graph()
G.add_edges_from([k,x] for k,v in my_dictionary.items() for x in v)

pos = nx.bipartite_layout(G,my_dictionary.keys())
one_link_nodes = set(n for n,k in G.degree if k==1)
styles = ['--' if u in one_link_nodes or v in one_link_nodes else '-' for u,v in G.edges]
edge_colors = ['gray' if u in one_link_nodes or v in one_link_nodes else 'k' for u,v in G.edges]
node_colors = ['lightsteelblue' if n in one_link_nodes else 'orange' for n in G.nodes]
nx.draw(G, pos = pos, with_labels = True, node_color = node_colors, 
        edge_color = edge_colors, style = styles)
plt.show()

The result:

enter image description here

Ben Grossmann
  • 4,387
  • 1
  • 12
  • 16
  • How would you only show the ones with more than one link in this case only draw A and B only linking to 1 thanks lot – FalconX Oct 17 '22 at 17:18
  • See my edit. I have it configured now so that both the original and one-link version use the same layout. If you prefer, you can just compute the layout by calling `pos = nx.bipartite_layout(G,my_dictionary.keys())` after removing nodes. – Ben Grossmann Oct 17 '22 at 17:31
  • Wow dude you made my week not gonna lie thanks a lot superstar – FalconX Oct 17 '22 at 17:55
  • @FalconX Glad to help. If that's everything you were looking for, I'd appreciate it if you would "accept" the answer by clicking the check mark (**✓**) underneath the vote arrows on my answer. – Ben Grossmann Oct 17 '22 at 19:40