Repository: projectmesa/mesa

Issue:
Add new shapes especially for direction indication in CanvasGrid
Presently Rectangle and Circle shapes are only supported in CanvasGrid. Sometime, there is a requirement of showing the heading (direction s.t. N/S/E/W) of the agent as well.Some more shapes might be introduced for this very purpose. It would be nice to have support of images as well.

Discussion:

Patch:
diff --git a/examples/Basic/Readme.md b/examples/Basic/Readme.md
new file mode 100644
index 00000000..d4ac4b96
--- /dev/null
+++ b/examples/Basic/Readme.md
@@ -0,0 +1,41 @@
+# Basic Grid with two agents
+
+## Summary
+
+A very basic example model to showcase the visulaization on web browser.
+
+A simple grid is dispalyed on browesr with two agents. The example does not
+have any agent motion involved. This example does not have any movenment of
+agents so as to keep it to the simplest of level possible.
+
+This model showcases following features:
+
+* A rectangular grid
+* Text Overlay on the agent's shape on CanvasGrid
+* ArrowHead shaped agent for displaying heading of the agent on CanvasGrid
+
+## Installation
+
+To install the dependencies use pip and the requirements.txt in this directory.
+e.g.
+
+```
+    $ pip install -r requirements.txt
+```
+
+## How to Run
+
+To run the model interactively, run ``run.py`` in this directory. e.g.
+
+```
+    $ python shapes_viz.py
+```
+
+Then open your browser to [http://127.0.0.1:8888/](http://127.0.0.1:8888/) and
+press Reset, then Run.
+
+## Files
+
+* ``basic/model.py: Defines the Basic model and agents.
+* ``basic/server.py``: Sets up the interactive visualization server.
+* ``run.py``: Launches a model visualization server.
diff --git a/examples/Basic/basic/model.py b/examples/Basic/basic/model.py
new file mode 100644
index 00000000..db832772
--- /dev/null
+++ b/examples/Basic/basic/model.py
@@ -0,0 +1,44 @@
+import random
+
+from mesa import Model, Agent
+from mesa.space import SingleGrid
+from mesa.time import RandomActivation
+
+
+class Walker(Agent):
+    def __init__(self, unique_id, pos, heading=(1, 0)):
+        self.unique_id = unique_id
+        self.pos = pos
+        self.heading = heading
+        self.headings = {(1, 0), (0, 1), (-1, 0), (0, -1)}
+
+
+class ShapesModel(Model):
+    def __init__(self, N, width=20, height=10):
+        self.running = True
+        self.N = N    # num of agents
+        self.headings = ((1, 0), (0, 1), (-1, 0), (0, -1))  # tuples are fast
+        self.grid = SingleGrid(width, height, torus=False)
+        self.schedule = RandomActivation(self)
+        self.make_walker_agents()
+
+    def make_walker_agents(self):
+        unique_id = 0
+        while True:
+            if unique_id == self.N:
+                break
+            x = random.randrange(self.grid.width)
+            y = random.randrange(self.grid.height)
+            pos = (x, y)
+            heading = random.choice(self.headings)
+            # heading = (1, 0)
+            if self.grid.is_cell_empty(pos):
+                print("Creating agent {2} at ({0}, {1})"
+                      .format(x, y, unique_id))
+                a = Walker(unique_id, pos, heading)
+                self.schedule.add(a)
+                self.grid.place_agent(a, pos)
+                unique_id += 1
+
+    def step(self):
+        self.schedule.step()
diff --git a/examples/Basic/basic/server.py b/examples/Basic/basic/server.py
new file mode 100644
index 00000000..11df9f62
--- /dev/null
+++ b/examples/Basic/basic/server.py
@@ -0,0 +1,45 @@
+import random
+
+from basic.model import Walker, ShapesModel
+from mesa.visualization.modules import CanvasGrid
+from mesa.visualization.ModularVisualization import ModularServer
+
+
+def agent_draw(agent):
+    portrayal = None
+    if agent is None:
+        # Actually this if part is unnecessary, but still keeping it for
+        # aesthetics
+        pass
+    elif isinstance(agent, Walker):
+        print("Uid: {0}, Heading: {1}".format(agent.unique_id, agent.heading))
+        portrayal = {"Shape": "arrowHead",
+                     "Filled": "true",
+                     "Layer": 2,
+                     "Color": "green",
+                     "Filled": "true",
+                     "heading0": agent.heading[0],
+                     "heading1": agent.heading[1],
+                     "text": agent.unique_id,
+                     "text_color": "white",
+                     "scale": 0.8,
+                     }
+    return portrayal
+
+
+def launch_basic():
+    width = 15
+    height = 10
+    num_agents = 2
+    pixel_ratio = 50
+    grid = CanvasGrid(agent_draw, width, height,
+                      width*pixel_ratio, height*pixel_ratio)
+    server = ModularServer(ShapesModel, [grid], "Basic Example",
+                           num_agents, width, height)
+    server.max_steps = 0
+    server.port = 8888
+    server.launch()
+
+if __name__ == "__main__":
+    random.seed(3)
+    launch_basic()
diff --git a/examples/Basic/requirements.txt b/examples/Basic/requirements.txt
new file mode 100644
index 00000000..da0b5b95
--- /dev/null
+++ b/examples/Basic/requirements.txt
@@ -0,0 +1,1 @@
+mesa
diff --git a/examples/Basic/run.py b/examples/Basic/run.py
new file mode 100644
index 00000000..23edc675
--- /dev/null
+++ b/examples/Basic/run.py
@@ -0,0 +1,3 @@
+from basic.server import launch_basic
+
+launch_basic()
diff --git a/examples/Readme.md b/examples/Readme.md
index 91399dc1..d7a8e056 100644
--- a/examples/Readme.md
+++ b/examples/Readme.md
@@ -2,7 +2,6 @@
 
 This directory contains example models meant to test and demonstrate Mesa's features, and provide demonstrations for how to build and analyze agent-based models. For more information on each model, see its own Readme and documentation.
 
-
 ### Color Patches
 A cellular automaton model where agents opinions are influenced by that of their neighbors. As the model evolves, color patches representing the prevailing opinion in a given area expand, contract, and sometimes disappear.
 
@@ -30,3 +29,6 @@ Completed code to go along with the [tutorial]() on making a simple model of how
 
 ### WolfSheep
 Implementation of an ecological model of predation and reproduction, based on the NetLogo [Wolf Sheep Predation model](http://ccl.northwestern.edu/netlogo/models/WolfSheepPredation).
+
+### Basic
+Example of grid display and direction showing agents in the form of arrow-head shape. 
diff --git a/mesa/__init__.py b/mesa/__init__.py
index 7d35c10d..d370701e 100644
--- a/mesa/__init__.py
+++ b/mesa/__init__.py
@@ -5,57 +5,14 @@ Mesa Agent-Based Modeling Framework
 Core Objects: Model, and Agent.
 
 """
-import datetime as dt
-import random
+
+from .model import Model
+from .agent import Agent
+
+
+__all__ = ["Model", "Agent"]
 
 __title__ = 'mesa'
 __version__ = '0.7.5'
 __license__ = 'Apache 2.0'
 __copyright__ = 'Copyright 2015 Project Mesa Team'
-
-
-class Model:
-    """ Base class for models. """
-    def __init__(self, seed=None):
-        """ Create a new model. Overload this method with the actual code to
-        start the model.
-
-        Args:
-            seed: seed for the random number generator
-
-        Attributes:
-            schedule: schedule object
-            running: a bool indicating if the model should continue running
-
-        """
-        if seed is None:
-            self.seed = dt.datetime.now()
-        else:
-            self.seed = seed
-        random.seed(seed)
-        self.running = True
-        self.schedule = None
-
-    def run_model(self):
-        """ Run the model until the end condition is reached. Overload as
-        needed.
-
-        """
-        while self.running:
-            self.step()
-
-    def step(self):
-        """ A single step. Fill in here. """
-        pass
-
-
-class Agent:
-    """ Base class for a model agent. """
-    def __init__(self, unique_id, model):
-        """ Create a new agent. """
-        self.unique_id = unique_id
-        self.model = model
-
-    def step(self, model):
-        """ A single step of the agent. """
-        pass
diff --git a/mesa/agent.py b/mesa/agent.py
new file mode 100644
index 00000000..caa872be
--- /dev/null
+++ b/mesa/agent.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+"""
+The agent class for Mesa framework.
+
+Core Objects: Agent
+
+"""
+
+
+class Agent:
+    """ Base class for a model agent. """
+    def __init__(self, unique_id, model):
+        """ Create a new agent. """
+        self.unique_id = unique_id
+        self.model = model
+
+    def step(self, model):
+        """ A single step of the agent. """
+        pass
diff --git a/mesa/model.py b/mesa/model.py
new file mode 100644
index 00000000..6e4d4241
--- /dev/null
+++ b/mesa/model.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+"""
+The model class for Mesa framework.
+
+Core Objects: Model
+
+"""
+import datetime as dt
+import random
+
+
+class Model:
+    """ Base class for models. """
+    def __init__(self, seed=None):
+        """ Create a new model. Overload this method with the actual code to
+        start the model.
+
+        Args:
+            seed: seed for the random number generator
+
+        Attributes:
+            schedule: schedule object
+            running: a bool indicating if the model should continue running
+
+        """
+        if seed is None:
+            self.seed = dt.datetime.now()
+        else:
+            self.seed = seed
+        random.seed(seed)
+        self.running = True
+        self.schedule = None
+
+    def run_model(self):
+        """ Run the model until the end condition is reached. Overload as
+        needed.
+
+        """
+        while self.running:
+            self.step()
+
+    def step(self):
+        """ A single step. Fill in here. """
+        pass
diff --git a/mesa/space.py b/mesa/space.py
index 4695b953..4e96a21b 100644
--- a/mesa/space.py
+++ b/mesa/space.py
@@ -41,9 +41,9 @@ def accept_tuple_argument(wrapped_function):
 class Grid:
     """ Base class for a square grid.
 
-    Grid cells are indexed by [y][x], where [0][0] is assumed to be -- top-left
-    and [height-1][width-1] is the bottom-right. If a grid is toroidal, the top
-    and bottom, and left and right, edges wrap to each other
+    Grid cells are indexed by [x][y], where [0][0] is assumed to be the
+    bottom-left and [width-1][height-1] is the top-right. If a grid is
+    toroidal, the top and bottom, and left and right, edges wrap to each other
 
     Properties:
         width, height: The grid's width and height.
@@ -59,21 +59,24 @@ class Grid:
         coord_iter: Returns coordinates as well as cell contents.
         place_agent: Positions an agent on the grid, and set its pos variable.
         move_agent: Moves an agent from its current position to a new position.
-        iter_neighborhood: Returns an iterator over cell coordinates that are in the
-        neighborhood of a certain point.
+        iter_neighborhood: Returns an iterator over cell coordinates that are
+        in the neighborhood of a certain point.
         torus_adj: Converts coordinate, handles torus looping.
-        out_of_bounds: Determines whether position is off the grid, returns the out of bounds coordinate.
-        iter_cell_list_contents: Returns an iterator of the contents of the cells identified in cell_list.
-        get_cell_list_contents: Returns a list of the contents of the cells identified in cell_list.
+        out_of_bounds: Determines whether position is off the grid, returns
+        the out of bounds coordinate.
+        iter_cell_list_contents: Returns an iterator of the contents of the
+        cells identified in cell_list.
+        get_cell_list_contents: Returns a list of the contents of the cells
+        identified in cell_list.
         remove_agent: Removes an agent from the grid.
         is_cell_empty: Returns a bool of the contents of a cell.
 
     """
-    def __init__(self, height, width, torus):
+    def __init__(self, width, height, torus):
         """ Create a new grid.
 
         Args:
-            height, width: The height and width of the grid
+            width, height: The width and height of the grid
             torus: Boolean whether the grid wraps or not.
 
         """
@@ -83,11 +86,11 @@ class Grid:
 
         self.grid = []
 
-        for y in range(self.height):
-            row = []
-            for x in range(self.width):
-                row.append(self.default_val())
-            self.grid.append(row)
+        for x in range(self.width):
+            col = []
+            for y in range(self.height):
+                col.append(self.default_val())
+            self.grid.append(col)
 
     @staticmethod
     def default_val():
@@ -104,9 +107,9 @@ class Grid:
 
     def coord_iter(self):
         """ An iterator that returns coordinates as well as cell contents. """
-        for row in range(self.height):
-            for col in range(self.width):
-                yield self.grid[row][col], col, row  # agent, x, y
+        for row in range(self.width):
+            for col in range(self.height):
+                yield self.grid[row][col], row, col    # agent, x, y
 
     def neighbor_iter(self, pos, moore=True):
         """ Iterate over position neighbors.
@@ -136,10 +139,10 @@ class Grid:
             radius: radius, in cells, of neighborhood to get.
 
         Returns:
-            A list of coordinate tuples representing the neighborhood;
-                With radius 1, at most 9 if
-                Moore, 5 if Von Neumann
-                (8 and 4 if not including the center).
+            A list of coordinate tuples representing the neighborhood. For
+            example with radius 1, it will return list with number of elements
+            equals at most 9 (8) if Moore, 5 (4) if Von Neumann (if not
+            including the center).
 
         """
         x, y = pos
@@ -156,7 +159,7 @@ class Grid:
                     continue
                 # Skip if not a torus and new coords out of bounds.
                 if not self.torus and (not (0 <= dx + x < self.width) or
-                        not (0 <= dy + y < self.height)):
+                                       not (0 <= dy + y < self.height)):
                     continue
 
                 px = self.torus_adj(x + dx, self.width)
@@ -250,7 +253,10 @@ class Grid:
         return coord
 
     def out_of_bounds(self, pos):
-        """ Determines whether position is off the grid, returns the out of bounds coordinate."""
+        """
+        Determines whether position is off the grid, returns the out of
+        bounds coordinate.
+        """
         x, y = pos
         return x < 0 or x >= self.width or y < 0 or y >= self.height
 
@@ -265,7 +271,7 @@ class Grid:
 
         """
         return (
-            self[y][x] for x, y in cell_list if not self.is_cell_empty((x, y)))
+            self[x][y] for x, y in cell_list if not self.is_cell_empty((x, y)))
 
     @accept_tuple_argument
     def get_cell_list_contents(self, cell_list):
@@ -301,32 +307,32 @@ class Grid:
     def _place_agent(self, pos, agent):
         """ Place the agent at the correct location. """
         x, y = pos
-        self.grid[y][x] = agent
+        self.grid[x][y] = agent
 
     def _remove_agent(self, pos, agent):
         """ Remove the agent from the given location. """
         x, y = pos
-        self.grid[y][x] = None
+        self.grid[x][y] = None
 
     def is_cell_empty(self, pos):
         """ Returns a bool of the contents of a cell. """
         x, y = pos
-        return True if self.grid[y][x] == self.default_val() else False
+        return True if self.grid[x][y] == self.default_val() else False
 
 
 class SingleGrid(Grid):
     """ Grid where each cell contains exactly at most one object. """
     empties = []
 
-    def __init__(self, height, width, torus):
+    def __init__(self, width, height, torus):
         """ Create a new single-item grid.
 
         Args:
-            height, width: The height and width of the grid
+            width, height: The width and width of the grid
             torus: Boolean whether the grid wraps or not.
 
         """
-        super().__init__(height, width, torus)
+        super().__init__(width, height, torus)
         # Add all cells to the empties list.
         self.empties = list(itertools.product(
                             *(range(self.width), range(self.height))))
@@ -388,9 +394,9 @@ class SingleGrid(Grid):
 class MultiGrid(Grid):
     """ Grid where each cell can contain more than one object.
 
-    Grid cells are indexed by [y][x], where [0][0] is assumed to be -- top-left
-    and [height-1][width-1] is the bottom-right. If a grid is toroidal, the top
-    and bottom, and left and right, edges wrap to each other.
+    Grid cells are indexed by [x][y], where [0][0] is assumed to be at
+    bottom-left and [width-1][height-1] is the top-right. If a grid is
+    toroidal, the top and bottom, and left and right, edges wrap to each other.
 
     Each grid cell holds a set object.
 
@@ -412,12 +418,12 @@ class MultiGrid(Grid):
     def _place_agent(self, pos, agent):
         """ Place the agent at the correct location. """
         x, y = pos
-        self.grid[y][x].add(agent)
+        self.grid[x][y].add(agent)
 
     def _remove_agent(self, pos, agent):
         """ Remove the agent from the given location. """
         x, y = pos
-        self.grid[y][x].remove(agent)
+        self.grid[x][y].remove(agent)
 
     @accept_tuple_argument
     def iter_cell_list_contents(self, cell_list):
@@ -430,7 +436,7 @@ class MultiGrid(Grid):
 
         """
         return itertools.chain.from_iterable(
-            self[y][x] for x, y in cell_list if not self.is_cell_empty((x, y)))
+            self[x][y] for x, y in cell_list if not self.is_cell_empty((x, y)))
 
 
 class ContinuousSpace:
