In [70]:
import random
import numpy
from random import randint
from IPython.html import widgets
from IPython.display import display
from ipythonblocks import BlockGrid
from IPython.display import clear_output
from IPython.html.widgets import interact, interactive
In [106]:
#THE GRID MAKER WOOO!!!
grid_size = 5 #testing this grid maker
grid = BlockGrid(grid_size,grid_size)
for i in range(grid.height):
for j in range(grid.width):
rand_int1 = random.randint(1,3)
if rand_int1 == 1:
grid[i,j] = (0, 0, 255)
elif rand_int1 == 2:
grid[i,j] = (255, 0, 0)
elif rand_int1 == 3:
grid[i,j] = (0, 0, 0)
if grid[i,j] == (0, 0, 255):
grid[i,j] = blue_cell
elif grid[i,j] == (255, 0, 0):
grid[i,j] = red_cell
elif grid[i,j] == (0, 0, 0):
grid[i,j] = empty_cell
cell1 = grid[i,j]
grid.show()
In [ ]:
#def move(population,satisfaction_thresh):
#
# not_satisfied_population = pd.DataFrame(population)
#
# for agent_coord in population:
#
# block = Schelling[tuple(agent_coord)]
# coords_to_check = np.array([np.array(agent_coord) + np.array((1,0)),np.array(agent_coord) + np.array((1,1)), np.array(agent_coord) + np.array((0,1)),
# np.array(agent_coord) + np.array((1,-1)), np.array(agent_coord) + np.array((0,-1)),
# np.array(agent_coord) + np.array((-1,-1)), np.array(agent_coord) + np.array((-1,0)),
# np.array(agent_coord) + np.array((-1,1))])
#
# coords_to_check = pd.DataFrame(coords_to_check)
# coords_to_check = coords_to_check[coords_to_check>=0].dropna()
# coords_to_check = coords_to_check[coords_to_check.ix[:,0] <= xsize-1].dropna()
# coords_to_check = coords_to_check[coords_to_check.ix[:,1] <= ysize-1].dropna()
#
# if agent_coord == [2,4]:
# display(coords_to_check)
# number_of_neighbors = 0
# same_neighbors = 0
# dif_neighbors = 0
# grey = (236,240,241)
#
# for check_coord in coords_to_check.values:##
# check_block = Schelling[int(check_coord[0]),int(check_coord[1])]
#
# if check_block.rgb == block.rgb:
## same_neighbors += 1
## number_of_neighbors += 1
##
## if check_block.rgb != block.rgb and check_block.rgb != grey:
## dif_neighbors += 1
## number_of_neighbors += 1
##
## if number_of_neighbors == 0 or (same_neighbors-dif_neighbors)/number_of_neighbors >= satisfaction_thresh:
# print('Satisfied!')
# print(agent_coord)
# print((same_neighbors-dif_neighbors)/number_of_neighbors)
# print('\n')
# not_satisfied_population = not_satisfied_population[not_satisfied_population.values != agent_coord]
# not_satisfied_population.drop_duplicates(inplace = True)
# else:
# print('Not Satisfied!')
# print(agent_coord)
# print((same_neighbors-dif_neighbors)/number_of_neighbors)
# print('\n')
# return not_satisfied_population
In [61]:
#This checks the rgb of each cell; returns true if they are the same color.
def equal_rgb(a,b):
if (a.red,a.green,a.blue)==(b.red,b.green,b.blue):
return True
else:
return False
In [62]:
#Checks if the rgb is black.
def equal_black(a):
if (a.red == 0) and (a.green == 0) and (a.blue == 0):
return True
else:
return False
In [104]:
def satisfaction(grid,i,j):
if grid[i,j]!=(0,0,0): #if you are equal to black you will not enter the if statement
GridSize = grid.width
sat = 0 #Count for saturation always will start at 0
#Saturation meaning if the color is the same.
if i == 0 or j == 0 or i == GridSize-1 or j == GridSize-1: #Edges: have 5 possible neighbors
MaxNeighbors = 5
#----------------------------The Corner Pieces------------
#----------------------------Upper Left Corner-------------
if i == 0 and j == 0:
MaxNeighbors = 3 #The max neighbors is three in all corners
if equal_rgb(grid[i+1,j],grid[i,j]): # Checking the neighbors
sat = sat + 1 # If the color is equal, the 'True' will translate to an addition of 1 to sat
elif equal_black(grid[i+1,j]): # If the block is black, then the max neighbors goes down since no one is there.
MaxNeighbors -= 1
if equal_rgb(grid[i+1,j+1],grid[i,j]): #same thing
sat = sat + 1
elif equal_black(grid[i+1,j+1]):
MaxNeighbors -= 1
if equal_rgb(grid[i,j+1],grid[i,j]): #same thing
sat = sat + 1
elif equal_black(grid[i,j+1]):
MaxNeighbors -= 1
if MaxNeighbors == 0: # No neighbors? Then you're not satisfied.
satisfaction = 0 # Cannot divide by zero, so we can make satisfaction rating automatically 0.
return satisfaction
else:
satisfaction = float(sat) / float(MaxNeighbors) #Had to make the satisfaction rating a float otherwise it would not work.
return satisfaction
#-----------------------------Bottom Left Corner---------------------------------------
elif i == 0 and j == GridSize-1:
MaxNeighbors = 3
if equal_rgb(grid[i,j-1],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i,j-1]):
MaxNeighbors -= 1
if equal_rgb(grid[i+1,j-1],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i+1,j-1]):
MaxNeighbors -= 1
if equal_rgb(grid[i,j-1],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i,j-1]):
MaxNeighbors -= 1
if MaxNeighbors == 0:
satisfaction = 0
return satisfaction
else:
satisfaction = float(sat) / float(MaxNeighbors)
return satisfaction
#---------------------------Upper Right Corner---------------------------------
elif (i==GridSize-1 and j ==0):
MaxNeighbors = 3
if equal_rgb(grid[i-1,j],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i-1,j]):
MaxNeighbors -= 1
if equal_rgb(grid[i-1,j+1],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i-1,j+1]):
MaxNeighbors -= 1
if equal_rgb(grid[i,j+1],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i,j+1]):
MaxNeighbors -= 1
if MaxNeighbors == 0:
satisfaction = 0
return satisfaction
else:
satisfaction = float(sat) / float(MaxNeighbors)
return satisfaction
#------------------Bottom Right Corner---------------------------------------
elif (i == GridSize-1 and j ==GridSize-1):
MaxNeighbors = 3
if equal_rgb(grid[i-1,j],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i-1,j]):
MaxNeighbors -= 1
if equal_rgb(grid[i-1,j-1],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i-1,j-1]):
MaxNeighbors -= 1
if equal_rgb(grid[i,j-1],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i,j-1]):
MaxNeighbors -= 1
if MaxNeighbors == 0:
satisfaction = 0
return satisfaction
else:
satisfaction = float(sat) / float(MaxNeighbors)
return satisfaction
#------------Edge Pieces-------------------------------------------
#------------The Left Edge-----------------------------------------
elif i == 0 and j != 0 and j!=GridSize-1 :
if equal_rgb(grid[i+1,j],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i+1,j]):
MaxNeighbors -= 1
if equal_rgb(grid[i+1,j+1],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i+1,j+1]):
MaxNeighbors -= 1
if equal_rgb(grid[i+1,j-1],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i+1,j-1]):
MaxNeighbors -= 1
if equal_rgb(grid[i,j-1],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i,j-1]):
MaxNeighbors -= 1
if equal_rgb(grid[i,j+1],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i,j+1]):
MaxNeighbors -= 1
if MaxNeighbors == 0:
satisfaction = 0
return satisfaction
else:
satisfaction = float(sat) / float(MaxNeighbors)
return satisfaction
#---------------------------The Top Edge------------------------------------------
elif j == 0 and i!=0 and i!=GridSize-1:
if equal_rgb(grid[i+1,j],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i+1,j]):
MaxNeighbors -= 1
if equal_rgb(grid[i+1,j+1],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i+1,j+1]):
MaxNeighbors -= 1
if equal_rgb(grid[i,j+1],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i,j+1]):
MaxNeighbors -= 1
if equal_rgb(grid[i-1,j+1],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i-1,j+1]):
MaxNeighbors -= 1
if equal_rgb(grid[i-1,j],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i-1,j]):
MaxNeighbors -= 1
if MaxNeighbors == 0:
satisfaction = 0
return satisfaction
else:
satisfaction = float(sat) / float(MaxNeighbors)
return satisfaction
#-----------------------------------The Right Edge---------------------------------------------------
elif i == GridSize-1 and j !=0 and j!=GridSize-1:
if equal_rgb(grid[i,j+1],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i,j+1]):
MaxNeighbors -= 1
if equal_rgb(grid[i-1, j-1],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i-1, j-1]):
MaxNeighbors -= 1
if equal_rgb(grid[i-1,j],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i-1,j]):
MaxNeighbors -= 1
if equal_rgb(grid[i,j-1],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i,j-1]):
MaxNeighbors -= 1
if equal_rgb(grid[i-1,j+1],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i-1,j+1]):
MaxNeighbors -= 1
if MaxNeighbors == 0:
satisfaction = 0
return satisfaction
else:
satisfaction = float(sat) / float(MaxNeighbors)
return satisfaction
#--------------------------------------The Bottom Edge-----------------------------------
elif j == GridSize-1 and i!=0 and i != GridSize-1:
if equal_rgb(grid[i+1,j],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i+1,j]):
MaxNeighbors -= 1
if equal_rgb(grid[i-1, j-1],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i-1, j-1]):
MaxNeighbors -= 1
if equal_rgb(grid[i-1,j],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i-1,j]):
MaxNeighbors -= 1
if equal_rgb(grid[i,j-1],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i,j-1]):
MaxNeighbors -= 1
if equal_rgb(grid[i+1,j-1],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i+1,j-1]):
MaxNeighbors -= 1
if MaxNeighbors == 0:
satisfaction = 0
return satisfaction
else:
satisfaction = float(sat) / float(MaxNeighbors)
return satisfaction
#-----------Cells not on the edge in the else statement. Must check all sides (8 neighbors max)-------------
else:
MaxNeighbors = 8
if equal_rgb(grid[i+1,j],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i+1,j],):
MaxNeighbors -= 1
if equal_rgb(grid[i+1,j+1],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i+1,j+1]):
MaxNeighbors -= 1
if equal_rgb(grid[i,j+1],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i,j+1]):
MaxNeighbors -= 1
if equal_rgb(grid[i-1, j-1],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i-1, j-1]):
MaxNeighbors -= 1
if equal_rgb(grid[i-1,j],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i-1,j]):
MaxNeighbors -= 1
if equal_rgb(grid[i,j-1],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i,j-1]):
MaxNeighbors -= 1
if equal_rgb(grid[i-1,j+1],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i-1,j+1]):
MaxNeighbors -= 1
if equal_rgb(grid[i+1,j-1],grid[i,j]):
sat = sat + 1
elif equal_black(grid[i+1,j-1]):
MaxNeighbors -= 1
if MaxNeighbors == 0:
satisfaction = 0
return satisfaction
else:
satisfaction = float(sat) / float(MaxNeighbors)
return satisfaction
else: #If it's black then nothing happens
return None
In [ ]:
def find_movers(grid,threshold):
movers = []
nulls = []
for i in range(grid.width): #Iterates through the grid.
for j in range(grid.height):
if equal_black(grid[i,j]): #Finds empty cells
nulls.append((i,j)) #These cells are appended (something I could not do with my first attempt at this!)
else: #Else means colored cells
if satisfaction(grid,i,j) < threshold: #compares satisfaction to the satisfaction threshold, aka the percent a cell desires for similar race neighbors
movers.append((i,j)) #The cells that are not satisfied are appended to movers
for i in range(len(movers)-1): #Loops through movers list
if len(nulls) != 0: # Needs this to fix error if the length is 0
p = random.randint(0,len(nulls)-1) # picks random indice from nulls aka our black cells.
#This next part changes the color of the black cells to the mover cell. The movers then turn into black cells.
#nulls are removed since they are no longer nulls until the next iteration.
grid[nulls[p]].rgb = grid[movers[i]].rgb
grid[movers[i]].rgb = (0,0,0)
nulls.remove(nulls[p])
clear_output() #We can see changes with the block grid with clear_output()
grid.show()
In [108]:
#THIS IS THE THING!!
def Schelling(Grid_Size=100,Threshold=0.5,RedPop=60,BluePop=30,Iterations=1): # How this part should look once we're using the sliders
grid = BlockGrid(Grid_Size,Grid_Size) #Creates grid
if (RedPop + BluePop)> 100: #Makes sure the total population does not exceed 100%
print ("Values of (red plus blue) must not exceed 100 %")
else:
for i in range(grid.height): #This is basically the random generator from before.
for j in range(grid.width): #The percent of it happening depends on the percent from the sliders
rand_int1 = random.randint(1,100)
if rand_int1 <= BluePop:
grid[i,j] = (0, 0, 255)
elif rand_int1 <= (RedPop + BluePop):
grid[i,j] = (255, 0, 0)
elif rand_int1 > (RedPop + BluePop):
grid[i,j] = (0, 0, 0)
grid.show()
while Iterations > 0: #Running iterations as long as there are unsatisfied cells.
find_movers(grid,Threshold) #Finds the movers
Iterations = Iterations - 1 #While loops can be stopped with this code :)
x = interact(Schelling,GridSize=(5,100,1), Threshold=(0,1,.05), RedPop = (0,100,5), BluePop = (0,100,5) , Iterations = (0,400,5))#CODE FOR SLIDERS
In [96]:
numpy.savez(Schelling(Grid_Size=50,Threshold=0.5,RedPop=80,BluePop=10,Iterations=150))
In [102]:
numpy.savez(Schelling(Grid_Size=50,Threshold=0.5,RedPop=40,BluePop=40,Iterations=150))
In [98]:
def SchellingQ1(Grid_Size=50,Threshold=0.5,RedPop=50,BluePop=30, PurplePop = 10, GreenPop = 5,Iterations=1):
# How this part should look once we're using the sliders
grid = BlockGrid(Grid_Size,Grid_Size) #Creates grid
if (RedPop + BluePop + GreenPop + PurplePop)> 100:
SchellingQ1(Grid_Size=50,Threshold=0.5,RedPop=50,BluePop=30, PurplePop = 10, GreenPop = 5,Iterations=1)
print ("Values of (red plus blue plus purple plus green) must not exceed 100 %")
else:
for i in range(grid.height):
for j in range(grid.width):
rand_int1 = random.randint(1,100)
if rand_int1 <= BluePop:
grid[i,j] = (0, 0, 255)
elif rand_int1 <= (RedPop + BluePop):
grid[i,j] = (255, 0, 0)
elif rand_int1 <= (RedPop + BluePop + GreenPop):
grid[i,j] = (0, 255, 0)
elif rand_int1 <= (RedPop + BluePop + GreenPop + PurplePop):
grid[i,j] = (255, 0, 255)
elif rand_int1 > (RedPop + BluePop + GreenPop + PurplePop):
grid[i,j] = (0, 0, 0)
grid.show()
while Iterations > 0:
find_movers(grid,Threshold)
Iterations = Iterations - 1
x = interact(SchellingQ1,GridSize=(5,100,5), Threshold=(0,1,.05), RedPop = (0,100,5), BluePop = (0,100,5) , GreenPop = (0,100,5), PurplePop = (0,100,5), Iterations = (0,400,5))
In [75]:
numpy.savez(file = SchellingQ1(Grid_Size=50,Threshold=0.5,RedPop=50,BluePop=30, PurplePop = 10, GreenPop = 5,Iterations=35))
In [84]:
numpy.savez(file = SchellingQ1(Grid_Size=50,Threshold=0.5,RedPop=50,BluePop=30, PurplePop = 10, GreenPop = 5,Iterations=100))
In [85]:
numpy.savez(file = SchellingQ1(Grid_Size=50,Threshold=0.5,RedPop=50,BluePop=30, PurplePop = 10, GreenPop = 5,Iterations=200))
This is actual data taken from the 2010 Census. These pictures were taken from The Cooper Center, using SAS and Python to create the maps/pictures. Here is the link to the website:
http://www.coopercenter.org/demographics/Racial-Dot-Map
I chose Indianapolis, San Luis Obispo, and San Francisco as places of interest. As you can see, each city already shows different races or colors clumping together. I am using this as a part of my presentation to answer the question: Can our use of Python predict how neighborhoods will be created in real life?
Looking at San Franciso, Schelling comes close, but it is clear that the saturation of colors is pretty mixed in the middle of San Francisco. In my Python model for Schelling for more than one race, it shows the clumping of similar ethnicities. In the real world, at least in the United States in densely populated cities where multiple races are found, other variables come into play aside from race preference (e.g. socioeconomic status, schools, highway access, etc.).