An explanation of rule 30: https://en.wikipedia.org/wiki/Rule_30

import matplotlib.pyplot as plt
import numpy as np
def create_array(n):
    l = [int(x) for x in np.zeros(n)]
    m = n//2
    l[m] = 1
    return l


def add_array(arr):
    i = 0
    new_array= []
    for i in range(len(arr)):
        if i == len(arr) - 1: 
            new_array.append(0)
            break
        elif arr[i-1] == 0 and arr[i] == 0 and arr[i+1] == 0: #000
            new_array.append(0)
        elif arr[i-1] == 0 and arr[i] == 0 and arr[i+1] == 1: #001
            new_array.append(1)
        elif arr[i-1] == 0 and arr[i] == 1 and arr[i+1] == 0: #010
            new_array.append(1)
        elif arr[i-1] == 0 and arr[i] == 1 and arr[i+1] == 1: #011
            new_array.append(1)
        elif arr[i-1] == 1 and arr[i] == 0 and arr[i+1] == 0: #100
            new_array.append(1)
        elif arr[i-1] == 1 and arr[i] == 0 and arr[i+1] == 1: #101
            new_array.append(0)
        elif arr[i-1] == 1 and arr[i] == 1 and arr[i+1] == 0: #110
            new_array.append(0)
        elif arr[i-1] == 1 and arr[i] == 1 and arr[i+1] == 1: #111
            new_array.append(0)
            
    return new_array
init_arr = create_array(500)

a = []
x = []
for i in range(250):
    if i == 0:
        a.append(init_arr)
    elif i == 1:
        x = add_array(init_arr)
        a.append(x)
    elif i >= 1:
        x = add_array(x)
        a.append(x)
        
y=np.array([np.array(xi) for xi in a])

plt.figure(figsize = (20,40))

plt.imshow(y, interpolation='nearest')
plt.show()