@@ -471,7 +477,7 @@ class ContinuousSpace:
         self.cell_width = (self.x_max - self.x_min) / grid_width
         self.cell_height = (self.y_max - self.y_min) / grid_height
 
-        self._grid = MultiGrid(grid_height, grid_width, torus)
+        self._grid = MultiGrid(grid_width, grid_height, torus)
 
     def place_agent(self, agent, pos):
         """ Place a new agent in the space.
@@ -525,7 +531,7 @@ class ContinuousSpace:
         cell_radius = math.ceil(radius / scale)
         cell_pos = self._point_to_cell(pos)
         possible_objs = self._grid.get_neighbors(cell_pos,
-                                              True, True, cell_radius)
+                                                 True, True, cell_radius)
         neighbors = []
         # Iterate over candidates and check actual distance.
         for obj in possible_objs:
diff --git a/mesa/time.py b/mesa/time.py
index ab510fae..23c354b8 100644
--- a/mesa/time.py
+++ b/mesa/time.py
@@ -142,7 +142,7 @@ class StagedActivation(BaseScheduler):
     stage_time = 1
 
     def __init__(self, model, stage_list=["step"], shuffle=False,
-            shuffle_between_stages=False):
+                 shuffle_between_stages=False):
         """ Create an empty Staged Activation schedule.
 
         Args:
