Skip to content

Commit

Permalink
Merge 3b96b10 into fb73157
Browse files Browse the repository at this point in the history
  • Loading branch information
cash committed May 9, 2018
2 parents fb73157 + 3b96b10 commit e9cdedc
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 239 deletions.
2 changes: 1 addition & 1 deletion dworp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from .agent import Agent, SelfNamingAgent, TwoStageAgent, IdentifierHelper
from .environment import Environment, NullEnvironment, NetworkEnvironment
from .observer import Observer, ChainedObserver, KeyPauseObserver, PauseObserver
from .observer import Observer, ChainedObserver, KeyPauseObserver, PauseObserver, PauseAtEndObserver
from .scheduling import Scheduler, BasicScheduler, RandomOrderScheduler, RandomSampleScheduler
from .simulation import Simulation, BasicSimulation, TwoStageSimulation
from .space import Grid
Expand Down
23 changes: 22 additions & 1 deletion dworp/observer.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@ class ChainedObserver(Observer):
*observers: Variable length arguments of Observer objects
"""
def __init__(self, *observers):
self.observers = observers
self.observers = list(observers)

def append(self, observer):
self.observers.append(observer)

def start(self, time, agents, env):
for observer in self.observers:
Expand Down Expand Up @@ -122,3 +125,21 @@ def stop(self, agents, env):

def pause(self):
time.sleep(self.delay)


class PauseAtEndObserver(Observer):
"""Pause for x seconds at the end of the simulation
This is useful if you want to keep a plot up on the screen.
Args:
delay (int): Length of delay in seconds
"""
def __init__(self, delay):
self.delay = delay

def step(self, time, agents, env):
pass

def stop(self, agents, env):
time.sleep(self.delay)
75 changes: 46 additions & 29 deletions examples/segregation.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@
import dworp
import dworp.plot
import logging
import matplotlib.colors
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
import sys
try:
import pygame
except ImportError:
# vis will be turned off
pass


class Household(dworp.Agent):
Expand Down Expand Up @@ -112,35 +115,43 @@ def test(self, time, agents, env):
return SegObserver.get_happiness(agents) >= 100


class HeatmapPlotObserver(dworp.Observer):
"""Plot the segregration grid"""
def __init__(self, colors):
self.data = None
self.colors = colors
cmap = matplotlib.colors.ListedColormap([colors[0], "white", colors[1]])
self.options = {
'cmap': cmap, 'cbar': False, 'linewidths': 0.2,
'xticklabels': False, 'yticklabels': False
}
class PyGameRenderer(dworp.Observer):
def __init__(self, size, zoom, fps):
self.zoom = zoom
self.fps = fps
self.width = size[0]
self.height = size[1]

pygame.init()
pygame.display.set_caption("Segregation")
self.screen = pygame.display.set_mode((self.zoom * self.width, self.zoom * self.height))
self.background = pygame.Surface((self.screen.get_size()))
self.background = self.background.convert()
self.clock = pygame.time.Clock()

def start(self, time, agents, env):
self.data = np.zeros(env.grid.data.shape)
plt.ion()
self.plot(env.grid)
self.draw(agents)

def step(self, time, agents, env):
self.plot(env.grid)
self.draw(agents)

def plot(self, grid):
for x in range(self.data.shape[0]):
for y in range(self.data.shape[1]):
if grid.data[x, y] is None:
self.data[x, y] = 0
elif grid.data[x, y].color == self.colors[0]:
self.data[x, y] = -1
else:
self.data[x, y] = 1
sns.heatmap(self.data, **self.options)
def done(self, agents, env):
pygame.quit()

def draw(self, agents):
side = self.zoom - 1
self.background.fill((255, 255, 255))
for agent in agents:
x = self.zoom * agent.x
y = self.zoom * agent.y
color = (255, 128, 0) if agent.color == "orange" else (0, 0, 255)
pygame.draw.rect(self.background, color, (x, y, side, side), 0)
self.screen.blit(self.background, (0, 0))
pygame.display.flip()
self.clock.tick(self.fps)
for event in pygame.event.get():
if event.type == pygame.QUIT:
quit()


class SegregationParams:
Expand Down Expand Up @@ -186,6 +197,9 @@ def __init__(self, params, observer):
parser.add_argument("--similar", help="desired similarity (0-100)", default=30, type=int)
parser.add_argument("--size", help="grid size formatted as XXXxYYY", default="50x50")
parser.add_argument("--seed", help="seed of RNG", default=42, type=int)
parser.add_argument("--fps", help="frames per second", default="2", type=int)
parser.add_argument("--no-vis", dest='vis', action='store_false')
parser.set_defaults(vis=True)
args = parser.parse_args()

# prepare parameters of simulation
Expand All @@ -195,14 +209,17 @@ def __init__(self, params, observer):
similarity = args.similar / float(100)
grid_size = [int(dim) for dim in args.size.split("x")]
seed = args.seed
vis_flag = args.vis and 'pygame' in sys.modules
# vis does not support different colors
colors = ["blue", "orange"]
params = SegregationParams(density, similarity, grid_size, seed, colors)

# create and run one realization of the simulation
observer = dworp.ChainedObserver(
SegObserver(),
HeatmapPlotObserver(colors),
dworp.plot.PlotPauseObserver(delay=1, start=True)
)
if vis_flag:
observer.append(dworp.PauseAtEndObserver(3))
observer.append(PyGameRenderer(grid_size, 10, args.fps))
sim = SegregationSimulation(params, observer)
sim.run()
208 changes: 0 additions & 208 deletions examples/segregation_novis.py

This file was deleted.

Loading

0 comments on commit e9cdedc

Please sign in to comment.