Reputation: 21
How can I expand this code, to include a different number of hexagonal layers? I need a graph of a hexagonal lattice given number m of layers. m=1 means 1 regular hexagon with side 1 and center at the origin, for m=2 add 6 regular hexagons around the initial one, for m=3 add the 3rd layer of hexagons, so on.
import networkx as nx
import matplotlib.pyplot as plt
G = nx.hexagonal_lattice_graph(m=2,n=3, periodic=False, with_positions=True,
create_using=None)
pos = nx.get_node_attributes(G, 'pos')
nx.draw(G, pos=pos, with_labels=True)
plt.show()
Upvotes: 2
Views: 1003
Reputation: 22506
An interesting question! Took me a little longer than I expected. Basically, the function hexagonal_lattice_graph()
produces a m x n
rectangular grid of hexagons. So, the task is to first draw a large grid, and then remove the nodes that are outside of the outermost layer.
I use distance to decide which nodes remain, and which ones get removed. It was further tricky because odd and even m
behave slightly differently. So the center coordinates have to be calculated carefully.
import networkx as nx
import matplotlib.pyplot as plt
def node_dist(x,y, cx, cy):
"""Distance of each node from the center of the innermost layer"""
return abs(cx-x) + abs(cy-y)
def remove_unwanted_nodes(G, m):
"""Remove all the nodes that don't belong to an m-layer hexagonal ring."""
#Compute center of all the hexagonal rings as cx, cy
cx, cy = m-0.5, 2*m -(m%2) #odd is 2m-1, even is 2m
#in essence, we are converting from a rectangular grid to a hexagonal ring... based on distance.
unwanted = []
for n in G.nodes:
x,y = n
#keep short distance nodes, add far away nodes to the list called unwanted
if node_dist(x,y, cx, cy) > 2*m:
unwanted.append(n)
#now we are removing the nodes from the Graph
for n in unwanted:
G.remove_node(n)
return G
##################
m = 4 #change m here. 1 = 1 layer, single hexagon.
G = nx.hexagonal_lattice_graph(2*m-1,2*m-1, periodic=False,
with_positions=True,
create_using=None)
pos = nx.get_node_attributes(G, 'pos')
G = remove_unwanted_nodes(G, m)
#render the result
plt.figure(figsize=(9,9))
nx.draw(G, pos=pos, with_labels=True)
plt.axis('scaled')
plt.show()
Which produces the following for m=3:
and for m=4:
Welcome to SO! Hope the solution above is clear and helps you move forward.
Upvotes: 3