diff --git a/mesa/visualization/ModularVisualization.md b/mesa/visualization/ModularVisualization.md
index 23f1ebe9..f0623ba6 100644
--- a/mesa/visualization/ModularVisualization.md
+++ b/mesa/visualization/ModularVisualization.md
@@ -28,15 +28,21 @@ Mesa already comes with some pre-built modules. Using the built-ins allow you to
 One built-in module is **CanvasGrid**, which you can use to visualize objects located on grid cells. The CanvasGrid will cover a majority of agent-based models, particularly the simpler ones.
 
 CanvasGrid iterates over every object in every cell of your model's grid (it assumes that your model has a grid named **grid**) and converts it into a dictionary which defines how it will be drawn. It does this via a **portrayal_method**: a function which the user defines, which takes an object as an input and outputs a dictionary with the following keys:
-    "Shape": Can be either "circle" or "rect"
+    "Shape": Can be "circle", "rect" or "arrowHead"
         For Circles:
             "r": The radius, defined as a fraction of cell size. r=1 will fill the entire cell.
         For rectangles:
             "w", "h": The width and height of the rectangle, which are in fractions of cell width and height.
+        For arrowHead:
+            "scale": Proportion scaling as a fraction of cell size. shape=0.5 will fit the arrowHead into half of the cell.
+            "heading0": represents x direction unit vector.
+            "heading1": represents y direction unit vector.
     "Color": The color to draw the shape in; needs to be a valid HTML color, e.g."Red" or "#AA08F8"
     "Filled": either "true" or "false", and determines whether the shape is filled or not.
     "Layer": Layer number of 0 or above; higher-numbered layers are drawn above lower-numbered layers.
