
A YouTube video about “percolation” includes an interesting animation of shifting colours that exhibits a sudden phase transition. As a challenge, I set out to replicate the evolving pattern in Python. But then I remembered hearing that ChatGPT was good at writing code, so I asked it for help
Percolation
Percolation models can be used to simulate physical systems, such as liquids permeating through porous materials. The idea is to take a grid pattern of nodes with edges between them, and then remove edges at random. Each edge survives with a probability, p. If the edges were pipes, we could imagine that water could percolate through a well-connected grid (image on the left), but, as more edges are removed, the nodes form connected islands that prevent onward percolation (image on the right).


Asking ChatGPT
I started by asking ChatGPT to model a randomly connected lattice in Python. It suggested using a library called networkx that I have used in the past, so I pasted the code into a Jupyter notebook. The code worked, but the nodes were scattered at random, so I asked ChatGPT for code to produce a regular grid. This failed, so I passed the error message back to ChatGPT, which explained the problem and suggested revised code that worked perfectly, producing something like the left hand image above.
The next step was to apply the same colour to all connected nodes. Initially I called these clusters, but then I discovered that networkx has a method called connected_components, so I substituted this into ChatGPT’s code. After about half an hour, I had added more colours and some ipywidget sliders, to produce a fully working interactive model, where I could vary p and adjust the size of the grid.
The really interesting behaviour happens when p is around 0.5. Below this value the grid tends to form a disjoint set of unconnected islands, but above the critical value, the large areas quickly connect up. This image at the top of this blog occurs around the middle of the video below.
Python code
This is the code if you want to try it yourself. You might need to pip install networkx and ipywidgets.
import networkx as nx
import numpy as np
import matplotlib.pyplot as plt
import random
from ipywidgets import interact
def randomLattice(p=0.5, n = 100):
# Square grid m=n
m=n
# Create a 2D grid of nodes using NumPy
nodes = np.array([(i, j) for i in range(m) for j in range(n)])
# Convert the NumPy array to a list of tuples
nodes = [tuple(node) for node in nodes]
# Create an empty graph
G = nx.Graph()
# Add nodes to the graph
G.add_nodes_from(nodes)
# Connect adjacent nodes horizontally
for i in range(m):
for j in range(n-1):
if random.random() < p: # adjust the probability to control the connectivity
G.add_edge((i, j), (i, j+1))
# Connect adjacent nodes vertically
for i in range(m-1):
for j in range(n):
if random.random() < p: # adjust the probability to control the connectivity
G.add_edge((i, j), (i+1, j))
clusters = list(nx.connected_components(G))
colours = ["b", "r", "g", "y", "m", "c", "k",'lime','cyan','violet','gold','indigo','navy','grey','peru']
node_to_colour = {}
for i, cluster in enumerate(clusters):
for node in cluster:
node_to_colour[node] = colours[i%len(colours)]
#print(clusters)
# Draw the graph as a regular grid
pos = dict(zip(nodes, nodes))
nx.draw(G, pos=pos, node_color=[node_to_colour[i] for i in nodes],
with_labels=False,node_size=20)
#plt.savefig(f'Grid_{int(p*100):03d}.png')
plt.show()
return
interact(randomLattice,p=(0,1,0.01), n = (5,200,1));