-    (Shapes also have "x" and "x" coordinates, for the x and y of the grid cell in which it is, but CanvasGrid adds those automatically).
+    "text": Text to overlay on top of the shape. Normally, agent's unique_id is used .
+    "text_color": Color of the text overlay.
+    (Shapes also have "x" and "y" coordinates, for the x and y of the grid cell in which it is, but CanvasGrid adds those automatically).
 
 For example, suppose for a Schelling model, we want to draw all agents as circles; red ones for the majority (agent type=0), and blue ones for the minority (agent type=1). The function to do this might look like this:
 
@@ -150,6 +156,3 @@ Data to visualize arrive over the websocket as a list. For each index of the lis
 Currently, module JavaScript files live in the *mesa/visualization/templates* directory, and the Python files live in *mesa/visualization/modules*.
 
 When creating a new module, the Python and JavaScript code need to be written in synch: the module Python-side **render** method needs to output data in the exact same format that the JavaScript **render** function receives as an input.
-
-
-
diff --git a/mesa/visualization/modules/CanvasGridVisualization.py b/mesa/visualization/modules/CanvasGridVisualization.py
index 450c3b39..5f0a70fc 100644
--- a/mesa/visualization/modules/CanvasGridVisualization.py
+++ b/mesa/visualization/modules/CanvasGridVisualization.py
@@ -52,26 +52,26 @@ class CanvasGrid(VisualizationElement):
     """
     package_includes = ["GridDraw.js", "CanvasModule.js"]
     portrayal_method = None  # Portrayal function
-    canvas_height = 500
     canvas_width = 500
+    canvas_height = 500
 
-    def __init__(self, portrayal_method, grid_height, grid_width,
-                 canvas_height=500, canvas_width=500):
+    def __init__(self, portrayal_method, grid_width, grid_height,
+                 canvas_width=500, canvas_height=500):
         """ Instantiate a new CanvasGrid.
 
         Args:
             portrayal_method: function to convert each object on the grid to
                               a portrayal, as described above.
-            grid_height, grid_width: Size of the grid, in cells.
+            grid_width, grid_height: Size of the grid, in cells.
             canvas_height, canvas_width: Size of the canvas to draw in the
                                          client, in pixels. (default: 500x500)
 
         """
         self.portrayal_method = portrayal_method
-        self.grid_height = grid_height
         self.grid_width = grid_width
-        self.canvas_height = canvas_height
+        self.grid_height = grid_height
         self.canvas_width = canvas_width
+        self.canvas_height = canvas_height
 
         new_element = ("new CanvasModule({}, {}, {}, {})"
             .format(self.canvas_width, self.canvas_height,
@@ -81,8 +81,8 @@ class CanvasGrid(VisualizationElement):
 
     def render(self, model):
         grid_state = defaultdict(list)
-        for y in range(model.grid.height):
-            for x in range(model.grid.width):
+        for x in range(model.grid.width):
+            for y in range(model.grid.height):
                 cell_objects = model.grid.get_cell_list_contents([(x, y)])
                 for obj in cell_objects:
                     portrayal = self.portrayal_method(obj)
diff --git a/mesa/visualization/templates/CanvasModule.js b/mesa/visualization/templates/CanvasModule.js
index 43e537b8..4861c3e3 100644
--- a/mesa/visualization/templates/CanvasModule.js
+++ b/mesa/visualization/templates/CanvasModule.js
@@ -11,7 +11,7 @@ var CanvasModule = function(canvas_width, canvas_height, grid_width, grid_height
 
 	// Create the context and the drawing controller:
 	var context = canvas.getContext("2d");
-	var canvasDraw = new GridVisualization(canvas_width, canvas_height, grid_height, grid_width, context);
+	var canvasDraw = new GridVisualization(canvas_width, canvas_height, grid_width, grid_height, context);
 
 	this.render = function(data) {
 		canvasDraw.resetCanvas();
@@ -24,4 +24,4 @@ var CanvasModule = function(canvas_width, canvas_height, grid_width, grid_height
 		canvasDraw.resetCanvas();
 	};
 
-};
\ No newline at end of file
+};
diff --git a/mesa/visualization/templates/GridDraw.js b/mesa/visualization/templates/GridDraw.js
index a195c6b5..3ffd5cd3 100644
--- a/mesa/visualization/templates/GridDraw.js
+++ b/mesa/visualization/templates/GridDraw.js
@@ -1,77 +1,82 @@
-/*
+/**
 Mesa Canvas Grid Visualization
 ====================================================================
 
-This is JavaScript code to visualize a Mesa Grid or MultiGrid state using the 
+This is JavaScript code to visualize a Mesa Grid or MultiGrid state using the
 HTML5 Canvas. Here's how it works:
 
 On the server side, the model developer will have assigned a portrayal to each
 agent type. The visualization then loops through the grid, for each object adds
-a JSON object to an inner list (keyed on layer) of lists to be sent to the browser. 
+a JSON object to an inner list (keyed on layer) of lists to be sent to the
+browser.
 
-Each JSON object to be drawn contains the following fields: Shape (currently 
-only rectanges and circles are supported), x, y, Color, Filled (boolean), Layer; 
-circles also get a Radius, while rectangles get x and y sizes. The latter values
-are all between [0, 1] and get scaled to the grid cell.
+Each JSON object to be drawn contains the following fields: Shape (currently
+only rectanges and circles are supported), x, y, Color, Filled (boolean),
+Layer; circles also get a Radius, while rectangles get x and y sizes. The
+latter values are all between [0, 1] and get scaled to the grid cell.
 
-The browser (this code, in fact) then iteratively draws them in, one layer at a time. Thus, it 
-should be possible to turn different layers on and off. 
+The browser (this code, in fact) then iteratively draws them in, one layer at a
+time. Thus, it should be possible to turn different layers on and off.
 
-Here's a sample input, for a 2x2 grid with one layer being cell colors and the other agent 
-locations, represented by circles:
+Here's a sample input, for a 2x2 grid with one layer being cell colors and the
+other agent locations, represented by circles:
 
 {"Shape": "rect", "x": 0, "y": 0, "Color": "#00aa00", "Filled": "true", "Layer": 0}
 
-{0:[{"Shape": "rect", "x": 0, "y": 0, "w": 1, "h": 1, "Color": "#00aa00", "Filled": "true", "Layer": 0},
-	{"Shape": "rect", "x": 0, "y": 0, "w": 1, "h": 1, "Color": "#00aa00", "Filled": "true", "Layer": 0},
-	{"Shape": "rect", "x": 0, "y": 0, "w": 1, "h": 1, "Color": "#00aa00", "Filled": "true", "Layer": 0},
-	{"Shape": "rect", "x": 0, "y": 0, "w": 1, "h": 1, "Color": "#00aa00", "Filled": "true", "Layer": 0} 
+{0:[
+        {"Shape": "rect", "x": 0, "y": 0, "w": 1, "h": 1, "Color": "#00aa00", "Filled": "true", "Layer": 0},
+	{"Shape": "rect", "x": 0, "y": 1, "w": 1, "h": 1, "Color": "#00aa00", "Filled": "true", "Layer": 0},
+	{"Shape": "rect", "x": 1, "y": 0, "w": 1, "h": 1, "Color": "#00aa00", "Filled": "true", "Layer": 0},
+	{"Shape": "rect", "x": 1, "y": 1, "w": 1, "h": 1, "Color": "#00aa00", "Filled": "true", "Layer": 0}
    ],
- 1: [
+ 1:[
 	{"Shape": "circle", "x": 0, "y": 0, "r": 0.5, "Color": "#AAAAAA", "Filled": "true", "Layer": 1, "text": 'A', "text_color": "white"},
 	{"Shape": "circle", "x": 1, "y": 1, "r": 0.5, "Color": "#AAAAAA", "Filled": "true", "Layer": 1, "text": 'B', "text_color": "white"}
+	{"Shape": "arrowHead", "x": 1, "y": 0, "heading0": -1, heading1: 0, "scale": 0.5, "Color": "green", "Filled": "true", "Layer": 1, "text": 'C', "text_color": "white"}
    ]
 }
 
 */
 
-var GridVisualization = function(height, width, gridHeight, gridWidth, context) {
-	var height = height;
+var GridVisualization = function(width, height, gridWidth, gridHeight, context) {
 	var width = width;
-	var gridHeight = gridHeight;
+	var height = height;
 	var gridWidth = gridWidth;
+	var gridHeight = gridHeight;
 	var context = context;
 
 	// Find cell size:
-	var cellHeight = Math.floor(height / gridHeight);
 	var cellWidth = Math.floor(width / gridWidth);
+	var cellHeight = Math.floor(height / gridHeight);
 
+        // Find max radius of the circle that can be inscribed (fit) into the
+        // cell of the grid.
 	var maxR = Math.min(cellHeight, cellWidth)/2 - 1;
 
-
-	this.drawLayer = function(portrayalLayer) {
+	// Calls the appropriate shape(agent)
+        this.drawLayer = function(portrayalLayer) {
 		for (var i in portrayalLayer) {
 			var p = portrayalLayer[i];
 			if (p.Shape == "rect")
-				this.drawRectange(p.x, p.y, p.w, p.h, p.Color, p.Filled, p.text, p.text_color);
-			if (p.Shape == "circle")
+				this.drawRectangle(p.x, p.y, p.w, p.h, p.Color, p.Filled, p.text, p.text_color);
+			else if (p.Shape == "circle")
 				this.drawCircle(p.x, p.y, p.r, p.Color, p.Filled, p.text, p.text_color);
+                        else if (p.Shape == "arrowHead")
+				this.drawArrowHead(p.x, p.y, p.heading0, p.heading1, p.scale, p.Color, p.Filled, p.text, p.text_color);
 		}
 	};
 
+	// DRAWING METHODS
+	// =====================================================================
 
-
-	//   DRAWING METHODS
-	//  =====================================================================
-	
 	/**
-		Draw a circle in the specified grid cell.
-		x, y: Grid coords
-		r: Radius, as a multiple of cell size
-		color: Code for the fill color
-		fill: Boolean for whether or not to fill the circle.
-                text: Inscribed text in rectangle.
-                text_color: Color of the inscribed text.
+	Draw a circle in the specified grid cell.
+	x, y: Grid coords
+	r: Radius, as a multiple of cell size
+	color: Code for the fill color
+	fill: Boolean for whether or not to fill the circle.
+        text: Inscribed text in rectangle.
+        text_color: Color of the inscribed text.
         */
 	this.drawCircle = function(x, y, radius, color, fill, text, text_color) {
 		var cx = (x + 0.5) * cellWidth;
@@ -89,7 +94,7 @@ var GridVisualization = function(height, width, gridHeight, gridWidth, context)
 			context.fillStyle = color;
 			context.fill();
 		}
-                
+
                 // This part draws the text inside the Circle
                 if (text !== undefined) {
                         context.fillStyle = text_color;
@@ -101,15 +106,16 @@ var GridVisualization = function(height, width, gridHeight, gridWidth, context)
 	};
 
 	/**
-		Draw a rectangle in the specified grid cell.
-		x, y: Grid coords
-		w, h: Width and height, [0, 1]
-		color: Color for the rectangle
-		fill: Boolean, whether to fill or not.
-                text: Inscribed text in rectangle.
-                text_color: Color of the inscribed text.
+	Draw a rectangle in the specified grid cell.
+	x, y: Grid coords
+	w, h: Width and height, [0, 1]
+	color: Color for the rectangle
+	fill: Boolean, whether to fill or not.
+        text: Inscribed text in rectangle.
+        text_color: Color of the inscribed text.
 	*/
-	this.drawRectange = function(x, y, w, h, color, fill, text, text_color) {
+	this.drawRectangle = function(x, y, w, h, color, fill, text, text_color) {
+		y = gridHeight - y - 1;
 		context.beginPath();
 		var dx = w * cellWidth;
 		var dy = h * cellHeight;
@@ -136,8 +142,89 @@ var GridVisualization = function(height, width, gridHeight, gridWidth, context)
                 }
 	};
 
+        /**
+	Draw an arrow head in the specified grid cell.
+	x, y: Grid coords
+	s: Scaling of the arrowHead with respect to cell size[0, 1]
+	color: Color for the shape
+	fill: Boolean, whether to fill or not.
+        text: Inscribed text in shape.
+        text_color: Color of the inscribed text.
+	*/
+        this.drawArrowHead = function(x, y, heading0, heading1, scale, color, fill, text, text_color) {
+                y = gridHeight - y -1;
+                arrowR = maxR * scale;
+		var cx = (x + 0.5) * cellWidth;
+		var cy = (y + 0.5) * cellHeight;
+                if (heading0 === 0 && heading1 === 1) {
+                        p1_x = cx;
+                        p1_y = cy - arrowR;
+                        p2_x = cx - arrowR;
+                        p2_y = cy + arrowR;
+                        p3_x = cx;
+                        p3_y = cy + 0.8*arrowR;
+                        p4_x = cx + arrowR;
+                        p4_y = cy + arrowR;
+                }
+                else if (heading0 === 1 && heading1 === 0) {
+                        p1_x = cx + arrowR;
+                        p1_y = cy;
+                        p2_x = cx - arrowR;
+                        p2_y = cy - arrowR;
+                        p3_x = cx - 0.8*arrowR;
+                        p3_y = cy;
+                        p4_x = cx - arrowR;
+                        p4_y = cy + arrowR;
+                }
+                else if (heading0 === 0 && heading1 === (-1)) {
+                        p1_x = cx;
+                        p1_y = cy + arrowR;
+                        p2_x = cx - arrowR;
+                        p2_y = cy - arrowR;
+                        p3_x = cx;
+                        p3_y = cy - 0.8*arrowR;
+                        p4_x = cx + arrowR;
+                        p4_y = cy - arrowR;
+                }
+                else if (heading0 === (-1) && heading1 === 0) {
+                        p1_x = cx - arrowR;
+                        p1_y = cy;
+                        p2_x = cx + arrowR;
+                        p2_y = cy - arrowR;
+                        p3_x = cx + 0.8*arrowR;
+                        p3_y = cy;
+                        p4_x = cx + arrowR;
+                        p4_y = cy + arrowR;
+                }
+
+		context.beginPath();
+                context.moveTo(p1_x, p1_y);
+                context.lineTo(p2_x, p2_y);
+                context.lineTo(p3_x, p3_y);
+                context.lineTo(p4_x, p4_y);
+		context.closePath();
+
+		context.strokeStyle = color;
+		context.stroke();
+
+		if (fill) {
+			context.fillStyle = color;
+			context.fill();
+		}
+
+                // This part draws the text inside the ArrowHead
+                if (text !== undefined) {
+        		var cx = (x + 0.5) * cellWidth;
+                  	var cy = (y + 0.5) * cellHeight;
+                        context.fillStyle = text_color
+                        context.textAlign = 'center';
+                        context.textBaseline= 'middle';
+                        context.fillText(text, cx, cy);
+                }
+        };
+
 	/**
-		Draw Grid lines in the full gird
+        Draw Grid lines in the full gird
         */
 
 	this.drawGridLines = function() {
@@ -161,7 +248,7 @@ var GridVisualization = function(height, width, gridHeight, gridWidth, context)
 	};
 
 	this.resetCanvas = function() {
-		context.clearRect(0, 0, height, width);
+		context.clearRect(0, 0, width, height);
 		context.beginPath();
 	};
 


Test patch:
diff --git a/tests/test_batchrunner.py b/tests/test_batchrunner.py
index fb917fea..a900f6f4 100644
--- a/tests/test_batchrunner.py
+++ b/tests/test_batchrunner.py
@@ -61,7 +61,7 @@ class TestBatchRunner(unittest.TestCase):
         self.params = {
             'model_param': range(3),
             'agent_param': [1, 8],
-            }
+        }
         self.iterations = 17
         self.batch = BatchRunner(
             MockModel,
diff --git a/tests/test_grid.py b/tests/test_grid.py
index 20f9806f..e2fd7f27 100644
--- a/tests/test_grid.py
+++ b/tests/test_grid.py
@@ -6,10 +6,19 @@ import unittest
 from mesa.space import Grid, SingleGrid, MultiGrid
 
 # Initial agent positions for testing
-#              X ---- >
-TEST_GRID = [[0, 1, 0, 1, 0],   # Y
-             [0, 1, 1, 0, 0],   # |
-             [0, 0, 0, 1, 0]]   # V
+#
+# --- visual aid ----
+#   0 0 0
+#   1 1 0
+#   0 1 0
+#   1 0 1
+#   0 0 1
+# -------------------
+TEST_GRID = [
+    [0, 1, 0, 1, 0],
+    [0, 0, 1, 1, 0],
+    [1, 1, 0, 0, 0]
+]
 
 
 class MockAgent:
@@ -32,12 +41,14 @@ class TestBaseGrid(unittest.TestCase):
         '''
         Create a test non-toroidal grid and populate it with Mock Agents
         '''
-        self.grid = Grid(3, 5, self.torus)
+        width = 3    # width of grid
+        height = 5    # height of grid
+        self.grid = Grid(width, height, self.torus)
         self.agents = []
         counter = 0
-        for y in range(3):
-            for x in range(5):
-                if TEST_GRID[y][x] == 0:
+        for x in range(width):
+            for y in range(height):
+                if TEST_GRID[x][y] == 0:
                     continue
                 counter += 1
                 # Create and place the mock agent
@@ -51,7 +62,7 @@ class TestBaseGrid(unittest.TestCase):
         '''
         for agent in self.agents:
             x, y = agent.pos
-            assert self.grid[y][x] == agent
+            assert self.grid[x][y] == agent
 
     def test_cell_agent_reporting(self):
         '''
@@ -98,7 +109,10 @@ class TestBaseGrid(unittest.TestCase):
         neighborhood = self.grid.get_neighborhood((1, 1), moore=True)
         assert len(neighborhood) == 8
 
-        neighborhood = self.grid.get_neighborhood((4, 1), moore=True)
+        neighborhood = self.grid.get_neighborhood((1, 4), moore=False)
+        assert len(neighborhood) == 3
+
+        neighborhood = self.grid.get_neighborhood((1, 4), moore=True)
         assert len(neighborhood) == 5
 
         neighborhood = self.grid.get_neighborhood((0, 0), moore=False)
@@ -108,14 +122,14 @@ class TestBaseGrid(unittest.TestCase):
         assert len(neighbors) == 0
 
         neighbors = self.grid.get_neighbors((4, 1), moore=True)
-        assert len(neighbors) == 2
+        assert len(neighbors) == 0
 
         neighbors = self.grid.get_neighbors((1, 1), moore=False,
                                             include_center=True)
         assert len(neighbors) == 3
 
-        neighbors = self.grid.get_neighbors((3, 1), moore=False, radius=2)
-        assert len(neighbors) == 4
+        neighbors = self.grid.get_neighbors((1, 3), moore=False, radius=2)
+        assert len(neighbors) == 2
 
     def test_coord_iter(self):
         ci = self.grid.coord_iter()
@@ -129,9 +143,9 @@ class TestBaseGrid(unittest.TestCase):
         # first agent in the second space
         second = next(ci)
         assert second[0].unique_id == 1
-        assert second[0].pos == (1, 0)
-        assert second[1] == 1
-        assert second[2] == 0
+        assert second[0].pos == (0, 1)
+        assert second[1] == 0
+        assert second[2] == 1
 
 
 class TestBaseGridTorus(TestBaseGrid):
@@ -149,24 +163,24 @@ class TestBaseGridTorus(TestBaseGrid):
         neighborhood = self.grid.get_neighborhood((1, 1), moore=True)
         assert len(neighborhood) == 8
 
-        neighborhood = self.grid.get_neighborhood((4, 1), moore=True)
+        neighborhood = self.grid.get_neighborhood((1, 4), moore=True)
         assert len(neighborhood) == 8
 
         neighborhood = self.grid.get_neighborhood((0, 0), moore=False)
         assert len(neighborhood) == 4
 
-        neighbors = self.grid.get_neighbors((4, 1), moore=False)
-        assert len(neighbors) == 0
+        neighbors = self.grid.get_neighbors((1, 4), moore=False)
+        assert len(neighbors) == 1
 
-        neighbors = self.grid.get_neighbors((4, 1), moore=True)
-        assert len(neighbors) == 2
+        neighbors = self.grid.get_neighbors((1, 4), moore=True)
+        assert len(neighbors) == 3
 
         neighbors = self.grid.get_neighbors((1, 1), moore=False,
                                             include_center=True)
         assert len(neighbors) == 3
 
-        neighbors = self.grid.get_neighbors((3, 1), moore=False, radius=2)
-        assert len(neighbors) == 4
+        neighbors = self.grid.get_neighbors((1, 3), moore=False, radius=2)
+        assert len(neighbors) == 2
 
 
 class TestSingleGrid(unittest.TestCase):
@@ -181,12 +195,14 @@ class TestSingleGrid(unittest.TestCase):
         '''
         Create a test non-toroidal grid and populate it with Mock Agents
         '''
-        self.grid = SingleGrid(3, 5, True)
+        width = 3
+        height = 5
+        self.grid = SingleGrid(width, height, True)
         self.agents = []
         counter = 0
-        for y in range(3):
-            for x in range(5):
-                if TEST_GRID[y][x] == 0:
+        for x in range(width):
+            for y in range(height):
+                if TEST_GRID[x][y] == 0:
                     continue
                 counter += 1
                 # Create and place the mock agent
@@ -199,21 +215,23 @@ class TestSingleGrid(unittest.TestCase):
         Test the SingleGrid empty count and enforcement.
         '''
 
-        assert len(self.grid.empties) == 10
+        assert len(self.grid.empties) == 9
         a = MockAgent(100, None)
         with self.assertRaises(Exception):
-            self.grid._place_agent((1, 0), a)
+            self.grid._place_agent((0, 1), a)
 
         # Place the agent in an empty cell
         self.grid.position_agent(a)
+        # Test whether after placing, the empty cells are reduced by 1
         assert a.pos not in self.grid.empties
-        assert len(self.grid.empties) == 9
+        assert len(self.grid.empties) == 8
         for i in range(10):
             self.grid.move_to_empty(a)
-        assert len(self.grid.empties) == 9
+        assert len(self.grid.empties) == 8
 
         # Place agents until the grid is full
-        for i in range(9):
+        empty_cells = len(self.grid.empties)
+        for i in range(empty_cells):
             a = MockAgent(101 + i, None)
             self.grid.position_agent(a)
         assert len(self.grid.empties) == 0
@@ -224,7 +242,17 @@ class TestSingleGrid(unittest.TestCase):
         with self.assertRaises(Exception):
             self.move_to_empty(self.agents[0])
 
+
 # Number of agents at each position for testing
+# Initial agent positions for testing
+#
+# --- visual aid ----
+#   0 0 0
+#   2 0 3
+#   0 5 0
+#   1 1 0
+#   0 0 0
+# -------------------
 TEST_MULTIGRID = [[0, 1, 0, 2, 0],
                   [0, 1, 5, 0, 0],
                   [0, 0, 0, 3, 0]]
@@ -241,12 +269,14 @@ class TestMultiGrid(unittest.TestCase):
         '''
         Create a test non-toroidal grid and populate it with Mock Agents
         '''
-        self.grid = MultiGrid(3, 5, self.torus)
+        width = 3
+        height = 5
+        self.grid = MultiGrid(width, height, self.torus)
         self.agents = []
         counter = 0
-        for y in range(3):
-            for x in range(5):
-                for i in range(TEST_MULTIGRID[y][x]):
+        for x in range(width):
+            for y in range(height):
+                for i in range(TEST_MULTIGRID[x][y]):
                     counter += 1
                     # Create and place the mock agent
                     a = MockAgent(counter, None)
@@ -259,7 +289,7 @@ class TestMultiGrid(unittest.TestCase):
         '''
         for agent in self.agents:
             x, y = agent.pos
-            assert agent in self.grid[y][x]
+            assert agent in self.grid[x][y]
 
     def test_neighbors(self):
         '''
@@ -269,21 +299,21 @@ class TestMultiGrid(unittest.TestCase):
         neighborhood = self.grid.get_neighborhood((1, 1), moore=True)
         assert len(neighborhood) == 8
 
-        neighborhood = self.grid.get_neighborhood((4, 1), moore=True)
+        neighborhood = self.grid.get_neighborhood((1, 4), moore=True)
         assert len(neighborhood) == 8
 
         neighborhood = self.grid.get_neighborhood((0, 0), moore=False)
         assert len(neighborhood) == 4
 
-        neighbors = self.grid.get_neighbors((4, 1), moore=False)
+        neighbors = self.grid.get_neighbors((1, 4), moore=False)
         assert len(neighbors) == 0
 
-        neighbors = self.grid.get_neighbors((4, 1), moore=True)
+        neighbors = self.grid.get_neighbors((1, 4), moore=True)
         assert len(neighbors) == 5
 
         neighbors = self.grid.get_neighbors((1, 1), moore=False,
                                             include_center=True)
         assert len(neighbors) == 7
 
-        neighbors = self.grid.get_neighbors((3, 1), moore=False, radius=2)
+        neighbors = self.grid.get_neighbors((1, 3), moore=False, radius=2)
         assert len(neighbors) == 11
diff --git a/tests/test_time.py b/tests/test_time.py
index 7c3164f9..81fae185 100644
--- a/tests/test_time.py
+++ b/tests/test_time.py
@@ -5,7 +5,8 @@ Test the advanced schedulers.
 from unittest import TestCase
 from unittest.mock import patch
 from mesa import Model, Agent
-from mesa.time import BaseScheduler, StagedActivation, RandomActivation, SimultaneousActivation
+from mesa.time import (BaseScheduler, StagedActivation, RandomActivation,
+                       SimultaneousActivation)
 
 RANDOM = 'random'
 STAGED = 'staged'
@@ -37,13 +38,14 @@ class MockModel(Model):
         Creates a Model instance with a schedule
 
         Args:
-            shuffle (Bool): whether or not to instantiate a scheduler with
-                            shuffling.
-                            This option is only used for StagedActivation schedulers.
+            shuffle (Bool): whether or not to instantiate a scheduler
+                            with shuffling.
+                            This option is only used for
+                            StagedActivation schedulers.
 
             activation (str): which kind of scheduler to use.
-                              'random' will create a RandomActivation scheduler.
-                              'staged' will create a StagedActivation scheduler.
+                              'random' creates a RandomActivation scheduler.
+                              'staged' creates a StagedActivation scheduler.
                               The default scheduler is a BaseScheduler.
         '''
         self.log = []
@@ -51,7 +53,8 @@ class MockModel(Model):
         # Make scheduler
         if activation == STAGED:
             model_stages = ["stage_one", "stage_two"]
-            self.schedule = StagedActivation(self, model_stages, shuffle=shuffle)
+            self.schedule = StagedActivation(self, model_stages,
+                                             shuffle=shuffle)
         elif activation == RANDOM:
             self.schedule = RandomActivation(self)
         elif activation == SIMULTANEOUS: