[pysal] 01/06: Imported Upstream version 1.13.0

Bas Couwenberg sebastic at debian.org
Fri Dec 9 18:34:14 UTC 2016


This is an automated email from the git hooks/post-receive script.

sebastic pushed a commit to branch master
in repository pysal.

commit 0b051ebdefdd04dee0cd67f9b9aa7025106a106c
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Fri Dec 9 19:04:47 2016 +0100

    Imported Upstream version 1.13.0
---
 .gitignore                                         |    5 +
 .travis.yml                                        |   10 +-
 CHANGELOG.txt                                      |   50 +
 MANIFEST.in                                        |    2 +-
 README.rst                                         |    8 +-
 THANKS.txt                                         |    5 +
 doc/source/conf.py                                 |   20 +-
 doc/source/developers/docs/index.rst               |    4 +
 doc/source/developers/guidelines.rst               |   37 +-
 doc/source/developers/release.rst                  |    2 +-
 doc/source/index.rst                               |    2 +-
 doc/source/users/installation.rst                  |   14 +-
 pysal/contrib/README.rst                           |    6 +-
 pysal/contrib/spint/count_model.py                 |    4 +-
 pysal/contrib/spint/gravity.py                     |  108 +-
 .../Example_NYCBikes_AllFeatures.ipynb             |   23 +-
 pysal/contrib/spint/notebooks/Gaussian_SAR.ipynb   |  791 ----
 pysal/contrib/spint/notebooks/IV_FLOWS.ipynb       |  195 -
 .../contrib/spint/notebooks/New_DistanceBand.ipynb |   12 +
 pysal/contrib/spint/notebooks/Vec_SA_Test.ipynb    |  389 --
 .../contrib/spint/notebooks/validate_gravity.ipynb |  862 +----
 pysal/contrib/spint/primer/SpIntPrimer.pdf         |  Bin 0 -> 302366 bytes
 pysal/contrib/spint/primer/austria.csv             |   82 +
 pysal/contrib/spint/primer/austria.dbf             |  Bin 0 -> 1175 bytes
 pysal/contrib/spint/primer/austria.prj             |    1 +
 pysal/contrib/spint/primer/austria.qpj             |    1 +
 pysal/contrib/spint/primer/austria.shp             |  Bin 0 -> 63112 bytes
 pysal/contrib/spint/primer/austria.shx             |  Bin 0 -> 172 bytes
 pysal/contrib/spint/tests/test_count_model.py      |    2 +-
 pysal/contrib/spint/tests/test_gravity.py          |  607 +--
 pysal/contrib/viz/Makefile                         |    2 +
 pysal/contrib/viz/color.py                         |   77 +
 pysal/contrib/viz/color_picker.ipynb               | 3988 ++++++++++++++++++++
 pysal/contrib/viz/geotable_plot.ipynb              | 3400 +++++++++++++++++
 pysal/contrib/viz/mapping.py                       |  398 +-
 pysal/contrib/viz/mapping_guide.ipynb              |    2 +-
 pysal/esda/mapclassify.py                          |   12 +-
 pysal/version.py                                   |    4 +-
 pysal/weights/weights.py                           |   29 +-
 requirements.txt                                   |    1 +
 travis.txt => requirements_dev.txt                 |    3 +-
 requirements_plus.txt                              |    1 -
 setup.py                                           |   27 +-
 43 files changed, 8535 insertions(+), 2651 deletions(-)

diff --git a/.gitignore b/.gitignore
index 6607001..3c39920 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,6 +20,10 @@ lib
 lib64
 __pycache__
 
+
+# virtual environment
+venv/
+
 # Installer logs
 pip-log.txt
 
@@ -101,3 +105,4 @@ pysal/examples/snow_maps/soho_graph.prj
 pysal/examples/snow_maps/soho_graph.qpj
 pysal/examples/snow_maps/soho_graph.shp
 pysal/examples/snow_maps/soho_graph.shx
+
diff --git a/.travis.yml b/.travis.yml
index cc68bc0..3dadf8b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -24,17 +24,17 @@ before_install:
   - if [[ $TRAVIS_PYTHON_VERSION == 3* ]]; then 2to3 -nw pysal/ > /dev/null; fi
 
 install:
-  - conda install --yes numpy scipy nose pip
+  - conda install --yes pip
   - if [ "$PYSAL_PLUS" == true ]; then
         echo 'plus testing'; conda install --yes --file requirements_plus.txt;
-        else conda install --yes --file requirements.txt; 
+        else conda install --yes --file requirements.txt;
     fi;
-  - pip install -r travis.txt
+  - pip install -r requirements_dev.txt
 
-script: 
+script:
   - python setup.py sdist >/dev/null
   - echo "check_stable=False" >pysal/config.py
-  - nosetests --with-coverage --cover-package=pysal; 
+  - nosetests --with-coverage --cover-package=pysal;
   #- cd doc; make pickle; make doctest
 notifications:
     email:
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index b2e5fc7..faa5d4e 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,3 +1,53 @@
+v<1.13.0>, 2016-11-24
+
+We closed a total of 38 issues, 7 pull requests and 31 regular issues;
+this is the full list (generated with the script 
+:file:`tools/github_stats.py`):
+
+Pull Requests (7):
+
+* :ghpull:`844`: Geotable plot
+* :ghpull:`875`: Spint constant
+* :ghpull:`874`: Use standard python facilites for warning
+* :ghpull:`873`: updating release schedule
+* :ghpull:`871`: Put requirements into setup.py so they are installed if missing
+* :ghpull:`870`: Doc/release
+* :ghpull:`869`: Dev
+
+Issues (31):
+
+* :ghissue:`844`: Geotable plot
+* :ghissue:`877`: documentation links to numpy and scipy are broken
+* :ghissue:`875`: Spint constant
+* :ghissue:`874`: Use standard python facilites for warning
+* :ghissue:`873`: updating release schedule
+* :ghissue:`871`: Put requirements into setup.py so they are installed if missing
+* :ghissue:`591`: check pysal version and report if a more recent stable version is available
+* :ghissue:`410`: prototype LISA cluster map
+* :ghissue:`333`: Add k functions
+* :ghissue:`274`: Implement LISA in network module
+* :ghissue:`746`: Network data structures
+* :ghissue:`751`: A method to get a list of example-files by type
+* :ghissue:`219`: inconsistent treatment of centroids in arc distance calculations in weights/user.py
+* :ghissue:`173`: implement cross sectional and space-time scan statistics
+* :ghissue:`170`: centralize all kernel based calculations
+* :ghissue:`134`: Complete cg.locators
+* :ghissue:`94`: Smoothing: add another module based on model-based smoothing
+* :ghissue:`91`: Smoothing: Develop simulations for comparing different smoothers 
+* :ghissue:`90`: Overhaul Polygon class
+* :ghissue:`89`: Optimize shapefile reader 
+* :ghissue:`88`: Optimize Clockwise test
+* :ghissue:`86`: Spatial_Dynamics: LISA Time paths
+* :ghissue:`85`: Spatial_Dynamics: modified knox statistic
+* :ghissue:`84`: Spatial_Dynamics: Optimize Theta
+* :ghissue:`652`: Use cKDtree for Arc_KDTree
+* :ghissue:`697`: Update Release Management to Support Rolling Releases
+* :ghissue:`761`: Object-oriented design for viz module
+* :ghissue:`767`: ZeroDivisonError when calculating certain centroids
+* :ghissue:`849`: dbf2df can not read dbf files within which there are Chinese characters
+* :ghissue:`870`: Doc/release
+* :ghissue:`869`: Dev
+
 v<1.12.0>, 2016-09-21
 
 We closed a total of 100 issues, 33 pull requests and 67 regular issues;
diff --git a/MANIFEST.in b/MANIFEST.in
index f7f610c..6d383ed 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,2 +1,2 @@
-include authors.txt INSTALL.txt LICENSE.txt THANKS.txt CHANGELOG.txt MANIFEST.in pysal/COPYING 
+include authors.txt INSTALL.txt LICENSE.txt THANKS.txt CHANGELOG.txt MANIFEST.in pysal/COPYING requirements_dev.txt requirements_plus.txt requirements.txt
 
diff --git a/README.rst b/README.rst
index 4f342de..1587a06 100644
--- a/README.rst
+++ b/README.rst
@@ -57,7 +57,7 @@ widening in the near future.
 .. |docs| image:: https://readthedocs.org/projects/pysal/badge/?verison=latest
    :scale: 50%
    :align: top
-   :target: http://pysal.readthedocs.org/en/latest/ 
+   :target: http://pysal.readthedocs.org/en/latest/
 .. |talk| image:: https://badges.gitter.im/Join%20Chat.svg
    :scale: 50%
    :align: top
@@ -87,10 +87,10 @@ Installation
 PySAL can be installed using pip:
 
 .. code-block:: bash
-   
+
     $ pip install pysal
 
-PySAL is also available through 
+PySAL is also available through
 `Anaconda <https://www.continuum.io/downloads>`__ and `Enthought Canopy <https://www.enthought.com/products/canopy/>`__.
 
 Documentation
@@ -121,7 +121,7 @@ as well as gitter_.
 Getting Involved
 ================
 
-If you are interested in contributing to PySAL please see our 
+If you are interested in contributing to PySAL please see our
 `development guidelines <http://pysal.readthedocs.org/en/latest/developers/index.html>`_.
 
 
diff --git a/THANKS.txt b/THANKS.txt
index 89aaf75..883363d 100644
--- a/THANKS.txt
+++ b/THANKS.txt
@@ -9,8 +9,10 @@ been left off, please email the "PySAL Developers List" <pysal-dev at googlegroups.
 
 Pedro Amaral
 Luc Anselin
+Jotham Apaloo
 Daniel Arribas-Bel
 David C. Folch
+Forest Gregg
 Myunghwa Hwang
 Wei Kang
 Marynia Kolak
@@ -22,6 +24,7 @@ Mark McCann
 Taylor Oshan
 Serge Rey
 Charles R. Schmidt
+Skipper Seabold
 Alessandra Sozzi
 Philip Stephens
 Bohumil Svoma
@@ -33,6 +36,8 @@ Xinyue Ye
 
 Funding from the following sources has supported PySAL development:
 
+Google Summer of Code 2016
+
 National Science Foundation New Approaches for Spatial Distribution Dynamics
 
 National Science Foundation CyberGIS Software Integration for Sustained Geospatial Innovation
diff --git a/doc/source/conf.py b/doc/source/conf.py
index 464ce65..cd630c2 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -16,7 +16,7 @@ import os
 extensions = ['sphinx.ext.autodoc',
 'sphinx.ext.doctest','sphinx.ext.graphviz', 'sphinx.ext.intersphinx',
 'sphinx.ext.autosummary',
-'sphinx.ext.pngmath','sphinx.ext.viewcode', 'sphinxcontrib.napoleon']
+'sphinx.ext.imgmath','sphinx.ext.viewcode', 'sphinx.ext.napoleon']
 
 #doctest extension config values
 #doctest_path = '/Users/stephens/code/pysal/doc/source/users/tutorials/'
@@ -45,9 +45,9 @@ copyright = u'2014-, PySAL Developers; 2009-13 Sergio Rey'
 # built documents.
 #
 # The short X.Y version.
-version = '1.12.0'
+version = '1.13.0'
 # The full version, including alpha/beta/rc tags.
-release = '1.12.0'
+release = '1.13.0'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
@@ -225,3 +225,17 @@ intersphinx_mapping = {'http://docs.python.org/': None}
 #numpydoc option
 numpydoc_show_class_members = True
 numpydoc_class_members_toctree = False
+
+# Napoleon settings
+napoleon_google_docstring = True
+napoleon_numpy_docstring = True
+napoleon_include_init_with_doc = False
+napoleon_include_private_with_doc = False
+napoleon_include_special_with_doc = False
+napoleon_use_admonition_for_examples = False
+napoleon_use_admonition_for_notes = False
+napoleon_use_admonition_for_references = False
+napoleon_use_ivar = False
+napoleon_use_param = True
+napoleon_use_rtype = True
+napoleon_use_keyword = True
diff --git a/doc/source/developers/docs/index.rst b/doc/source/developers/docs/index.rst
index 147f1fb..68238e4 100644
--- a/doc/source/developers/docs/index.rst
+++ b/doc/source/developers/docs/index.rst
@@ -51,7 +51,11 @@ from the command line using *pip* or *easy_install*.::
 
        $ easy_install sphinx
        $ easy_install sphinxcontrib-napoleon
+or
 
+       $ pip sphinx
+       $ pip sphinxcontrib-napoleon
+              
 If you get a permission error, trying using 'sudo'. 
 
 The source for the docs is in `doc`. Building the documentation is
diff --git a/doc/source/developers/guidelines.rst b/doc/source/developers/guidelines.rst
index 3e2c651..b7e4c5f 100644
--- a/doc/source/developers/guidelines.rst
+++ b/doc/source/developers/guidelines.rst
@@ -59,40 +59,9 @@ and the `gitter room <https://gitter.im/pysal/pysal>`_.
 Release Schedule
 -----------------------
 
-PySAL development follows a six-month release schedule that is aligned with
-the academic calendar.
-
-
-1.12 Cycle
-==========
-
-========   ========   ================= ====================================================
-Start      End        Phase             Notes
-========   ========   ================= ====================================================
-2/1/16      2/14/16   Module Proposals  Developers draft PEPs and prototype
-2/15/16     2/15/16   Developer vote    All developers vote on PEPs 
-2/16/16     2/16/16   Module Approval   BDFL announces final approval
-2/17/16     6/30/16   Development       Implementation and testing of approved modules
-7/1/16      7/27/16   Code Freeze       APIs fixed, bug and testing changes only
-7/23/16     7/30/16   Release Prep      Test release builds, updating svn 
-7/31/16     7/31/16   Release           Official release of 1.12
-========   ========   ================= ====================================================
-
-
-1.13 Cycle
-==========
-
-========   ========   ================= ====================================================
-Start      End        Phase             Notes
-========   ========   ================= ====================================================
-8/1/16      8/14/16   Module Proposals  Developers draft PEPs and prototype
-8/16/16     8/16/16   Developer vote    All developers vote on PEPs 
-8/16/16     8/16/16   Module Approval   BDFL announces final approval
-8/17/16    12/30/16   Development       Implementation and testing of approved modules
-1/1/17       1/1/17   Code Freeze       APIs fixed, bug and testing changes only
-1/23/17     1/30/17   Release Prep      Test release builds, updating svn 
-1/31/17     1/31/17   Release           Official release of 1.13
-========   ========   ================= ====================================================
+As of version 1.11, PySAL has moved to a rolling release model. Discussions
+about releases are carried out during the monthly developer meetings and in 
+the `gitter room <https://gitter.im/pysal/pysal>`_.
 
 
 ----------
diff --git a/doc/source/developers/release.rst b/doc/source/developers/release.rst
index 4fbcccf..bee0cbf 100644
--- a/doc/source/developers/release.rst
+++ b/doc/source/developers/release.rst
@@ -60,7 +60,7 @@ is `v1.10` in what follows)::
 
 - Test that your package can install correctly::
 
-  $ pip install -i https://testpypi.python.org/pypi pysal
+  $ pip install --extra-index-url https://testpypi.python.org/pypi pysal
 
 
 If all is good, proceed, otherwise fix, and repeat.
diff --git a/doc/source/index.rst b/doc/source/index.rst
index 7373984..ead78ed 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -20,7 +20,7 @@ PySAL
 
 .. sidebar:: Releases
 
-    - `Stable 1.12.0 (Released 2016-9-21) <users/installation.html>`_
+    - `Stable 1.13.0 (Released 2016-12-9) <users/installation.html>`_
     - `Development  <http://github.com/pysal/pysal/tree/dev>`_
 
 PySAL is an open source library of spatial analysis functions written in
diff --git a/doc/source/users/installation.rst b/doc/source/users/installation.rst
index 67c394c..9543f3a 100644
--- a/doc/source/users/installation.rst
+++ b/doc/source/users/installation.rst
@@ -33,8 +33,8 @@ stable version of PySAL with either of these distributions as follows:
 If you do not wish to use either Anaconda or Enthought, ensure the following software packages are available on your machine:
 
 * `Python <http://www.python.org/download>`_ 2.6, 2.7 or 3.4
-* `numpy <http://new.scipy.org/download.html>`_ 1.3 or later
-* `scipy <http://new.scipy.org/download.html>`_ 0.11 or later
+* `numpy <http://scipy.org/install.html>`_ 1.3 or later
+* `scipy <http://scipy.org/install.html>`_ 0.11 or later
 
 Getting your feet wet
 ----------------------
@@ -61,7 +61,7 @@ downloaded and installed manually or from the command line using
 
 Alternatively, grab the source distribution (.tar.gz) and decompress it to your selected destination. Open a command shell and navigate to the decompressed pysal folder. Type::
 
-  python setup.py install
+  pip install .
 
 
 Development version on GitHub 
@@ -74,10 +74,10 @@ Developers can checkout PySAL using **git**::
 Open a command shell and navigate to the cloned pysal
 directory. Type::
 
-  python setup.py develop
+  pip install -e .[dev]
 
-The 'develop' subcommand builds the modules in place 
-and modifies sys.path to include the code.
+The '-e' builds the modules in place 
+and symlinks from the python site packages directory to the pysal folder.
 The advantage of this method is that you get the latest code 
 but don't have to fuss with editing system environment variables.
 
@@ -107,7 +107,7 @@ After cloning pysal, install it in develop mode so Python knows where to find it
 Open a command shell and navigate to the cloned pysal
 directory. Type::
 
-  python setup.py develop
+  pip install -e .[dev]
 
 To test your setup, start a Python session and type::
 
diff --git a/pysal/contrib/README.rst b/pysal/contrib/README.rst
index c199227..3c76ef8 100644
--- a/pysal/contrib/README.rst
+++ b/pysal/contrib/README.rst
@@ -52,7 +52,11 @@ Currently the following contribs are available:
 
     - .. versionadded:: 1.5
     - Path: pysal.contrib.viz
-    - Requires: `matplotlib`_
+    - Requires: `matplotlib`_, `pandas`_
+    - Optional:
+        * `bokeh` backend on `geoplot`: `bokeh`_
+        * Color: `palettable`_
+        * Folium bridge on notebook: `folium`_, `geojson`_, `IPython`_
 
  6. Clusterpy -- Spatially constrained clustering.
 
diff --git a/pysal/contrib/spint/count_model.py b/pysal/contrib/spint/count_model.py
index cb7b5aa..b3dc450 100644
--- a/pysal/contrib/spint/count_model.py
+++ b/pysal/contrib/spint/count_model.py
@@ -145,7 +145,7 @@ class CountModelResults(object):
                         value of the loglikelihood function evaluated with only an
                         intercept; see family.py for distribution-specific
                         loglikelihoods
-        aic           : float 
+        AIC           : float 
                         Akaike information criterion
         resid         : array
                         response residuals; defined as y-mu
@@ -167,7 +167,7 @@ class CountModelResults(object):
         self.X = results.X
         self.family = results.family
         self.params = results.params
-        self.aic = results.aic
+        self.AIC = results.aic
         self.df_model = results.df_model
         self.df_resid = results.df_resid
         self.llf = results.llf
diff --git a/pysal/contrib/spint/gravity.py b/pysal/contrib/spint/gravity.py
index 94df1b6..111722a 100644
--- a/pysal/contrib/spint/gravity.py
+++ b/pysal/contrib/spint/gravity.py
@@ -50,7 +50,7 @@ class BaseGravity(CountModel):
                       n x p; p attributes for each destination of n flows;
                       default is None
     constant        : boolean
-                      True to include intercept in model; false by default
+                      True to include intercept in model; True by default
     framework       : string
                       estimation technique; currently only 'GLM' is avaialble
     Quasi           : boolean
@@ -92,7 +92,7 @@ class BaseGravity(CountModel):
     dv              : array
                       n x p(d); p attributes for each destination of n flows
     constant        : boolean
-                      True to include intercept in model; false by default
+                      True to include intercept in model; True by default
     y               : array
                       n x 1; dependent variable used in estimation including any
                       transformations
@@ -122,7 +122,7 @@ class BaseGravity(CountModel):
                       value of the loglikelihood function evaluated with only an
                       intercept; see family.py for distribution-specific
                       loglikelihoods
-    aic             : float
+    AIC             : float
                       Akaike information criterion
     D2              : float
                       percentage of explained deviance
@@ -149,11 +149,11 @@ class BaseGravity(CountModel):
     >>> flows = np.array(db.by_col('count')).reshape((-1,1))
     >>> model = BaseGravity(flows, cost)
     >>> model.params
-    array([ 0.92860101])
+    array([ 17.84839637,  -1.68325787])
 
     """
     def __init__(self, flows, cost, cost_func='pow', o_vars=None, d_vars=None,
-            origins=None, destinations=None, constant=False, framework='GLM',
+            origins=None, destinations=None, constant=True, framework='GLM',
             SF=None, CD=None, Lag=None, Quasi=False):
         n = User.check_arrays(flows, cost)
         #User.check_y(flows, n)
@@ -165,12 +165,16 @@ class BaseGravity(CountModel):
         if type(cost_func) == str:
             if cost_func.lower() == 'pow':
                 self.cf = np.log
+                if (self.c==0).any():
+                    raise ValueError("Zero values detected: cost function 'pow'"
+                            "requires the logarithm of the cost variable which"
+                            "is undefined at 0")
             elif cost_func.lower() == 'exp':
                 self.cf = lambda x: x*1.0
         elif (type(cost_func) == FunctionType) | (type(cost_func) == np.ufunc):
             self.cf = cost_func
         else:
-            raise ValueError("cost_func must be 'exp', 'pow' or a valid"
+            raise ValueError("cost_func must be 'exp', 'pow' or a valid "
             " function that has a scalar as a input and output")
 
         y = np.reshape(self.f, (-1,1))
@@ -178,28 +182,46 @@ class BaseGravity(CountModel):
             X = np.empty((self.n, 0))
         else:
             X = sp.csr_matrix((self.n, 1))
-        if isinstance(self, Attraction) | isinstance(self, Doubly):
-            d_dummies = spcategorical(destinations.flatten())
-            X = sphstack(X, d_dummies, array_out=False)
         if isinstance(self, Production) | isinstance(self, Doubly):
             o_dummies = spcategorical(origins.flatten())
+            if constant:
+                o_dummies = o_dummies[:,1:]
             X = sphstack(X, o_dummies, array_out=False)
-        if isinstance(self, Doubly):
-            X = X[:,1:]
+        if isinstance(self, Attraction) | isinstance(self, Doubly):
+            d_dummies = spcategorical(destinations.flatten())
+            if constant | isinstance(self, Doubly):
+                d_dummies = d_dummies[:,1:]
+            X = sphstack(X, d_dummies, array_out=False)
         if self.ov is not None:	
             if isinstance(self, Gravity):
                 for each in range(self.ov.shape[1]):
+                    if (self.ov[:,each] == 0).any(): 
+                    	raise ValueError("Zero values detected in column %s "
+                                "of origin variables, which are undefined for "
+                                "Poisson log-linear spatial interaction models" % each)
                     X = np.hstack((X, np.log(np.reshape(self.ov[:,each], (-1,1)))))
             else:
                 for each in range(self.ov.shape[1]):
+                    if (self.ov[:,each] == 0).any(): 
+                    	raise ValueError("Zero values detected in column %s "
+                                "of origin variables, which are undefined for "
+                                "Poisson log-linear spatial interaction models" % each)
                     ov = sp.csr_matrix(np.log(np.reshape(self.ov[:,each], ((-1,1)))))
                     X = sphstack(X, ov, array_out=False)
         if self.dv is not None:    	
             if isinstance(self, Gravity):
                 for each in range(self.dv.shape[1]):
+                    if (self.dv[:,each] == 0).any(): 
+                    	raise ValueError("Zero values detected in column %s "
+                                "of destination variables, which are undefined for "
+                                "Poisson log-linear spatial interaction models" % each)
                     X = np.hstack((X, np.log(np.reshape(self.dv[:,each], (-1,1)))))
             else:
                 for each in range(self.dv.shape[1]):
+                    if (self.dv[:,each] == 0).any(): 
+                    	raise ValueError("Zero values detected in column %s "
+                                "of destination variables, which are undefined for "
+                                "Poisson log-linear spatial interaction models" % each)
                     dv = sp.csr_matrix(np.log(np.reshape(self.dv[:,each], ((-1,1)))))
                     X = sphstack(X, dv, array_out=False)
         if isinstance(self, Gravity):
@@ -236,7 +258,7 @@ class BaseGravity(CountModel):
         self.resid_dev = results.resid_dev
         self.llf = results.llf
         self.llnull = results.llnull
-        self.aic = results.aic
+        self.AIC = results.AIC
         self.k = results.k
         self.D2 = results.D2
         self.adj_D2 = results.adj_D2
@@ -283,7 +305,7 @@ class Gravity(BaseGravity):
                       n x p; p attributes for each destination of n flows;
                       default is None
     constant        : boolean
-                      True to include intercept in model; false by default
+                      True to include intercept in model; True by default
     framework       : string
                       estimation technique; currently only 'GLM' is avaialble
     Quasi           : boolean
@@ -324,7 +346,7 @@ class Gravity(BaseGravity):
     dv              : array 
                       n x p(d); p attributes for each destination of n flows
     constant        : boolean
-                      True to include intercept in model; false by default
+                      True to include intercept in model; True by default
     y               : array
                       n x 1; dependent variable used in estimation including any
                       transformations
@@ -354,7 +376,7 @@ class Gravity(BaseGravity):
                       value of the loglikelihood function evaluated with only an
                       intercept; see family.py for distribution-specific
                       loglikelihoods
-    aic             : float 
+    AIC             : float 
                       Akaike information criterion
     D2              : float
                       percentage of explained deviance
@@ -383,11 +405,12 @@ class Gravity(BaseGravity):
     >>> d_cap = np.array(db.by_col('d_cap')).reshape((-1,1))
     >>> model = Gravity(flows, o_cap, d_cap, cost, 'exp')
     >>> model.params
-    array([ 0.87911778,  0.71080687, -0.00194626])
+    array([  3.80050153e+00,   5.54103854e-01,   3.94282921e-01,
+            -2.27091686e-03])
     
     """
     def __init__(self, flows, o_vars, d_vars, cost,
-            cost_func, constant=False, framework='GLM', SF=None, CD=None,
+            cost_func, constant=True, framework='GLM', SF=None, CD=None,
             Lag=None, Quasi=False):
         self.f = np.reshape(flows, (-1,1))
         if len(o_vars.shape) > 1:
@@ -433,7 +456,7 @@ class Gravity(BaseGravity):
         """
         results = {}
         covs = self.ov.shape[1] + self.dv.shape[1] + 1
-        results['aic'] = []
+        results['AIC'] = []
         results['deviance'] = []
         results['pseudoR2'] = []
         results['adj_pseudoR2'] = []
@@ -451,8 +474,9 @@ class Gravity(BaseGravity):
             o_vars = self.ov[subset.reshape(self.ov.shape[0]),:]
             d_vars = self.dv[subset.reshape(self.dv.shape[0]),:]
             dij = self.reshape(self.c[subset])
-            model = Gravity(f, o_vars, d_vars, dij, self.cf)
-            results['aic'].append(model.aic)
+            model = Gravity(f, o_vars, d_vars, dij, self.cf,
+                    constant=False)
+            results['AIC'].append(model.AIC)
             results['deviance'].append(model.deviance)
             results['pseudoR2'].append(model.pseudoR2)
             results['adj_pseudoR2'].append(model.adj_pseudoR2)
@@ -488,7 +512,7 @@ class Production(BaseGravity):
                       n x p; p attributes for each destination of n flows;
                       default is None
     constant        : boolean
-                      True to include intercept in model; false by default
+                      True to include intercept in model; True by default
     framework       : string
                       estimation technique; currently only 'GLM' is avaialble
     Quasi           : boolean
@@ -529,7 +553,7 @@ class Production(BaseGravity):
     dv              : array 
                       n x p; p attributes for each destination of n flows
     constant        : boolean
-                      True to include intercept in model; false by default
+                      True to include intercept in model; True by default
     y               : array
                       n x 1; dependent variable used in estimation including any
                       transformations
@@ -559,7 +583,7 @@ class Production(BaseGravity):
                       value of the loglikelihood function evaluated with only an
                       intercept; see family.py for distribution-specific
                       loglikelihoods
-    aic             : float 
+    AIC             : float 
                       Akaike information criterion
     D2              : float
                       percentage of explained deviance
@@ -589,11 +613,10 @@ class Production(BaseGravity):
     >>> d_cap = np.array(db.by_col('d_cap')).reshape((-1,1))
     >>> model = Production(flows, o, d_cap, cost, 'exp')
     >>> model.params[-4:]
-    array([  5.38580065e+00,   5.00216058e+00,   8.55357745e-01,
-            -2.27444394e-03])
+    array([ 1.34721352,  0.96357345,  0.85535775, -0.00227444])
 
     """
-    def __init__(self, flows, origins, d_vars, cost, cost_func, constant=False,
+    def __init__(self, flows, origins, d_vars, cost, cost_func, constant=True,
             framework='GLM', SF=None, CD=None, Lag=None, Quasi=False):
         self.constant = constant
         self.f = self.reshape(flows)
@@ -629,7 +652,7 @@ class Production(BaseGravity):
         """
         results = {}
         covs = self.dv.shape[1] + 1
-        results['aic'] = []
+        results['AIC'] = []
         results['deviance'] = []
         results['pseudoR2'] = []
         results['adj_pseudoR2'] = []
@@ -649,8 +672,8 @@ class Production(BaseGravity):
             o = self.reshape(self.o[subset])
             d_vars = self.dv[subset.reshape(self.dv.shape[0]),:]
             dij = self.reshape(self.c[subset])
-            model = Production(f, o, d_vars, dij, self.cf)
-            results['aic'].append(model.aic)
+            model = Production(f, o, d_vars, dij, self.cf, constant=False)
+            results['AIC'].append(model.AIC)
             results['deviance'].append(model.deviance)
             results['pseudoR2'].append(model.pseudoR2)
             results['adj_pseudoR2'].append(model.adj_pseudoR2)
@@ -686,7 +709,7 @@ class Attraction(BaseGravity):
                       n x p; p attributes for each origin of  n flows; default
                       is None
     constant        : boolean
-                      True to include intercept in model; false by default
+                      True to include intercept in model; True by default
     y               : array
                       n x 1; dependent variable used in estimation including any
                       transformations
@@ -732,7 +755,7 @@ class Attraction(BaseGravity):
     ov              : array
                       n x p; p attributes for each origin of n flows
     constant        : boolean
-                      True to include intercept in model; false by default
+                      True to include intercept in model; True by default
     params          : array
                       n x k, k estimated beta coefficients; k = # of
                       destinations + p + 1
@@ -758,7 +781,7 @@ class Attraction(BaseGravity):
                       value of the loglikelihood function evaluated with only an
                       intercept; see family.py for distribution-specific
                       loglikelihoods
-    aic             : float 
+    AIC             : float 
                       Akaike information criterion
     D2              : float
                       percentage of explained deviance
@@ -787,12 +810,11 @@ class Attraction(BaseGravity):
     >>> o_cap = np.array(db.by_col('o_cap')).reshape((-1,1))
     >>> model = Attraction(flows, d, o_cap, cost, 'exp')
     >>> model.params[-4:]
-    array([  5.23366116e+00,   4.89037868e+00,   8.82909095e-01,
-            -2.29081323e-03])
-
+    array([ 1.21962276,  0.87634028,  0.88290909, -0.00229081])
+    
     """
     def __init__(self, flows, destinations, o_vars, cost, cost_func,
-            constant=False, framework='GLM', SF=None, CD=None, Lag=None,
+            constant=True, framework='GLM', SF=None, CD=None, Lag=None,
             Quasi=False):
         self.f = np.reshape(flows, (-1,1))
         if len(o_vars.shape) > 1:
@@ -825,7 +847,7 @@ class Attraction(BaseGravity):
         """
         results = {}
         covs = self.ov.shape[1] + 1
-        results['aic'] = []
+        results['AIC'] = []
         results['deviance'] = []
         results['pseudoR2'] = []
         results['adj_pseudoR2'] = []
@@ -845,8 +867,8 @@ class Attraction(BaseGravity):
             d = self.reshape(self.d[subset])
             o_vars = self.ov[subset.reshape(self.ov.shape[0]),:]
             dij = self.reshape(self.c[subset])
-            model = Attraction(f, d, o_vars, dij, self.cf)
-            results['aic'].append(model.aic)
+            model = Attraction(f, d, o_vars, dij, self.cf, constant=False)
+            results['AIC'].append(model.AIC)
             results['deviance'].append(model.deviance)
             results['pseudoR2'].append(model.pseudoR2)
             results['adj_pseudoR2'].append(model.adj_pseudoR2)
@@ -883,7 +905,7 @@ class Doubly(BaseGravity):
                       functional form of the cost function;
                       'exp' | 'pow' | custom function
     constant        : boolean
-                      True to include intercept in model; false by default
+                      True to include intercept in model; True by default
     y               : array
                       n x 1; dependent variable used in estimation including any
                       transformations
@@ -929,7 +951,7 @@ class Doubly(BaseGravity):
     d               : array
                       n x 1; index of destination id's
     constant        : boolean
-                      True to include intercept in model; false by default
+                      True to include intercept in model; True by default
     params          : array
                       n x k, estimated beta coefficients; k = # of origins + #
                       of destinations; the first x-1 values
@@ -959,7 +981,7 @@ class Doubly(BaseGravity):
                       value of the loglikelihood function evaluated with only an
                       intercept; see family.py for distribution-specific
                       loglikelihoods
-    aic             : float 
+    AIC             : float 
                       Akaike information criterion
     D2              : float
                       percentage of explained deviance
@@ -992,7 +1014,7 @@ class Doubly(BaseGravity):
 
     """
     def __init__(self, flows, origins, destinations, cost, cost_func,
-            constant=False, framework='GLM', SF=None, CD=None, Lag=None,
+            constant=True, framework='GLM', SF=None, CD=None, Lag=None,
             Quasi=False):
 
         self.f = np.reshape(flows, (-1,1))
diff --git a/pysal/contrib/spint/notebooks/examples/Example_NYCBikes_AllFeatures.ipynb b/pysal/contrib/spint/notebooks/Example_NYCBikes_AllFeatures.ipynb
similarity index 99%
rename from pysal/contrib/spint/notebooks/examples/Example_NYCBikes_AllFeatures.ipynb
rename to pysal/contrib/spint/notebooks/Example_NYCBikes_AllFeatures.ipynb
index d31fa64..92e79ed 100644
--- a/pysal/contrib/spint/notebooks/examples/Example_NYCBikes_AllFeatures.ipynb
+++ b/pysal/contrib/spint/notebooks/Example_NYCBikes_AllFeatures.ipynb
@@ -2,7 +2,7 @@
  "cells": [
   {
    "cell_type": "code",
-   "execution_count": 1,
+   "execution_count": 465,
    "metadata": {
     "collapsed": false
    },
@@ -18,9 +18,7 @@
      "name": "stderr",
      "output_type": "stream",
      "text": [
-      "//anaconda/envs/spint/lib/python2.7/site-packages/IPython/html.py:14: ShimWarning: The `IPython.html` package has been deprecated. You should import from `notebook` instead. `IPython.html.widgets` has moved to `ipywidgets`.\n",
-      "  \"`IPython.html.widgets` has moved to `ipywidgets`.\", ShimWarning)\n",
-      "//anaconda/envs/spint/lib/python2.7/site-packages/IPython/core/magics/pylab.py:161: UserWarning: pylab import has clobbered these variables: ['plt']\n",
+      "//anaconda/envs/spint/lib/python2.7/site-packages/IPython/core/magics/pylab.py:161: UserWarning: pylab import has clobbered these variables: ['plt', 'Polygon']\n",
       "`%matplotlib` prevents importing * from pylab and numpy\n",
       "  \"\\n`%matplotlib` prevents importing * from pylab and numpy\"\n"
      ]
@@ -46,7 +44,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 2,
+   "execution_count": 466,
    "metadata": {
     "collapsed": false
    },
@@ -240,7 +238,7 @@
        "[5 rows x 35 columns]"
       ]
      },
-     "execution_count": 2,
+     "execution_count": 466,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -253,7 +251,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 3,
+   "execution_count": 467,
    "metadata": {
     "collapsed": false
    },
@@ -307,7 +305,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 4,
+   "execution_count": 468,
    "metadata": {
     "collapsed": false
    },
@@ -883,15 +881,6 @@
     "#model implementation avaialble\n",
     "#from pysal.weights.spintW import vecW, netW, ODW"
    ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "collapsed": true
-   },
-   "outputs": [],
-   "source": []
   }
  ],
  "metadata": {
diff --git a/pysal/contrib/spint/notebooks/Gaussian_SAR.ipynb b/pysal/contrib/spint/notebooks/Gaussian_SAR.ipynb
deleted file mode 100644
index 6a66bab..0000000
--- a/pysal/contrib/spint/notebooks/Gaussian_SAR.ipynb
+++ /dev/null
@@ -1,791 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "code",
-   "execution_count": 920,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [],
-   "source": [
-    "import numpy as np\n",
-    "import pandas as pd\n",
-    "import os\n",
-    "os.chdir('/Users/toshan/dev/pysal/pysal/contrib/spint')\n",
-    "from gravity import Gravity, Production, Attraction, Doubly, BaseGravity\n",
-    "import statsmodels.formula.api as smf\n",
-    "from statsmodels.api import families\n",
-    "import pysal.spreg.ml_lag as ml_lag\n",
-    "import pysal\n",
-    "\n",
-    "os.chdir('/Users/toshan/dev/pysal/pysal/weights')\n",
-    "from spintW import ODW\n",
-    "from pysal.spreg.twosls_sp import GM_Lag, BaseGM_Lag\n",
-    "from pysal.spreg.twosls import BaseTSLS\n",
-    "from pysal.spreg.utils import set_endog"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 921,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [],
-   "source": [
-    "def m_inverse_prod(w, data, scalar, post_multiply=False, inv_method=\"power_exp\", threshold=0.0000000001, max_iterations=None):\n",
-    "    \"\"\" \n",
-    "\n",
-    "    Parameters\n",
-    "    ----------\n",
-    "\n",
-    "    w               : Pysal W object\n",
-    "                      nxn Pysal spatial weights object \n",
-    "\n",
-    "    data            : Numpy array\n",
-    "                      nx1 vector of data\n",
-    "\n",
-    "    scalar          : float\n",
-    "                      Scalar value (typically rho or lambda)\n",
-    "\n",
-    "    post_multiply   : boolean\n",
-    "                      If True then post-multiplies the data vector by the\n",
-    "                      inverse of the spatial filter, if false then\n",
-    "                      pre-multiplies.\n",
-    "    \n",
-    "    threshold       : float\n",
-    "                      Test value to stop the iterations. Test is against\n",
-    "                      sqrt(increment' * increment), where increment is a\n",
-    "                      vector representing the contribution from each\n",
-    "                      iteration.\n",
-    "\n",
-    "    max_iterations  : integer\n",
-    "                      Maximum number of iterations for the expansion.   \n",
-    "\n",
-    "    Examples\n",
-    "    --------\n",
-    "    \"\"\"\n",
-    "    N = data.shape[0]\n",
-    "    matrix = la.inv(np.eye(N))\n",
-    "    try:\n",
-    "        for i in range(len(w)):\n",
-    "            matrix -=  (scalar[i] * w[i].full()[0])\n",
-    "    except:\n",
-    "        for i in range(len(w)):\n",
-    "            matrix -= (scalar[i] * w[i])\n",
-    "    if post_multiply:\n",
-    "        inv_prod = spdot(data.T, np.asarray(matrix))\n",
-    "    else:\n",
-    "        inv_prod = spdot(np.asarray(matrix), data)\n",
-    "    return inv_prod\n",
-    "\n",
-    "\n",
-    "\n",
-    "\n",
-    "import numpy as np\n",
-    "import numpy.linalg as la\n",
-    "from scipy import sparse as sp\n",
-    "from scipy.sparse.linalg import splu as SuperLU\n",
-    "import pysal as ps\n",
-    "from pysal.spreg.utils import RegressionPropsY, RegressionPropsVM, inverse_prod, spdot\n",
-    "import pysal.spreg.diagnostics as DIAG\n",
-    "import pysal.spreg.user_output as USER\n",
-    "import pysal.spreg.summary_output as SUMMARY\n",
-    "from pysal.spreg.w_utils import symmetrize\n",
-    "try:\n",
-    "    from scipy.optimize import minimize_scalar\n",
-    "    from scipy.optimize import minimize\n",
-    "    minimize_scalar_available = True\n",
-    "except ImportError:\n",
-    "    minimize_scalar_available = False\n",
-    "\n",
-    "__all__ = [\"ML_Lag\"]\n",
-    "\n",
-    "\n",
-    "class BaseML_Lag(RegressionPropsY, RegressionPropsVM):\n",
-    "\n",
-    "    \"\"\"\n",
-    "    ML estimation of the spatial lag model (note no consistency\n",
-    "    checks, diagnostics or constants added); Anselin (1988) [Anselin1988]_\n",
-    "    Parameters\n",
-    "    ----------\n",
-    "    y            : array\n",
-    "                   nx1 array for dependent variable\n",
-    "    x            : array\n",
-    "                   Two dimensional array with n rows and one column for each\n",
-    "                   independent (exogenous) variable, excluding the constant\n",
-    "    w            : pysal W object\n",
-    "                   Spatial weights object\n",
-    "    method       : string\n",
-    "                   if 'full', brute force calculation (full matrix expressions)\n",
-    "                   if 'ord', Ord eigenvalue method\n",
-    "                   if 'LU', LU sparse matrix decomposition\n",
-    "    epsilon      : float\n",
-    "                   tolerance criterion in mimimize_scalar function and inverse_product\n",
-    "    Attributes\n",
-    "    ----------\n",
-    "    betas        : array\n",
-    "                   (k+1)x1 array of estimated coefficients (rho first)\n",
-    "    rho          : float\n",
-    "                   estimate of spatial autoregressive coefficient\n",
-    "    u            : array\n",
-    "                   nx1 array of residuals\n",
-    "    predy        : array\n",
-    "                   nx1 array of predicted y values\n",
-    "    n            : integer\n",
-    "                   Number of observations\n",
-    "    k            : integer\n",
-    "                   Number of variables for which coefficients are estimated\n",
-    "                   (including the constant, excluding the rho)\n",
-    "    y            : array\n",
-    "                   nx1 array for dependent variable\n",
-    "    x            : array\n",
-    "                   Two dimensional array with n rows and one column for each\n",
-    "                   independent (exogenous) variable, including the constant\n",
-    "    method       : string\n",
-    "                   log Jacobian method\n",
-    "                   if 'full': brute force (full matrix computations)\n",
-    "                   if 'ord' : Ord eigenvalue method\n",
-    "    epsilon      : float\n",
-    "                   tolerance criterion used in minimize_scalar function and inverse_product\n",
-    "    mean_y       : float\n",
-    "                   Mean of dependent variable\n",
-    "    std_y        : float\n",
-    "                   Standard deviation of dependent variable\n",
-    "    vm           : array\n",
-    "                   Variance covariance matrix (k+1 x k+1)\n",
-    "    vm1          : array\n",
-    "                   Variance covariance matrix (k+2 x k+2) includes sigma2\n",
-    "    sig2         : float\n",
-    "                   Sigma squared used in computations\n",
-    "    logll        : float\n",
-    "                   maximized log-likelihood (including constant terms)\n",
-    "    predy_e      : array\n",
-    "                   predicted values from reduced form\n",
-    "    e_pred       : array\n",
-    "                   prediction errors using reduced form predicted values\n",
-    "    Examples\n",
-    "    --------\n",
-    "    >>> import numpy as np\n",
-    "    >>> import pysal as ps\n",
-    "    >>> db =  ps.open(ps.examples.get_path(\"baltim.dbf\"),'r')\n",
-    "    >>> ds_name = \"baltim.dbf\"\n",
-    "    >>> y_name = \"PRICE\"\n",
-    "    >>> y = np.array(db.by_col(y_name)).T\n",
-    "    >>> y.shape = (len(y),1)\n",
-    "    >>> x_names = [\"NROOM\",\"NBATH\",\"PATIO\",\"FIREPL\",\"AC\",\"GAR\",\"AGE\",\"LOTSZ\",\"SQFT\"]\n",
-    "    >>> x = np.array([db.by_col(var) for var in x_names]).T\n",
-    "    >>> x = np.hstack((np.ones((len(y),1)),x))\n",
-    "    >>> ww = ps.open(ps.examples.get_path(\"baltim_q.gal\"))\n",
-    "    >>> w = ww.read()\n",
-    "    >>> ww.close()\n",
-    "    >>> w.transform = 'r'\n",
-    "    >>> w_name = \"baltim_q.gal\"\n",
-    "    >>> mllag = BaseML_Lag(y,x,w,method='ord') #doctest: +SKIP\n",
-    "    >>> \"{0:.6f}\".format(mllag.rho) #doctest: +SKIP\n",
-    "    '0.425885'\n",
-    "    >>> np.around(mllag.betas, decimals=4) #doctest: +SKIP\n",
-    "    array([[ 4.3675],\n",
-    "           [ 0.7502],\n",
-    "           [ 5.6116],\n",
-    "           [ 7.0497],\n",
-    "           [ 7.7246],\n",
-    "           [ 6.1231],\n",
-    "           [ 4.6375],\n",
-    "           [-0.1107],\n",
-    "           [ 0.0679],\n",
-    "           [ 0.0794],\n",
-    "           [ 0.4259]])\n",
-    "    >>> \"{0:.6f}\".format(mllag.mean_y) #doctest: +SKIP\n",
-    "    '44.307180'\n",
-    "    >>> \"{0:.6f}\".format(mllag.std_y) #doctest: +SKIP\n",
-    "    '23.606077'\n",
-    "    >>> np.around(np.diag(mllag.vm1), decimals=4) #doctest: +SKIP\n",
-    "    array([  23.8716,    1.1222,    3.0593,    7.3416,    5.6695,    5.4698,\n",
-    "              2.8684,    0.0026,    0.0002,    0.0266,    0.0032,  220.1292])\n",
-    "    >>> np.around(np.diag(mllag.vm), decimals=4) #doctest: +SKIP\n",
-    "    array([ 23.8716,   1.1222,   3.0593,   7.3416,   5.6695,   5.4698,\n",
-    "             2.8684,   0.0026,   0.0002,   0.0266,   0.0032])\n",
-    "    >>> \"{0:.6f}\".format(mllag.sig2) #doctest: +SKIP\n",
-    "    '151.458698'\n",
-    "    >>> \"{0:.6f}\".format(mllag.logll) #doctest: +SKIP\n",
-    "    '-832.937174'\n",
-    "    >>> mllag = BaseML_Lag(y,x,w) #doctest: +SKIP\n",
-    "    >>> \"{0:.6f}\".format(mllag.rho) #doctest: +SKIP\n",
-    "    '0.425885'\n",
-    "    >>> np.around(mllag.betas, decimals=4) #doctest: +SKIP\n",
-    "    array([[ 4.3675],\n",
-    "           [ 0.7502],\n",
-    "           [ 5.6116],\n",
-    "           [ 7.0497],\n",
-    "           [ 7.7246],\n",
-    "           [ 6.1231],\n",
-    "           [ 4.6375],\n",
-    "           [-0.1107],\n",
-    "           [ 0.0679],\n",
-    "           [ 0.0794],\n",
-    "           [ 0.4259]])\n",
-    "    >>> \"{0:.6f}\".format(mllag.mean_y) #doctest: +SKIP\n",
-    "    '44.307180'\n",
-    "    >>> \"{0:.6f}\".format(mllag.std_y) #doctest: +SKIP\n",
-    "    '23.606077'\n",
-    "    >>> np.around(np.diag(mllag.vm1), decimals=4) #doctest: +SKIP\n",
-    "    array([  23.8716,    1.1222,    3.0593,    7.3416,    5.6695,    5.4698,\n",
-    "              2.8684,    0.0026,    0.0002,    0.0266,    0.0032,  220.1292])\n",
-    "    >>> np.around(np.diag(mllag.vm), decimals=4) #doctest: +SKIP\n",
-    "    array([ 23.8716,   1.1222,   3.0593,   7.3416,   5.6695,   5.4698,\n",
-    "             2.8684,   0.0026,   0.0002,   0.0266,   0.0032])\n",
-    "    >>> \"{0:.6f}\".format(mllag.sig2) #doctest: +SKIP\n",
-    "    '151.458698'\n",
-    "    >>> \"{0:.6f}\".format(mllag.logll) #doctest: +SKIP\n",
-    "    '-832.937174'\n",
-    "    \"\"\"\n",
-    "\n",
-    "    def __init__(self, y, x, wo, wd, ww, method='full', epsilon=0.0000001):\n",
-    "        # set up main regression variables and spatial filters\n",
-    "        self.y = y\n",
-    "        self.x = x\n",
-    "        self.n, self.k = self.x.shape\n",
-    "        self.method = method\n",
-    "        self.epsilon = epsilon\n",
-    "        #W = w.full()[0]\n",
-    "        #Wsp = w.sparse\n",
-    "        oylag = ps.lag_spatial(wo, y)\n",
-    "        dylag = ps.lag_spatial(wd, y)\n",
-    "        wylag = ps.lag_spatial(ww, y)\n",
-    "        ylag = (wo.sparse*wd.sparse*ODw.sparse)*f\n",
-    "        # b0, b1, e0 and e1\n",
-    "        xtx = spdot(self.x.T, self.x)\n",
-    "        xtxi = la.inv(xtx)\n",
-    "        xty = spdot(self.x.T, self.y)\n",
-    "        xtylo = spdot(self.x.T, oylag)\n",
-    "        xtyld = spdot(self.x.T, dylag)\n",
-    "        xtylw = spdot(self.x.T, wylag)\n",
-    "        xtyl = spdot(self.x.T, ylag)\n",
-    "        b0 = np.dot(xtxi, xty)\n",
-    "        b1 = np.dot(xtxi, xtylo)\n",
-    "        b2 = np.dot(xtxi, xtyld)\n",
-    "        b3 = np.dot(xtxi, xtylw)\n",
-    "        b4 = np.dot(xtxi, xtyl)\n",
-    "        e0 = self.y - spdot(x, b0)\n",
-    "        e1 = oylag - spdot(x, b1)\n",
-    "        e2 = dylag - spdot(x, b2)\n",
-    "        e3 = wylag - spdot(x, b3)\n",
-    "        e4 = ylag - spdot(x, b4)\n",
-    "        methodML = method.upper()\n",
-    "        # call minimizer using concentrated log-likelihood to get rho\n",
-    "        if methodML in ['FULL', 'LU', 'ORD']:\n",
-    "            if methodML == 'FULL':\n",
-    "                Wo = wo.full()[0]     # moved here\n",
-    "                Wd = wd.full()[0]\n",
-    "                Ww = ww.full()[0]\n",
-    "                x0 = np.array([0.0, 0.0, 0.0])\n",
-    "                bounds = [(-1.0, 1.0), (-1.0, 1.0), (-1.0, 1.0)]\n",
-    "                res = minimize(lag_c_loglik, x0 , bounds=bounds,\n",
-    "                                      args=(\n",
-    "                                          self.n, e0, e1, e2, e3, e4, Wo, Wd, Ww),\n",
-    "                                      tol=epsilon)\n",
-    "            elif methodML == 'LU':\n",
-    "                I = sp.identity(w.n)\n",
-    "                Wsp = w.sparse  # moved here\n",
-    "                res = minimize_scalar(lag_c_loglik_sp, 0.0, bounds=(-1.0,1.0),\n",
-    "                                      args=(self.n, e0, e1, I, Wsp),\n",
-    "                                      method='bounded', tol=epsilon)\n",
-    "            elif methodML == 'ORD':\n",
-    "                # check on symmetry structure\n",
-    "                if w.asymmetry(intrinsic=False) == []:\n",
-    "                    ww = symmetrize(w)\n",
-    "                    WW = ww.todense()\n",
-    "                    evals = la.eigvalsh(WW)\n",
-    "                else:\n",
-    "                    W = w.full()[0]     # moved here\n",
-    "                    evals = la.eigvals(W)\n",
-    "                res = minimize_scalar(lag_c_loglik_ord, 0.0, bounds=(-1.0, 1.0),\n",
-    "                                      args=(\n",
-    "                                          self.n, e0, e1, evals), method='bounded',\n",
-    "                                      tol=epsilon)\n",
-    "        else:\n",
-    "            # program will crash, need to catch\n",
-    "            print(\"{0} is an unsupported method\".format(methodML))\n",
-    "            self = None\n",
-    "            return\n",
-    "        \n",
-    "        #print res.x\n",
-    "        self.o_rho, self.d_rho, self.w_rho = res.x\n",
-    "\n",
-    "        # compute full log-likelihood, including constants\n",
-    "        ln2pi = np.log(2.0 * np.pi)\n",
-    "        llik = -res.fun - self.n / 2.0 * ln2pi - self.n / 2.0\n",
-    "        self.logll = llik[0][0]\n",
-    "\n",
-    "        # b, residuals and predicted values\n",
-    "\n",
-    "        b = b0 - self.o_rho * b1 - self.d_rho * b2 - self.w_rho *b3\n",
-    "        self.betas = np.vstack((b, self.o_rho, self.d_rho, self.w_rho))   # rho added as last coefficient\n",
-    "        self.u = e0 - self.o_rho * e1 - self.o_rho * e2 - self.w_rho * e3\n",
-    "        self.predy = self.y - self.u\n",
-    "        xb = spdot(x, b)\n",
-    "\n",
-    "        self.predy_e = m_inverse_prod(\n",
-    "            [wo.sparse, wd.sparse, ww.sparse], xb, [self.o_rho, self.d_rho, self.w_rho], inv_method=\"power_exp\", threshold=epsilon)\n",
-    "        self.e_pred = self.y - self.predy_e\n",
-    "\n",
-    "        # residual variance\n",
-    "        self.sig2 = self.sig2n  # no allowance for division by n-k\n",
-    "        #print self.betas\n",
-    "        # information matrix\n",
-    "        a = -self.o_rho * Wo - self.d_rho * Wd + self.w_rho * Ww\n",
-    "        W_o = -Wo - self.d_rho * Wd + self.w_rho * Ww\n",
-    "        W_d = -self.o_rho * Wo - Wd + self.w_rho * Ww\n",
-    "        W_w = -self.o_rho * Wo - self.d_rho * Wd + Ww\n",
-    "        np.fill_diagonal(a, 1.0)\n",
-    "        ai = la.inv(a)\n",
-    "\n",
-    "        o_wai = np.dot(W_o, ai)\n",
-    "        o_tr1 = np.trace(o_wai)\n",
-    "        d_wai = np.dot(W_d, ai)\n",
-    "        d_tr1 = np.trace(d_wai)\n",
-    "        w_wai = np.dot(W_w, ai)\n",
-    "        w_tr1 = np.trace(w_wai)\n",
-    "\n",
-    "        oo_wai2 = np.dot(o_wai, o_wai)\n",
-    "        oo_tr2 = np.trace(oo_wai2)\n",
-    "        dd_wai2 = np.dot(d_wai, d_wai)\n",
-    "        dd_tr2 = np.trace(dd_wai2)\n",
-    "        ww_wai2 = np.dot(w_wai, w_wai)\n",
-    "        ww_tr2 = np.trace(ww_wai2)\n",
-    "        \n",
-    "        od_wai2 = np.dot(o_wai, d_wai)\n",
-    "        od_tr2 = np.trace(od_wai2)\n",
-    "\n",
-    "        do_wai2 = np.dot(d_wai, o_wai)\n",
-    "        do_tr2 = np.trace(do_wai2)\n",
-    "\n",
-    "        ow_wai2 = np.dot(o_wai, w_wai)\n",
-    "        ow_tr2 = np.trace(ow_wai2)\n",
-    "\n",
-    "        wo_wai2 = np.dot(w_wai, o_wai)\n",
-    "        wo_tr2 = np.trace(wo_wai2)\n",
-    "\n",
-    "        \n",
-    "        dw_wai2 = np.dot(d_wai, w_wai)\n",
-    "        dw_tr2 = np.trace(dw_wai2)\n",
-    "\n",
-    "        wd_wai2 = np.dot(w_wai, d_wai)\n",
-    "        wd_tr2 = np.trace(wd_wai2)\n",
-    "\n",
-    "        oo_waiTwai = np.dot(o_wai.T, o_wai)\n",
-    "        oo_tr3 = np.trace(oo_waiTwai)\n",
-    "        dd_waiTwai = np.dot(d_wai.T, d_wai)\n",
-    "        dd_tr3 = np.trace(dd_waiTwai)\n",
-    "        ww_waiTwai = np.dot(w_wai.T, w_wai)\n",
-    "        ww_tr3 = np.trace(ww_waiTwai)\n",
-    "\n",
-    "        od_waiTwai = np.dot(o_wai.T, d_wai)\n",
-    "        od_tr3 = np.trace(od_waiTwai)\n",
-    "\n",
-    "        do_waiTwai = np.dot(d_wai.T, o_wai)\n",
-    "        do_tr3 = np.trace(do_waiTwai)\n",
-    "\n",
-    "        ow_waiTwai = np.dot(o_wai.T, w_wai)\n",
-    "        ow_tr3 = np.trace(ow_waiTwai)\n",
-    "\n",
-    "        wo_waiTwai = np.dot(w_wai.T, o_wai)\n",
-    "        wo_tr3 = np.trace(wo_waiTwai)\n",
-    "\n",
-    "        dw_waiTwai = np.dot(d_wai.T, w_wai)\n",
-    "        dw_tr3 = np.trace(dw_waiTwai)\n",
-    "\n",
-    "        wd_waiTwai = np.dot(w_wai.T, d_wai)\n",
-    "        wd_tr3 = np.trace(wd_waiTwai)\n",
-    "\n",
-    "        o_wpredy = ps.lag_spatial(wo, self.predy_e)\n",
-    "        d_wpredy = ps.lag_spatial(wd, self.predy_e)\n",
-    "        w_wpredy = ps.lag_spatial(ww, self.predy_e)\n",
-    "\n",
-    "        o_xTwpy = spdot(x.T, o_wpredy)\n",
-    "        d_xTwpy = spdot(x.T, d_wpredy)\n",
-    "        w_xTwpy = spdot(x.T, w_wpredy)\n",
-    "\n",
-    "        oo_wpyTwpy = np.dot(o_wpredy.T, o_wpredy)\n",
-    "        dd_wpyTwpy = np.dot(d_wpredy.T, d_wpredy)\n",
-    "        ww_wpyTwpy = np.dot(w_wpredy.T, w_wpredy)\n",
-    "        od_wpyTwpy = np.dot(o_wpredy.T, d_wpredy)\n",
-    "        do_wpyTwpy = np.dot(d_wpredy.T, o_wpredy)\n",
-    "        ow_wpyTwpy = np.dot(o_wpredy.T, w_wpredy)\n",
-    "        wo_wpyTwpy = np.dot(w_wpredy.T, o_wpredy)\n",
-    "        dw_wpyTwpy = np.dot(d_wpredy.T, w_wpredy)\n",
-    "        wd_wpyTwpy = np.dot(w_wpredy.T, d_wpredy)\n",
-    "\n",
-    "\n",
-    "\n",
-    "        sig2 = self.sig2\n",
-    "\n",
-    "        beta_beta  = xtx / sig2\n",
-    "        beta_o_rho = o_xTwpy.T / sig2\n",
-    "        beta_d_rho = d_xTwpy.T / sig2\n",
-    "        beta_w_rho = w_xTwpy.T / sig2\n",
-    "        beta_sig2 = np.zeros((1, self.k))\n",
-    "\n",
-    "        o_rho_beta = o_xTwpy / sig2\n",
-    "        o_rho_o_rho = oo_tr2 + oo_tr3 + oo_wpyTwpy / sig2\n",
-    "        o_rho_d_rho = od_tr2 + od_tr3 + od_wpyTwpy / sig2\n",
-    "        o_rho_w_rho = ow_tr2 + ow_tr3 + ow_wpyTwpy / sig2\n",
-    "        o_rho_sig2 = o_tr1 / sig2\n",
-    "\n",
-    "        d_rho_beta = d_xTwpy / sig2\n",
-    "        d_rho_o_rho = do_tr2 + do_tr3 + do_wpyTwpy / sig2\n",
-    "        d_rho_d_rho = dd_tr2 + dd_tr3 + dd_wpyTwpy / sig2\n",
-    "        d_rho_w_rho = dw_tr2 + dw_tr3 + dw_wpyTwpy / sig2\n",
-    "        d_rho_sig2 = d_tr1 / sig2\n",
-    "\n",
-    "        w_rho_beta = w_xTwpy / sig2  \n",
-    "        w_rho_o_rho = wo_tr2 + wo_tr3 + wo_wpyTwpy / sig2\n",
-    "        w_rho_d_rho = wd_tr2 + wd_tr3 + wd_wpyTwpy / sig2\n",
-    "        w_rho_w_rho = ww_tr2 + ww_tr3 + ww_wpyTwpy / sig2\n",
-    "        w_rho_sig2 = w_tr1 / sig2\n",
-    "\n",
-    "        sig2_beta = np.zeros((self.k, 1))   \n",
-    "        sig2_o_rho = o_tr1 / sig2\n",
-    "        sig2_d_rho = d_tr1 / sig2\n",
-    "        sig2_w_rho = w_tr1 / sig2\n",
-    "        sig2_sig2 = self.n / (2.0 * sig2 ** 2)\n",
-    "\n",
-    "        # order of variables is beta, rho_o, rho_d, rho_w, sigma2\n",
-    "\n",
-    "    \n",
-    "        v1 = np.vstack((beta_beta, beta_o_rho, beta_d_rho, beta_w_rho, beta_sig2))\n",
-    "        v2 = np.vstack((o_rho_beta, o_rho_o_rho, o_rho_d_rho, o_rho_w_rho, o_rho_sig2))\n",
-    "        v3 = np.vstack((d_rho_beta, d_rho_o_rho, d_rho_d_rho, d_rho_w_rho, d_rho_sig2))\n",
-    "        v4 = np.vstack((w_rho_beta, w_rho_d_rho, w_rho_d_rho, w_rho_w_rho, w_rho_sig2))\n",
-    "        v5 = np.vstack((sig2_beta, sig2_d_rho, sig2_d_rho, sig2_w_rho, sig2_sig2))\n",
-    "        \n",
-    "        v = np.hstack((v1, v2, v3, v4, v5))\n",
-    "\n",
-    "        self.vm1 = la.inv(v)  # vm1 includes variance for sigma2\n",
-    "        self.vm = self.vm1[:-1, :-1]  # vm is for coefficients only\n",
-    "\n",
-    "\n",
-    "def lag_c_loglik(rho, n, e0, e1, e2, e3, e4, Wo, Wd, Ww):\n",
-    "    # concentrated log-lik for lag model, no constants, brute force\n",
-    "    o_rho, d_rho, w_rho = rho\n",
-    "    er = e0  - (o_rho * e1) - (d_rho * e2) - (w_rho * e3)\n",
-    "    sig2 = np.dot(er.T, er) / n\n",
-    "    nlsig2 = (n / 2.0) * np.log(sig2)\n",
-    "    a = (np.identity(n)  - ((o_rho * Wo)*(d_rho * Wd)*(w_rho * Ww)))\n",
-    "    np.fill_diagonal(a, 1.0)\n",
-    "    jacob = np.log(np.linalg.det(a))\n",
-    "    # this is the negative of the concentrated log lik for minimization\n",
-    "    clik = nlsig2 - jacob\n",
-    "    #print clik\n",
-    "    return clik\n",
-    "\n",
-    "def lag_c_loglik_sp(rho, n, e0, e1, I, Wsp):\n",
-    "    # concentrated log-lik for lag model, sparse algebra\n",
-    "    if isinstance(rho, np.ndarray):\n",
-    "        if rho.shape == (1,1):\n",
-    "            rho = rho[0][0] #why does the interior value change?\n",
-    "    er = e0 - rho * e1\n",
-    "    sig2 = np.dot(er.T, er) / n\n",
-    "    nlsig2 = (n / 2.0) * np.log(sig2)\n",
-    "    a = I - rho * Wsp\n",
-    "    LU = SuperLU(a.tocsc())\n",
-    "    jacob = np.sum(np.log(np.abs(LU.U.diagonal())))\n",
-    "    clike = nlsig2 - jacob\n",
-    "    return clike\n",
-    "\n",
-    "def lag_c_loglik_ord(rho, n, e0, e1, evals):\n",
-    "    # concentrated log-lik for lag model, no constants, Ord eigenvalue method\n",
-    "    er = e0 - rho * e1\n",
-    "    sig2 = np.dot(er.T, er) / n\n",
-    "    nlsig2 = (n / 2.0) * np.log(sig2)\n",
-    "    revals = rho * evals\n",
-    "    jacob = np.log(1 - revals).sum()\n",
-    "    if isinstance(jacob, complex):\n",
-    "        jacob = jacob.real\n",
-    "    # this is the negative of the concentrated log lik for minimization\n",
-    "    clik = nlsig2 - jacob\n",
-    "    return clik\n",
-    "\n"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "SAR SI DGP\n",
-    "\n"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    " $y = (I - \\rho W) X \\beta + (I - \\rho W)\\epsilon$ \n",
-    "\n",
-    " "
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "$X \\beta  = X_{o} \\beta_{o} + X_{d} \\beta_{d} + X_{d_{ij}} \\beta_{d_{ij}}$\n",
-    "\n"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    " $\\rho W = (I - \\rho_{o}W_{o})(I - \\rho_{d}W_{d}) = (I - \\rho_{o}W_{o} - \\rho_{d}W_{d} - \\rho_{w}W_{w})$\n",
-    "\n",
-    " "
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "$\\rho_{w}W_{w} = \\rho_{o} \\rho_{d}W_{o}*W_{d}$\n"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "SAR SI Model Specification\n"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    " $y = \\rho_{o}W_{o}  + \\rho_{d}W_{d} + \\rho_{w}W_{w} + k + X \\beta + (I - \\rho W)\\epsilon$"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 922,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [],
-   "source": [
-    "#Simulate covariates\n",
-    "\n",
-    "o_vars = np.random.randint(5000,10000, (81,1))\n",
-    "d_vars = np.random.randint(5000,10000, (81,1))\n",
-    "dij = np.random.randint(50,1000, (81,1))\n",
-    "\n",
-    "\n",
-    "X = np.hstack([o_vars.reshape((-1,1)), d_vars.reshape((-1,1)), dij.reshape((-1,1))])"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 954,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [],
-   "source": [
-    "#Simulate spatial weights and compute dependent variable using DGP\n",
-    "\n",
-    "z = 7\n",
-    "n = 49\n",
-    "N = n**2\n",
-    "o_vars = np.random.randint(5000,10000, (N,1))\n",
-    "d_vars = np.random.randint(5000,10000, (N,1))\n",
-    "dij = np.random.randint(50,1000, (N,1))\n",
-    "\n",
-    "\n",
-    "X = np.hstack([o_vars.reshape((-1,1)), d_vars.reshape((-1,1)), dij.reshape((-1,1))])\n",
-    "\n",
-    "o = pysal.weights.lat2W(z, z)\n",
-    "d = pysal.weights.lat2W(z, z)\n",
-    "\n",
-    "wo = np.kron(o.full()[0], np.identity(n))\n",
-    "wo = pysal.weights.full2W(wo)\n",
-    "wo.transform = 'r'\n",
-    "wd = np.kron(np.identity(n), d.full()[0])\n",
-    "wd = pysal.weights.full2W(wd)\n",
-    "wd.transform = 'r'\n",
-    "\n",
-    "ODw = ODW(o,d)\n",
-    "ODw.transform = 'r'\n",
-    "\n",
-    "o_rho = .15\n",
-    "d_rho = .15\n",
-    "w_rho = -.3\n",
-    "\n",
-    "ar = np.array(np.linalg.inv((np.identity(N) - o_rho*wo.sparse - d_rho*wd.sparse - w_rho*ODw.sparse)))\n",
-    "\n",
-    "betas = np.vstack([1,.3,.3,-5])\n",
-    "X_constant = np.hstack([np.ones((N,1)), X])\n",
-    "\n",
-    "XB = np.dot(X_constant,betas)\n",
-    "e = np.random.normal(0, 100, (N,1))\n",
-    "\n",
-    "y = np.dot(ar, XB) + np.dot(ar, e)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 955,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [],
-   "source": [
-    "#Prep instruments\n",
-    "\n",
-    "w_lags=1\n",
-    "\n",
-    "o_yend, o_q = set_endog(y, X, wo, None, None, w_lags, True)\n",
-    "d_yend, d_q = set_endog(y, X, wd, None, None, w_lags, True)\n",
-    "w_yend, w_q = set_endog(y, X, ODw, None, None, w_lags, True)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 959,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "[[-16.72171832]\n",
-      " [  0.29949819]\n",
-      " [  0.30055381]\n",
-      " [ -4.99972034]\n",
-      " [  0.15083737]\n",
-      " [  0.15049648]\n",
-      " [ -0.29155565]]\n",
-      "[  3.49950480e+02   2.06426812e-06   2.03681447e-06   5.76503201e-05\n",
-      "   6.21546016e-06   5.76756214e-06   1.92331040e-05]\n"
-     ]
-    }
-   ],
-   "source": [
-    "#GM_Lag via TSLS\n",
-    "\n",
-    "w = (wo.sparse, wd.sparse, ODw.sparse)\n",
-    "yend = np.hstack([o_yend, d_yend, w_yend])\n",
-    "q = np.hstack([o_q, d_q, w_q])\n",
-    "\n",
-    "model = BaseTSLS(y=y, x=X_constant, yend=yend, q=q)\n",
-    "print model.betas\n",
-    "print model.vm.diagonal()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 958,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "[[-12.59047756]\n",
-      " [  0.29941335]\n",
-      " [  0.30048807]\n",
-      " [ -4.9992496 ]\n",
-      " [  0.15157087]\n",
-      " [  0.15191892]\n",
-      " [ -0.29554088]]\n",
-      "[  3.79284298e+02   2.05665963e-06   2.03571089e-06   5.85031928e-05\n",
-      "   6.51171315e-06   5.92191738e-06   2.01701685e-05]\n"
-     ]
-    }
-   ],
-   "source": [
-    "#Extended ML_Lag\n",
-    "\n",
-    "model = BaseML_Lag(y, X_constant, wo, wd, ODw)\n",
-    "print model.betas\n",
-    "print model.vm.diagonal()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 964,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "2401\n"
-     ]
-    }
-   ],
-   "source": [
-    "print len(y>=0)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 965,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "2401"
-      ]
-     },
-     "execution_count": 965,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "len(y)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "collapsed": true
-   },
-   "outputs": [],
-   "source": [
-    "generate 2000\n"
-   ]
-  }
- ],
- "metadata": {
-  "anaconda-cloud": {},
-  "kernelspec": {
-   "display_name": "Python [Root]",
-   "language": "python",
-   "name": "Python [Root]"
-  },
-  "language_info": {
-   "codemirror_mode": {
-    "name": "ipython",
-    "version": 2
-   },
-   "file_extension": ".py",
-   "mimetype": "text/x-python",
-   "name": "python",
-   "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython2",
-   "version": "2.7.12"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 0
-}
diff --git a/pysal/contrib/spint/notebooks/IV_FLOWS.ipynb b/pysal/contrib/spint/notebooks/IV_FLOWS.ipynb
deleted file mode 100644
index 12169ce..0000000
--- a/pysal/contrib/spint/notebooks/IV_FLOWS.ipynb
+++ /dev/null
@@ -1,195 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "code",
-   "execution_count": 145,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [],
-   "source": [
-    "import numpy as np\n",
-    "import pandas as pd\n",
-    "import pysal as ps\n",
-    "import os\n",
-    "os.chdir('/Users/toshan/dev/pysal/pysal/weights')\n",
-    "from spintW import ODW\n",
-    "from pysal.spreg.twosls_sp import GM_Lag, BaseGM_Lag"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 146,
-   "metadata": {
-    "collapsed": true
-   },
-   "outputs": [],
-   "source": [
-    "#Prep Data\n",
-    "austria = pd.read_csv('http://dl.dropbox.com/u/8649795/AT_Austria.csv')\n",
-    "f = austria['Data'].values.reshape((-1,1))\n",
-    "o = austria['Origin'].values.reshape((-1,1))\n",
-    "d = austria['Destination'].values.reshape((-1,1))\n",
-    "dij = austria['Dij'].values.reshape((-1,1))\n",
-    "o_vars = austria['Oi2007'].values.reshape((-1,1))\n",
-    "d_vars = austria['Dj2007'].values.reshape((-1,1))\n",
-    "\n",
-    "Wo = ps.weights.lat2W(3,3)\n",
-    "Wd = ps.weights.lat2W(3,3)\n",
-    "Ww = ODW(Wo,Wd)\n",
-    "\n",
-    "y = f.reshape((-1,1))\n",
-    "X = np.hstack([o_vars.reshape((-1,1)), d_vars.reshape((-1,1)), dij.reshape((-1,1))])"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 149,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "array([[ -2.86692386e+02],\n",
-       "       [  1.02229167e-01],\n",
-       "       [  1.02020709e-01],\n",
-       "       [ -3.59211608e+00],\n",
-       "       [ -3.46757679e-02]])"
-      ]
-     },
-     "execution_count": 149,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "#GM Lag with OD-W\n",
-    "model = GM_Lag(y, X, w=ODw, w_lags=1)\n",
-    "model.betas"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 150,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "array([[  1.40576692e+03],\n",
-       "       [  6.93836657e-02],\n",
-       "       [  6.03194419e-02],\n",
-       "       [ -1.05386559e+01],\n",
-       "       [  3.10794995e-01]])"
-      ]
-     },
-     "execution_count": 150,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "#Base TSLS with OD-W\n",
-    "\n",
-    "X = np.hstack([np.ones((81,1)), o_vars.reshape((-1,1)), d_vars.reshape((-1,1)), dij.reshape((-1,1))])\n",
-    "#X = np.hstack([o_vars.reshape((-1,1)), d_vars.reshape((-1,1)), dij.reshape((-1,1))])\n",
-    "\n",
-    "Wo = ps.weights.full2W(np.kron(Wo.full()[0], np.identity(9)))\n",
-    "Wd = ps.weights.full2W(np.kron(np.identity(9), Wd.full()[0]))\n",
-    "\n",
-    "w_lags=1\n",
-    "    \n",
-    "o_yend, o_q = set_endog(y, X, Wo, None, None, w_lags, True)\n",
-    "d_yend, d_q = set_endog(y, X, Wd, None, None, w_lags, True)\n",
-    "w_yend, w_q = set_endog(y, X, Ww, None, None, w_lags, True)\n",
-    "\n",
-    "w = Ww.sparse\n",
-    "yend = w_yend\n",
-    "q = w_q\n",
-    "\n",
-    "model = TSLS.BaseTSLS(y=y, x=X, yend=yend, q=q)\n",
-    "model.betas"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 151,
-   "metadata": {
-    "collapsed": false,
-    "scrolled": true
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "array([[  5.38733321e+04],\n",
-       "       [ -1.33117926e+01],\n",
-       "       [ -7.14188368e+00],\n",
-       "       [  3.55723696e+02],\n",
-       "       [  7.88125684e+00],\n",
-       "       [  1.20094221e+01],\n",
-       "       [  6.54489799e+01]])"
-      ]
-     },
-     "execution_count": 151,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "#Base TSLS with O-W, D-Wm and OD-W\n",
-    "\n",
-    "w = (Wo.sparse, Wd.sparse, Ww.sparse)\n",
-    "yend = np.hstack([o_yend, d_yend, w_yend])\n",
-    "q = np.hstack([o_q, d_q, w_q])\n",
-    "\n",
-    "model = TSLS.BaseTSLS(y=f, x=X, yend=yend, q=q)\n",
-    "model.betas"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "collapsed": true
-   },
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "collapsed": true
-   },
-   "outputs": [],
-   "source": []
-  }
- ],
- "metadata": {
-  "anaconda-cloud": {},
-  "kernelspec": {
-   "display_name": "Python [Root]",
-   "language": "python",
-   "name": "Python [Root]"
-  },
-  "language_info": {
-   "codemirror_mode": {
-    "name": "ipython",
-    "version": 2
-   },
-   "file_extension": ".py",
-   "mimetype": "text/x-python",
-   "name": "python",
-   "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython2",
-   "version": "2.7.12"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 0
-}
diff --git a/pysal/contrib/spint/notebooks/New_DistanceBand.ipynb b/pysal/contrib/spint/notebooks/New_DistanceBand.ipynb
index bffe39b..fa7ad80 100644
--- a/pysal/contrib/spint/notebooks/New_DistanceBand.ipynb
+++ b/pysal/contrib/spint/notebooks/New_DistanceBand.ipynb
@@ -319,6 +319,18 @@
    "display_name": "Python [Root]",
    "language": "python",
    "name": "Python [Root]"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 2
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython2",
+   "version": "2.7.12"
   }
  },
  "nbformat": 4,
diff --git a/pysal/contrib/spint/notebooks/Vec_SA_Test.ipynb b/pysal/contrib/spint/notebooks/Vec_SA_Test.ipynb
deleted file mode 100644
index 1ca91e2..0000000
--- a/pysal/contrib/spint/notebooks/Vec_SA_Test.ipynb
+++ /dev/null
@@ -1,389 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "code",
-   "execution_count": 1,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Populating the interactive namespace from numpy and matplotlib\n"
-     ]
-    }
-   ],
-   "source": [
-    "import os\n",
-    "os.chdir('../')\n",
-    "from vec_SA import VecMoran\n",
-    "import numpy as np\n",
-    "from pysal.weights.Distance import DistanceBand\n",
-    "import matplotlib.pyplot as plt\n",
-    "%pylab inline"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "# Demonstrating the vector-based Moran's I statistic for spatial autocorrelation and the associated proposed randomization techniques for generating psuedo p-values\n",
-    "\n",
-    "##### - Technique A: Randomly select one vector among the N observed vectors and assign its origin (destination) to the origin (destination) point of another observed vector. This is equivlanet to geometrically translating both the original origin and the original destination by the coordinates of the new origin (destination) point, which preserves the direction and magnitude of the original vector. Using this technique it is possible to generate new vectors that are outside the bou [...]
-    "##### - Technique B: For each vector among the N observed vectors, reassign its origin (destination) point to the destination (origin) from another  randomly selected vector from the N observed vectors. This does does not preserve distance or magnitude, though it does ensure that all new vectors remain within the bounding box of the of the original vectors"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "### Generate 1000 random datasets of 50 vectors, then calculate the vector Moran's I  from the destination perspective (VMD) and a psuedo p value  (based on 99 permutations) using randomization technique A and randomization technique B for each of the 1000 datasets. "
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 237,
-   "metadata": {
-    "collapsed": false,
-    "scrolled": false
-   },
-   "outputs": [],
-   "source": [
-    "dest_A_rand_I = []\n",
-    "dest_B_rand_I = []\n",
-    "dest_A_rand_p = []\n",
-    "dest_B_rand_p = []\n",
-    "for i in range(1000):\n",
-    "    phi = np.random.uniform(0,np.pi*2, 50).reshape((-1,1))\n",
-    "    num = np.arange(0,50).reshape((-1,1))\n",
-    "    OX = np.random.randint(0,500, 50).reshape((-1,1))\n",
-    "    OY = np.random.randint(0,500, 50).reshape((-1,1))\n",
-    "    DX = np.cos(phi)*(np.random.randint(0,500, 50)).reshape((-1,1))\n",
-    "    DY = np.sin(phi)*np.random.randint(0,500, 50).reshape((-1,1))\n",
-    "\n",
-    "    vecs = np.hstack([num, OX, OY, DX, DY])\n",
-    "    dests = vecs[:, 3:5]\n",
-    "    wd = DistanceBand(dests, threshold=9999, alpha=-1.5, binary=False)\n",
-    "\n",
-    "    vmd = VecMoran(vecs, wd, focus='destination', rand='A', permutations=999)\n",
-    "    dest_A_rand_I.append(vmd.I)\n",
-    "    dest_A_rand_p.append(vmd.p_z_sim)\n",
-    "    vmd = VecMoran(vecs, wd, focus='destination', rand='B', permutations=999)\n",
-    "    dest_B_rand_I.append(vmd.I)\n",
-    "    dest_B_rand_p.append(vmd.p_z_sim)\n",
-    "\n",
-    "\n"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 238,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXoAAAEKCAYAAAAcgp5RAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzsnXeUFMUWh39LRhAeQUQkqiAgooCSniSRoIBEBUSUrIhE\nyUhQkqDkYIBVcpAgSUABFyQpgkTJOcM+WGDZZdnQ9/3Rc2uqp7sn7czOgvWdU4eZ7urq6l7mVtWt\nGwCFQqFQKBQKhUKhUCgUCoVCoVAoFAqFQqFQKBQKhUKhUCgUCoVCEQLaANgapLZ/AHATwB9Baj8l\nOQugZqg7oXi4SBPqDigCwlkAsQCipTI5lB1KQaoAeA1APgAVLc5XB6DB+G5aS+czAvgewG0AVwD0\nDGJfvYEc5UFkFoDhoe6Ewky6UHdAERAIQH0Av4W6IyGgEPSBLs5NnUsACticGwbgaQAFATwBIALA\nYQC/ [...]
-      "text/plain": [
-       "<matplotlib.figure.Figure at 0x10d6dd490>"
-      ]
-     },
-     "metadata": {},
-     "output_type": "display_data"
-    }
-   ],
-   "source": [
-    "X,Y,U,V = zip(*vecs[:,1:])\n",
-    "plt.subplot(111)\n",
-    "for x in range(0,len(vecs[:,1])):\n",
-    "    plt.arrow(X[x],  #x1\n",
-    "              Y[x],  # y1\n",
-    "              U[x]-X[x], # x2 - x1\n",
-    "              V[x]-Y[x], # y2 - y1\n",
-    "              fc=\"k\", ec=\"k\", head_width=0.05, head_length=0.1)\n",
-    "plt.xlim([-510,550])\n",
-    "plt.ylim([-510,550])\n",
-    "plt.title('Example of 50 random vectors')\n",
-    "plt.show()"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "### Generate 1000 random datasets of 50 vectors with constrained origins (to induce positive spatial autocorrrlation), then calculate the vector Moran's I  from the destination perspective (VMD) and a psuedo p value  (based on 99 permutations) using randomization technique A and randomization technique B for each of the 1000 datasets. "
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 239,
-   "metadata": {
-    "collapsed": true
-   },
-   "outputs": [],
-   "source": [
-    "\n",
-    "dest_A_cons_I = []\n",
-    "dest_B_cons_I = []\n",
-    "dest_A_cons_p = []\n",
-    "dest_B_cons_p = []\n",
-    "for i in range(1000):\n",
-    "    phi = np.random.uniform(0,np.pi*2, 50).reshape((-1,1))\n",
-    "    num = np.arange(0,50).reshape((-1,1))\n",
-    "    OX = np.random.randint(450,500, 50).reshape((-1,1))\n",
-    "    OY = np.random.randint(450,500, 50).reshape((-1,1))\n",
-    "    DX = np.cos(phi)*(np.random.randint(450,500, 50)).reshape((-1,1))\n",
-    "    DY = np.sin(phi)*np.random.randint(450,500, 50).reshape((-1,1))\n",
-    "\n",
-    "    vecs = np.hstack([num, OX, OY, DX, DY])\n",
-    "    dests = vecs[:, 3:5]\n",
-    "    wd = DistanceBand(dests, threshold=9999, alpha=-1.5, binary=False)\n",
-    "\n",
-    "    vmd = VecMoran(vecs, wd, focus='destination', rand='A', permutations=999)\n",
-    "    dest_A_cons_I.append(vmd.I)\n",
-    "    dest_A_cons_p.append(vmd.p_z_sim)\n",
-    "    vmd = VecMoran(vecs, wd, focus='destination', rand='B', permutations=999)\n",
-    "    dest_B_cons_I.append(vmd.I)\n",
-    "    dest_B_cons_p.append(vmd.p_z_sim)\n",
-    "\n"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 240,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXoAAAEKCAYAAAAcgp5RAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzsXXd4FEUb/wEJJYAJvRcB6fqJBSwgoRcpgoAUQUB6E5Eu\nSG9KE0GRooA0AypNpARIUAGRjoQSqiGAIYUE0nP7fn/MzWZmb6/mLgmwv+eZ5253Zqft7Dsz77wF\nMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAbegN4HcP5f09\ngGgAxzyUf2biJoAmWV2JJwgTAKy0Ed8bnhuX2QX/AHjLA/n6AwhzY367AfT0QNonBjcBJAB4KIQl\nWVkhHfSGZz6oBmCDLa+VeH8ACuS+EQdIHgDfAYgFcBfAxx6oozO4AaBxFtfBVawBMCOrK2EDFcHG\nQk7h [...]
-      "text/plain": [
-       "<matplotlib.figure.Figure at 0x10c01d590>"
-      ]
-     },
-     "metadata": {},
-     "output_type": "display_data"
-    }
-   ],
-   "source": [
-    "X,Y,U,V = zip(*vecs[:,1:])\n",
-    "plt.subplot(111)\n",
-    "for x in range(0,len(vecs[:,1])):\n",
-    "    plt.arrow(X[x],  #x1\n",
-    "              Y[x],  # y1\n",
-    "              U[x]-X[x], # x2 - x1\n",
-    "              V[x]-Y[x], # y2 - y1\n",
-    "              fc=\"k\", ec=\"k\", head_width=0.05, head_length=0.1)\n",
-    "plt.xlim([-510,550])\n",
-    "plt.ylim([-510,550])\n",
-    "plt.title('Example of 50 random vectors with constrained origins')\n",
-    "plt.show()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 247,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYMAAAEKCAYAAADw2zkCAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAGktJREFUeJzt3X+4HFV5wPHvkoQKJheShkISCJeCVGMt2BaUonVbKwWt\nRPtDASuh0FZrH6Van0LQlotVfrWiba22VYGgEIpaKVCxAmUFrWK1qECgkJRIAkkUEklQ2oK5/eM9\ny86duz9m793Z3Zt8P8+zz52dmZ15d+aceeecmbkLkiRJkiRJkiRJkiRJkiRJUuk+Ary7R8taCuwA\nKul9DTijR8sG+Bzwxh4ur6j3At8DHhnAugflcuDP+7zOY4EHiDJ0Yp/X3Q81elsf1HuX07tyPwZ8\nokfLesYeU/zceuCHwHZgG/Bl4E00DtYAf0Ac7Ios65c7zPMQMA8YT+/HM8PdGmPyhnxlk3FlWwq8\nA3gu [...]
-      "text/plain": [
-       "<matplotlib.figure.Figure at 0x11311fd90>"
-      ]
-     },
-     "metadata": {},
-     "output_type": "display_data"
-    },
-    {
-     "data": {
-      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXoAAAEKCAYAAAAcgp5RAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAHZFJREFUeJzt3X+cHWV96PHPkhB+Q0zwhvwAQoGIsVCx8sNS6mJtbsrV\nJK96L6C1pDX12qZVr7dVSK+apFpF+0PstXhbFAgUolGvEX0pJUZO660KoiDCGpMgW1wgCxtoiEZq\nMHv/+D7jmT05Z8/M7jm7yfB5v17ndebMzJl55pmZ7/PMM3POA5IkSZIkSZIkSZIkSZIkSTrAfRR4\nZ4eWdRKwG+hJn2vAig4tG+CLwO90cHlFvRd4Anh0EtadmQ/sAw6Z4PVeDzwJfGOC1zsReoEfTnYi\nNKr5dPa43wf8QoeWdcDoB/YATwNPAf8KvIl6IC67rFeU/M4dwBvGsC6ANcBNY/xuJ51E5OHMSU7H\nfCY+ [...]
-      "text/plain": [
-       "<matplotlib.figure.Figure at 0x111894450>"
-      ]
-     },
-     "metadata": {},
-     "output_type": "display_data"
-    }
-   ],
-   "source": [
-    "#Method A random\n",
-    "plt.hist(dest_A_rand_I, bins = 25)\n",
-    "plt.title('Distribution of VMD I values from random vectors - Method A')\n",
-    "plt.show()\n",
-    "plt.hist(dest_A_rand_p, bins = 25)\n",
-    "plt.title('Distribution of p values from random vectors - Method A')\n",
-    "plt.show()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 248,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZYAAAEKCAYAAAAxXHOuAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAHFVJREFUeJzt3Xu0XFWd4PHvNQkgjwvEIJCEEAakAZeiToPQNG219tDQ\nKjA9qxVxIGkcR5tZ6PKxmsd0y9VRoLW1sZcjzlIeQSGKOtJA+wBsqnmIOLgiAjFKAkgCSXhDQEAe\nd/747aLOrVvP1K7HrXw/a9W6p17n/M45++zf2XufUxckSZIkSZIkSZIkSZIkSZIkqafOA/4u07wW\nAZuAsfS8DLwv07wBvg+ckHF+7fo08BDwwACWPSgXAf+rz8s8DLiLKENH93nZM1Ht8ZbTBPD1Hsx3\nS7cUuCHTvErA2kzzetkr2vjMvcDvgCeBx4CbgA8wtSD+DVFxtjOvt7b4zH3ADsBkej5ZmO7UBNML\n9l/U [...]
-      "text/plain": [
-       "<matplotlib.figure.Figure at 0x1107ec450>"
-      ]
-     },
-     "metadata": {},
-     "output_type": "display_data"
-    },
-    {
-     "data": {
-      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYcAAAEKCAYAAAD5MJl4AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAGgRJREFUeJzt3Xu8XGV97/HPkIRLEkJMackNEk6QI/Fl0V1F0FJ2LYdS\nROD0tICXNlZqbfHltVpIq7Jje/ByaqG2pfXIxYAmCqgULfUF0kxtS+VSgQIxzaXEmGA2ECAJiVgi\nu3/8nnHWnmdm79mz9uy9s/N5v17z2jPrMut5Zj3r+a71rJkEJEmSJEmSJEmSJEmSJEmSpAPOXwMf\nGqX3OgbYDVTS6ypw0Si9N8BtwG+M4vu160+AJ4DHxmHbNYuBF4CDxni71wFPAd8e4+3ur0bzeGr0\nAvA/uvTeB7LNwC+N0ntVGd0+r2s2A3uBXcDTwL8A76DeeY/0vV43wnXWAG/rYFsAfcANHa47mo4h\nPsOf [...]
-      "text/plain": [
-       "<matplotlib.figure.Figure at 0x10dab2bd0>"
-      ]
-     },
-     "metadata": {},
-     "output_type": "display_data"
-    }
-   ],
-   "source": [
-    "#Method A constricted\n",
-    "plt.hist(dest_A_cons_I, bins=25)\n",
-    "plt.title('Distribution of VMD I values from constrained vectors - Method A')\n",
-    "plt.show()\n",
-    "plt.hist(dest_A_cons_p, bins=25)\n",
-    "plt.title('Distribution of p values from constrained vectors - Method A')\n",
-    "plt.show()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 249,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYIAAAEKCAYAAAAfGVI8AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAGs5JREFUeJzt3X20JGV94PFvw0AEZy7MZAzMDAyXBYmOx6jZBSXo2okr\nAY1gkrMKGoVANrruUTbGs7xowiVR3hLRJCbuRgUGgSGgKwEiRiC04BuuHlReA0wYYWBmFBiZQdGA\nc/eP39N23b79Un1vv915vp9z+tzqquqqX1c9T/3qearqNkiSJEmSJEmSJEmSJEmSJEl983HgA31a\n1mpgO1BJ72vAyX1aNsDngbf1cXllfRD4AfDoCNY9KhcDfz7kdR4B3E+UoWOGvO5hqNHf+qD+u5j+\nlfsp4NN9Wha7zOOzG4AfA9uArcBXgHfQOFAD/HfiQFdmWb/RZZ6HgCXAdHo/XRju1RSzN+LrWowb\ntNXA [...]
-      "text/plain": [
-       "<matplotlib.figure.Figure at 0x1147fb650>"
-      ]
-     },
-     "metadata": {},
-     "output_type": "display_data"
-    },
-    {
-     "data": {
-      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXQAAAEKCAYAAAACS67iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAGGtJREFUeJzt3Xu4HVV9h/H3kHBRIGDEhkggoWAQLBSQq5R6pNEiVeDR\nFi9Vo1Kr1aIPtXKxKge1gpd6K2otCAQEJOgjt3oBIlG8gKAgchckIkIChBgiEI3k9I/fGvecffY+\nZ/bl7H3Oyvt5nv1k75m9Z9asmfnOmjUzJyBJkiRJkiRJkiRJkiRJkpS9LwDv69K0dgDWAAPp81Lg\n6C5NG+AbwOu7OL2qPgw8DDzQh3kX5gHrgY16PN+zgEeBa3s8314YBH7d70JoTPPo7na/HvjzLk2r\n55YBTwCPAauAHwBvpRa4rU7rkBZ/czXw5jbmBTAEnNvmb7tpB6IOn9nncsyj94F+MBF4m/Vwnr00\nyNQO [...]
-      "text/plain": [
-       "<matplotlib.figure.Figure at 0x1135d5e50>"
-      ]
-     },
-     "metadata": {},
-     "output_type": "display_data"
-    }
-   ],
-   "source": [
-    "#Method B random\n",
-    "plt.hist(dest_B_rand_I, bins=25)\n",
-    "plt.title('Distribution of VMD I values from random vectors - Method B')\n",
-    "plt.show()\n",
-    "plt.hist(dest_B_rand_p, bins=25)\n",
-    "plt.title('Distribution of p values from random vectors - Method B')\n",
-    "plt.show()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 250,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZUAAAEKCAYAAADaa8itAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAHGxJREFUeJzt3X20XGV96PHvMQkihAPEIJBACA1SxCW+3IJQynWqXRR8\nIbZdVcSLpHi9WrrQVXWVl1o5eBWoXi3t8oJdyktQiGKtXqC+AMKUFzFeXBGBGCEBJAES3iFBVCCn\nf/yeYfaZM69nnjMvJ9/PWrPOnpk9e//27Gc/v/08z95zQJIkSZIkSZIkSZIkSZIkSZK6dj7wiUzL\nWgRsBkbS8zLw/kzLBvgucHzG5bXr08AjwIN9WHe/XAz87x6v83DgbqIMHdPjdQ+j2uMtpzHgq9Ow\n3G3dMuDGTMsqAeszLQuAl7Qxz33Ar4GngSeAm4EPMrEQ/jVRabazrDe3mOd+YCdgPD0fL0x3aozJ\nhfqt [...]
-      "text/plain": [
-       "<matplotlib.figure.Figure at 0x10b837690>"
-      ]
-     },
-     "metadata": {},
-     "output_type": "display_data"
-    },
-    {
-     "data": {
-      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXsAAAEKCAYAAADzQPVvAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAGcRJREFUeJzt3X2YJFV96PHv7C4I7jIsG8yy8rJrEAR8fMEExRiT0aCX\nEAViEny/q5LEJD6aa6IBjYYhNxc010Q0rz4RcUVBUSMiUS/ruhOJIEoCGEWCbFgBYQdYFvYNDcrc\nP36n7Jqe7unqmZ7qnj7fz/P0M9X1dk6dOvWrU6eqekCSJEmSJEmSJEmSJEmSJEl98PfAO3q0riOA\nXcBI+j4BnNmjdQN8Hnh1D9dX1Z8D9wF39yHtwjrgUWBJzeleBDwAfK3mdBerXh5PzR4FfmaB1p2z\nrcAv92hdE/Q25lW2FdgL7AR2AF8FXk8jGHe7rud3ucxm4HVzSAtgHLh4jsv20hFEGf5Un/OxjvqD\n/XOB [...]
-      "text/plain": [
-       "<matplotlib.figure.Figure at 0x10d5c07d0>"
-      ]
-     },
-     "metadata": {},
-     "output_type": "display_data"
-    }
-   ],
-   "source": [
-    "#Method B constricted\n",
-    "plt.hist(dest_B_cons_I, bins=25)\n",
-    "plt.title('Distribution of VMD I values from constrained vectors - Method B')\n",
-    "plt.show()\n",
-    "plt.hist(dest_B_cons_p, bins=25)\n",
-    "plt.title('Distribution of p values from constrained vectors - Method B')\n",
-    "plt.show()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 245,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "a\n"
-     ]
-    }
-   ],
-   "source": [
-    "print 'a'"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "collapsed": true
-   },
-   "outputs": [],
-   "source": []
-  }
- ],
- "metadata": {
-  "kernelspec": {
-   "display_name": "Python [Root]",
-   "language": "python",
-   "name": "Python [Root]"
-  },
-  "language_info": {
-   "codemirror_mode": {
-    "name": "ipython",
-    "version": 2
-   },
-   "file_extension": ".py",
-   "mimetype": "text/x-python",
-   "name": "python",
-   "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython2",
-   "version": "2.7.12"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 0
-}
diff --git a/pysal/contrib/spint/notebooks/validate_gravity.ipynb b/pysal/contrib/spint/notebooks/validate_gravity.ipynb
index 4eace91..f95e876 100644
--- a/pysal/contrib/spint/notebooks/validate_gravity.ipynb
+++ b/pysal/contrib/spint/notebooks/validate_gravity.ipynb
@@ -2,7 +2,7 @@
  "cells": [
   {
    "cell_type": "code",
-   "execution_count": 1,
+   "execution_count": 75,
    "metadata": {
     "collapsed": false
    },
@@ -17,16 +17,16 @@
     "sys.path.append('/Users/toshan/dev/pysal/pysal/contrib/spint')\n",
     "from gravity import Gravity, Production, Attraction, Doubly, BaseGravity\n",
     "import gravity\n",
-    "from spint_utils import sorensen\n",
+    "from utils import sorensen\n",
     "import statsmodels.formula.api as smf\n",
     "from statsmodels.api import families as families"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 2,
+   "execution_count": 32,
    "metadata": {
-    "collapsed": true
+    "collapsed": false
    },
    "outputs": [],
    "source": [
@@ -37,12 +37,12 @@
     "d = austria['Destination'].values\n",
     "dij = austria['Dij'].values\n",
     "o_vars = austria['Oi2007'].values\n",
-    "d_vars = austria['Dj2007'].values"
+    "d_vars = austria['Dj2007'].values\n"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 3,
+   "execution_count": 33,
    "metadata": {
     "collapsed": false
    },
@@ -51,22 +51,22 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "[ 0.44051324  0.5144978  -0.00976746]\n",
-      "[ 0.44051324  0.5144978  -0.00976746]\n"
+      "[ -7.95447436e+00   8.63867812e-01   8.80474585e-01  -6.20544765e-03]\n",
+      "[ -7.95447436e+00   8.63867812e-01   8.80474585e-01  -6.20544766e-03]\n"
      ]
     }
    ],
    "source": [
-    "grav = Gravity(f, o_vars, d_vars, dij, 'exp', framework='glm')\n",
+    "grav = Gravity(f, o_vars, d_vars, dij, 'exp', framework='glm', constant=True)\n",
     "print grav.params\n",
     "\n",
-    "gravity = smf.glm('Data~np.log(Oi2007)+np.log(Dj2007)+Dij-1', family=families.Poisson(), data=austria).fit()\n",
+    "gravity = smf.glm('Data~np.log(Oi2007)+np.log(Dj2007)+Dij', family=families.Poisson(), data=austria).fit()\n",
     "print gravity.params.values"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 4,
+   "execution_count": 35,
    "metadata": {
     "collapsed": false,
     "scrolled": false
@@ -76,10 +76,10 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "[-1.11700938  0.5696138   1.03487752 -0.51400641 -0.23320154  0.09225167\n",
-      " -0.42761955  0.03771866 -0.0922097   0.89278717 -0.00727113]\n",
-      "[-1.11700938  0.56961379  1.03487751 -0.51400641 -0.23320154  0.09225166\n",
-      " -0.42761955  0.03771866 -0.0922097   0.89278717 -0.00727113]\n"
+      "[-1.11700938  1.68662317  2.15188689  0.60300297  0.88380784  1.20926104\n",
+      "  0.68938983  1.15472804  1.02479968  0.89278717 -0.00727113]\n",
+      "[-1.11700938  1.68662317  2.15188689  0.60300297  0.88380784  1.20926105\n",
+      "  0.68938983  1.15472805  1.02479968  0.89278717 -0.00727113]\n"
      ]
     }
    ],
@@ -87,7 +87,7 @@
     "production = Production(f, o, d_vars, dij, 'exp', framework='glm')\n",
     "print production.params\n",
     "\n",
-    "gravity = smf.glm('Data~Origin+np.log(Dj2007)+Dij-1', family=families.Poisson(), data=austria).fit()\n",
+    "gravity = smf.glm('Data~Origin+np.log(Dj2007)+Dij', family=families.Poisson(), data=austria).fit()\n",
     "print gravity.params.values"
    ]
   },
@@ -102,18 +102,18 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "[-0.88439723  0.73740882  1.04332355 -0.75977722 -0.26060911 -0.1879365\n",
-      " -0.67530313 -0.19871953 -0.39900098  0.89235874 -0.00693755]\n",
-      "[-0.88439723  0.73740882  1.04332355 -0.75977722 -0.26060911 -0.1879365\n",
-      " -0.67530313 -0.19871953 -0.39900099  0.89235874 -0.00693755]\n"
+      "[-0.88439723  1.62180605  1.92772078  0.12462001  0.62378812  0.69646073\n",
+      "  0.20909411  0.6856777   0.48539625  0.89235874 -0.00693755]\n",
+      "[-0.88439723  1.62180605  1.92772078  0.12462002  0.62378812  0.69646073\n",
+      "  0.20909411  0.6856777   0.48539625  0.89235874 -0.00693755]\n"
      ]
     }
    ],
    "source": [
-    "attraction = Attraction(f, d, o_vars, dij, 'exp', framework='glm')\n",
+    "attraction = Attraction(f, d, o_vars, dij, 'exp', framework='glm', constant=True)\n",
     "print attraction.params\n",
     "\n",
-    "gravity = smf.glm('Data~np.log(Oi2007)+Destination + Dij-1', family=families.Poisson(), data=austria).fit()\n",
+    "gravity = smf.glm('Data~np.log(Oi2007)+Destination + Dij', family=families.Poisson(), data=austria).fit()\n",
     "print gravity.params.values"
    ]
   },
@@ -121,823 +121,29 @@
    "cell_type": "code",
    "execution_count": 6,
    "metadata": {
-    "collapsed": false
+    "collapsed": false,
+    "scrolled": true
    },
    "outputs": [
     {
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "[-0.00791533]\n",
-      "[-0.00791533]\n"
+      "[ 6.20471518  1.5449095   2.4414292   0.69924374  0.94869185  1.28967637\n",
+      "  0.74270015  1.19468573  0.98874193  1.49709841  2.18492741  0.18784818\n",
+      "  0.66434515  0.74264938  0.21334535  0.66765781  0.39986094 -0.00791533]\n",
+      "[ 6.20471518  1.5449095   2.4414292   0.69924374  0.94869185  1.28967637\n",
+      "  0.74270016  1.19468574  0.98874192  1.49709841  2.18492741  0.18784818\n",
+      "  0.66434515  0.74264938  0.21334535  0.66765782  0.39986087 -0.00791533]\n"
      ]
     }
    ],
    "source": [
-    "doubly = Doubly(f, o, d, dij, 'exp', framework='glm')\n",
-    "print doubly.params[-1:]\n",
+    "doubly = Doubly(f, o, d, dij, 'exp', framework='glm', constant=True)\n",
+    "print doubly.params\n",
     "\n",
-    "gravity = smf.glm('Data~Origin+Destination+Dij-1', family=families.Poisson(), data=austria).fit()\n",
-    "print gravity.params.values[-1:]"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 7,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "0.68822035942795623"
-      ]
-     },
-     "execution_count": 7,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "sorensen(grav)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 8,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "0.74061920338298048"
-      ]
-     },
-     "execution_count": 8,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "sorensen(production)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 9,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "0.75063449829283135"
-      ]
-     },
-     "execution_count": 9,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "sorensen(attraction)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 10,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "0.81185211090388831"
-      ]
-     },
-     "execution_count": 10,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "sorensen(doubly)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 11,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "0.68822035942795623"
-      ]
-     },
-     "execution_count": 11,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "grav.SSI"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 12,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "0.74061920338298048"
-      ]
-     },
-     "execution_count": 12,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "production.SSI"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 13,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "0.75063449829283135"
-      ]
-     },
-     "execution_count": 13,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "attraction.SSI"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 14,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "0.81185211090388831"
-      ]
-     },
-     "execution_count": 14,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "doubly.SSI"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 15,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "23.103958298546722"
-      ]
-     },
-     "execution_count": 15,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "grav.srmse"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 16,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "26.41275121188659"
-      ]
-     },
-     "execution_count": 16,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "doubly.srmse"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 17,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "26.023881688328146"
-      ]
-     },
-     "execution_count": 17,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "production.srmse"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 18,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "0.81258943875040157"
-      ]
-     },
-     "execution_count": 18,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "grav.pseudoR2"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 19,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "0.9099205901109565"
-      ]
-     },
-     "execution_count": 19,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "production.pseudoR2"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 20,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "0.94353991219813327"
-      ]
-     },
-     "execution_count": 20,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "doubly.pseudoR2\n"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 21,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "0.81255536218830349"
-      ]
-     },
-     "execution_count": 21,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "grav.adj_pseudoR2"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 21,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "0.83445652029136452"
-      ]
-     },
-     "execution_count": 21,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "grav.D2"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 22,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "0.82965815856067948"
-      ]
-     },
-     "execution_count": 22,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "grav.adj_D2"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 23,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "0.94666192089648937"
-      ]
-     },
-     "execution_count": 23,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "doubly.D2"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 24,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "0.92987030340093968"
-      ]
-     },
-     "execution_count": 24,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "doubly.adj_D2"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 123,
-   "metadata": {
-    "collapsed": true
-   },
-   "outputs": [],
-   "source": [
-    "y = grav.y\n",
-    "yhat = grav.yhat\n",
-    "n = grav.n"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 124,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "28741.324123392122"
-      ]
-     },
-     "execution_count": 124,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "(np.sum((yhat-y)**2)/n)**.5"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 125,
-   "metadata": {
-    "collapsed": true
-   },
-   "outputs": [],
-   "source": [
-    "y = production.y\n",
-    "yhat = production.yhat\n",
-    "n = production.n\n"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 126,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "32373.708820280212"
-      ]
-     },
-     "execution_count": 126,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "np.sqrt(np.sum((y-yhat)**2)/n) \n"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 127,
-   "metadata": {
-    "collapsed": true
-   },
-   "outputs": [],
-   "source": [
-    "y = doubly.y\n",
-    "yhat = doubly.yhat\n",
-    "n = doubly.n"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 128,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "32857.462507586919"
-      ]
-     },
-     "execution_count": 128,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "np.sqrt(np.sum((y-yhat)**2)/n) "
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 39,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "72"
-      ]
-     },
-     "execution_count": 39,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "len(doubly.y)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 41,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "72"
-      ]
-     },
-     "execution_count": 41,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "doubly.n"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 42,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "1244.0972222222222"
-      ]
-     },
-     "execution_count": 42,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "np.mean(doubly.y)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 46,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "3872.2890919495749"
-      ]
-     },
-     "execution_count": 46,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "np.sqrt(np.mean((y-yhat)**2))"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 47,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "array([  9.78988280e+02,   2.26003279e+03,   1.04038742e+02,\n",
-       "         3.38382580e+02,   1.90458075e+02,   8.67908467e+01,\n",
-       "         4.37554720e+01,   1.35532201e+01,   1.02693176e+03,\n",
-       "         1.43579537e+04,   5.02646536e+02,   1.61314478e+03,\n",
-       "         1.60124044e+03,   5.84144805e+02,   2.98377549e+02,\n",
-       "         9.55604104e+01,   2.92086883e+03,   1.76899160e+04,\n",
-       "         9.49267467e+02,   3.14910952e+03,   2.73315395e+03,\n",
-       "         1.01972797e+03,   5.15779061e+02,   1.64177257e+02,\n",
-       "         1.73496758e+02,   7.99088484e+02,   1.22486311e+03,\n",
-       "         9.31563443e+02,   6.29698756e+02,   5.91117070e+02,\n",
-       "         4.15424488e+02,   1.31747905e+02,   4.49674437e+02,\n",
-       "         2.04361676e+03,   3.23802841e+03,   7.42345992e+02,\n",
-       "         1.00234547e+03,   6.00432512e+02,   3.13590596e+02,\n",
-       "         9.69658353e+01,   3.29132064e+02,   2.63792996e+03,\n",
-       "         3.65458094e+03,   6.52540343e+02,   1.30346098e+03,\n",
-       "         1.16517842e+03,   6.73203489e+02,   2.21973821e+02,\n",
-       "         1.47356669e+02,   9.45479887e+02,   1.33962391e+03,\n",
-       "         6.01828982e+02,   7.67131590e+02,   1.14476805e+03,\n",
-       "         6.43385796e+02,   2.00425139e+02,   7.41169755e+01,\n",
-       "         4.81822820e+02,   6.76007805e+02,   4.21969575e+02,\n",
-       "         3.99722086e+02,   6.59873779e+02,   6.41890452e+02,\n",
-       "         9.85596546e+02,   2.44225078e+01,   1.64157859e+02,\n",
-       "         2.28909306e+02,   1.42362371e+02,   1.31485029e+02,\n",
-       "         2.31461478e+02,   2.12717926e+02,   1.04848355e+03])"
-      ]
-     },
-     "execution_count": 47,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "yhat"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 64,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "26.799427831357789"
-      ]
-     },
-     "execution_count": 64,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "np.sqrt(np.sum(((y-yhat)**2)/n)) / np.sum(y/n)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 90,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "0.005019646605929266"
-      ]
-     },
-     "execution_count": 90,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "np.sqrt(np.sum((y-yhat)**2)/n) / np.sum(y)/float(n)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 88,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "1244.0972222222222"
-      ]
-     },
-     "execution_count": 88,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "np.sum(y)/float(n)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 86,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "1244.0972222222222"
-      ]
-     },
-     "execution_count": 86,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "np.mean(y)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 130,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "nan"
-      ]
-     },
-     "execution_count": 130,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "np.nan * -1"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 132,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "False"
-      ]
-     },
-     "execution_count": 132,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "np.nan == np.nan"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "collapsed": true
-   },
-   "outputs": [],
-   "source": [
-    "np"
+    "gravity = smf.glm('Data~Origin+Destination+Dij', family=families.Poisson(), data=austria).fit()\n",
+    "print gravity.params.values"
    ]
   }
  ],
diff --git a/pysal/contrib/spint/primer/SpIntPrimer.pdf b/pysal/contrib/spint/primer/SpIntPrimer.pdf
new file mode 100644
index 0000000..602b6b1
Binary files /dev/null and b/pysal/contrib/spint/primer/SpIntPrimer.pdf differ
diff --git a/pysal/contrib/spint/primer/austria.csv b/pysal/contrib/spint/primer/austria.csv
new file mode 100644
index 0000000..65ba89e
--- /dev/null
+++ b/pysal/contrib/spint/primer/austria.csv
@@ -0,0 +1,82 @@
+,Origin,Destination,Data,Oi,Dj,Dij
+0,AT11,AT11,0,4016,5146,1e-300
+1,AT11,AT12,1131,4016,25741,103.001845
+2,AT11,AT13,1887,4016,26980,84.204666
+3,AT11,AT21,69,4016,4117,220.811933
+4,AT11,AT22,738,4016,8634,132.00748
+5,AT11,AT31,98,4016,8193,214.511814
+6,AT11,AT32,31,4016,4902,246.933305
+7,AT11,AT33,43,4016,3952,390.85611
+8,AT11,AT34,19,4016,1910,505.089539
+9,AT12,AT11,1633,20080,5146,103.001845
+10,AT12,AT12,0,20080,25741,1e-300
+11,AT12,AT13,14055,20080,26980,45.796272
+12,AT12,AT21,416,20080,4117,216.994739
+13,AT12,AT22,1276,20080,8634,129.878172
+14,AT12,AT31,1850,20080,8193,140.706671
+15,AT12,AT32,388,20080,4902,201.232355
+16,AT12,AT33,303,20080,3952,343.50075
+17,AT12,AT34,159,20080,1910,453.515594
+18,AT13,AT11,2301,29142,5146,84.204666
+19,AT13,AT12,20164,29142,25741,45.796272
+20,AT13,AT13,0,29142,26980,1e-300
+21,AT13,AT21,1080,29142,4117,249.932874
+22,AT13,AT22,1831,29142,8634,158.630661
+23,AT13,AT31,1943,29142,8193,186.420738
+24,AT13,AT32,742,29142,4902,244.108305
+25,AT13,AT33,674,29142,3952,387.61776
+26,AT13,AT34,407,29142,1910,498.407152
+27,AT21,AT11,85,4897,5146,220.811933
+28,AT21,AT12,379,4897,25741,216.994739
+29,AT21,AT13,1597,4897,26980,249.932874
+30,AT21,AT21,0,4897,4117,1e-300
+31,AT21,AT22,1608,4897,8634,92.407958
+32,AT21,AT31,328,4897,8193,151.777157
+33,AT21,AT32,317,4897,4902,92.894408
+34,AT21,AT33,469,4897,3952,194.851669
+35,AT21,AT34,114,4897,1910,306.105825
+36,AT22,AT11,762,8487,5146,132.00748
+37,AT22,AT12,1110,8487,25741,129.878172
+38,AT22,AT13,2973,8487,26980,158.630661
+39,AT22,AT21,1252,8487,4117,92.407958
+40,AT22,AT22,0,8487,8634,1e-300
+41,AT22,AT31,1081,8487,8193,124.563096
+42,AT22,AT32,622,8487,4902,122.433524
+43,AT22,AT33,425,8487,3952,261.893783
+44,AT22,AT34,262,8487,1910,376.34667
+45,AT31,AT11,196,10638,5146,214.511814
+46,AT31,AT12,2027,10638,25741,140.706671
+47,AT31,AT13,3498,10638,26980,186.420738
+48,AT31,AT21,346,10638,4117,151.777157
+49,AT31,AT22,1332,10638,8634,124.563096
+50,AT31,AT31,0,10638,8193,1e-300
+51,AT31,AT32,2144,10638,4902,81.753652
+52,AT31,AT33,821,10638,3952,208.456383
+53,AT31,AT34,274,10638,1910,314.793199
+54,AT32,AT11,49,5790,5146,246.933305
+55,AT32,AT12,378,5790,25741,201.232355
+56,AT32,AT13,1349,5790,26980,244.108305
+57,AT32,AT21,310,5790,4117,92.894408
+58,AT32,AT22,851,5790,8634,122.433524
+59,AT32,AT31,2117,5790,8193,81.753652
+60,AT32,AT32,0,5790,4902,1e-300
+61,AT32,AT33,630,5790,3952,145.076472
+62,AT32,AT34,106,5790,1910,258.591197
+63,AT33,AT11,87,4341,5146,390.85611
+64,AT33,AT12,424,4341,25741,343.50075
+65,AT33,AT13,978,4341,26980,387.61776
+66,AT33,AT21,490,4341,4117,194.851669
+67,AT33,AT22,670,4341,8634,261.893783
+68,AT33,AT31,577,4341,8193,208.456383
+69,AT33,AT32,546,4341,4902,145.076472
+70,AT33,AT33,0,4341,3952,1e-300
+71,AT33,AT34,569,4341,1910,114.46325
+72,AT34,AT11,33,2184,5146,505.089539
+73,AT34,AT12,128,2184,25741,453.515594
+74,AT34,AT13,643,2184,26980,498.407152
+75,AT34,AT21,154,2184,4117,306.105825
+76,AT34,AT22,328,2184,8634,376.34667
+77,AT34,AT31,199,2184,8193,314.793199
+78,AT34,AT32,112,2184,4902,258.591197
+79,AT34,AT33,587,2184,3952,114.46325
+80,AT34,AT34,0,2184,1910,1e-300
diff --git a/pysal/contrib/spint/primer/austria.dbf b/pysal/contrib/spint/primer/austria.dbf
new file mode 100644
index 0000000..0eb927e
Binary files /dev/null and b/pysal/contrib/spint/primer/austria.dbf differ
diff --git a/pysal/contrib/spint/primer/austria.prj b/pysal/contrib/spint/primer/austria.prj
new file mode 100644
index 0000000..2ba7b2c
--- /dev/null
+++ b/pysal/contrib/spint/primer/austria.prj
@@ -0,0 +1 @@
+GEOGCS["ETRS89",DATUM["D_ETRS_1989",SPHEROID["GRS_1980",6378137,298.257222101]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
\ No newline at end of file
diff --git a/pysal/contrib/spint/primer/austria.qpj b/pysal/contrib/spint/primer/austria.qpj
new file mode 100644
index 0000000..ca0b0e8
--- /dev/null
+++ b/pysal/contrib/spint/primer/austria.qpj
@@ -0,0 +1 @@
+GEOGCS["ETRS89",DATUM["European_Terrestrial_Reference_System_1989",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6258"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4258"]]
diff --git a/pysal/contrib/spint/primer/austria.shp b/pysal/contrib/spint/primer/austria.shp
new file mode 100644
index 0000000..3ba11e3
Binary files /dev/null and b/pysal/contrib/spint/primer/austria.shp differ
diff --git a/pysal/contrib/spint/primer/austria.shx b/pysal/contrib/spint/primer/austria.shx
new file mode 100644
index 0000000..ec3fe93
Binary files /dev/null and b/pysal/contrib/spint/primer/austria.shx differ
diff --git a/pysal/contrib/spint/tests/test_count_model.py b/pysal/contrib/spint/tests/test_count_model.py
index 4aed5fc..e15243f 100644
--- a/pysal/contrib/spint/tests/test_count_model.py
+++ b/pysal/contrib/spint/tests/test_count_model.py
@@ -78,7 +78,7 @@ class TestCountModel(unittest.TestCase):
                 -10.28910294])
         self.assertAlmostEqual(results.deviance, 230.46013824817649)
         self.assertAlmostEqual(results.llf, -247.42592089969378)
-        self.assertAlmostEqual(results.aic, 500.85184179938756)
+        self.assertAlmostEqual(results.AIC, 500.85184179938756)
         self.assertAlmostEqual(results.D2, 0.388656011675)
         self.assertAlmostEqual(results.adj_D2, 0.36207583826952761)
 
diff --git a/pysal/contrib/spint/tests/test_gravity.py b/pysal/contrib/spint/tests/test_gravity.py
index 8afb0f7..c37fd42 100644
--- a/pysal/contrib/spint/tests/test_gravity.py
+++ b/pysal/contrib/spint/tests/test_gravity.py
@@ -87,9 +87,9 @@ class TestGravity(unittest.TestCase):
     def test_BaseGravity_exp(self):
         f = np.array(self.f).reshape((-1,1))
         dij = np.array(self.dij).reshape((-1,1))
-        model = grav.BaseGravity(f, dij, 'exp')
+        model = grav.BaseGravity(f, dij, 'exp', constant=False)
         np.testing.assert_allclose(model.params, [0.01641585], atol = .0001)
-        self.assertAlmostEqual(model.aic, 957622.28429746185, delta = .0001)
+        self.assertAlmostEqual(model.AIC, 957622.28429746185, delta = .0001)
         np.testing.assert_allclose(model.cov_params, [[  1.92096665e-10]])
         self.assertAlmostEqual(model.deviance, 1087408.9707170483, delta = .0001)
         self.assertAlmostEqual(model.llf, -478810.14214873099, delta = .0001)
@@ -126,9 +126,9 @@ class TestGravity(unittest.TestCase):
     def test_BaseGravity_pow(self):
         f = np.array(self.f).reshape((-1,1))
         dij = np.array(self.dij).reshape((-1,1))
-        model = grav.BaseGravity(f, dij, 'pow')
+        model = grav.BaseGravity(f, dij, 'pow', constant=False)
         np.testing.assert_allclose(model.params, [ 1.27223738], atol = .0001)
-        self.assertAlmostEqual(model.aic, 377298.04716333596, delta = .0001)
+        self.assertAlmostEqual(model.AIC, 377298.04716333596, delta = .0001)
         np.testing.assert_allclose(model.cov_params, [[  4.31955426e-07]])
         self.assertAlmostEqual(model.deviance, 409811.34329065739, delta = .0001)
         self.assertAlmostEqual(model.llf, -188648.02358166798, delta = .0001)
@@ -159,9 +159,9 @@ class TestGravity(unittest.TestCase):
     def test_QuasiPoisson(self):
         f = np.array(self.f).reshape((-1,1))
         dij = np.array(self.dij).reshape((-1,1))
-        model = grav.BaseGravity(f, dij, 'exp', Quasi=True)
+        model = grav.BaseGravity(f, dij, 'exp', constant=False, Quasi=True)
         np.testing.assert_allclose(model.params, [0.01641585], atol = .0001)
-        self.assertTrue(math.isnan(model.aic))
+        self.assertTrue(math.isnan(model.AIC))
         np.testing.assert_allclose(model.cov_params, [[ 0.00079749]],
                 atol=1.0e-8)
         self.assertAlmostEqual(model.deviance, 1087408.9707170483, delta = .0001)
@@ -198,47 +198,53 @@ class TestGravity(unittest.TestCase):
     
     def test_Gravity(self):
         model = grav.Gravity(self.f, self.o_var, self.d_var,
-                self.dij, 'exp')
-        np.testing.assert_allclose(model.params, [ 0.44051324,  0.5144978,
-            -0.00976746])
-        self.assertAlmostEqual(model.aic, 33004.1458886, delta = .0001)
-        np.testing.assert_allclose(model.cov_params, [[  1.12101850e-05,
-            -1.09133569e-05,  -1.44593711e-08],
-            [ -1.09133569e-05,   1.10801323e-05,  -1.23580963e-08],
-            [ -1.44593711e-08,  -1.23580963e-08,   2.11497156e-09]])
-        self.assertAlmostEqual(model.deviance, 29051.791954, delta = .0001)
-        self.assertAlmostEqual(model.llf, -16499.0729443, delta = .0001)
+                self.dij, 'exp', constant=True)
+        np.testing.assert_allclose(model.params, [ -7.95447436e+00,
+            8.63867812e-01,   8.80474585e-01, -6.20544765e-03])
+        self.assertAlmostEqual(model.AIC, 20395.085388908723, delta = .0001)
+        np.testing.assert_allclose(model.cov_params,
+        [[  5.70906352e-03,  -3.00814799e-04,  -2.62650384e-04,
+         -2.40317578e-06],
+       [ -3.00814799e-04,   2.67121974e-05,   3.21466745e-06,
+          1.16544737e-07],
+       [ -2.62650384e-04,   3.21466745e-06,   2.28600781e-05,
+          9.94368232e-08],
+       [ -2.40317578e-06,   1.16544737e-07,   9.94368232e-08,
+          2.68830005e-09]])
+        self.assertAlmostEqual(model.deviance, 19806.408696637576, delta = .0001)
+        self.assertAlmostEqual(model.llf, -10193.542694454361, delta = .0001)
         self.assertAlmostEqual(model.llnull, -88037.0499629, delta = .0001)
-        np.testing.assert_allclose(model.pvalues, [0., 0., 0.])
-        np.testing.assert_allclose(model.std_err, [  3.34816144e-03,   3.32868327e-03,
-            4.59888200e-05])
-        np.testing.assert_allclose(model.tvalues, [ 131.5686976,   154.56496075,
-            -212.38771233])
+        np.testing.assert_allclose(model.pvalues, [0., 0., 0., 0.])
+        np.testing.assert_allclose(model.std_err, 
+         [  7.55583451e-02,   5.16838440e-03,   4.78122141e-03,
+         5.18488192e-05])
+        np.testing.assert_allclose(model.tvalues, 
+         [-105.27592086,  167.14465196,  184.15264854, -119.68349034])
         np.testing.assert_allclose(model.yhat, 
-            [  2791.71294459,   3450.9181662 ,    344.35367686,   1195.8168102 ,
-            519.06514371,    285.39822879,     62.00029499,     14.46008341,
-            2476.40288126,  10178.48689237,    724.46765915,   2474.67971095,
-            2163.32521114,    903.92942165,    199.56985231,     48.50282363,
-            3472.5689778 ,  11546.46123418,    612.90019043,   2180.94678642,
-            1615.46535168,    693.98410032,    151.37195314,     36.51168734,
-            412.74282775,    978.91114569,    730.04284105,   1879.61605356,
-            1022.73834302,   1371.83645825,    449.01488086,    107.81413822,
-            1259.84153016,   2939.13628073,   2283.39010725,   1652.13526474,
-            1710.55604408,   1318.04651914,    299.09085631,     69.60641198,
-            629.16274459,   2956.0542728 ,   1945.9091469 ,   1034.2626935 ,
-            1968.00942356,   2192.39883984,    563.51931891,    141.96553438,
-            346.7081784 ,   1237.93201505,    837.81110558,   1390.40186809,
-            1519.82045346,   2197.30955425,    791.58042696,    185.91772597,
-            74.60436444,    270.71659234,    181.00879336,    450.77145086,
-            341.60352923,    559.42021561,    784.06616575,    666.83596532,
-            18.14169546,     68.59991159,     45.52214916,    112.85166716,
-            82.89055652,    146.94298691,    192.00611495,    695.27339343])
-        self.assertAlmostEquals(model.D2, 0.834456520292)
-        self.assertAlmostEquals(model.adj_D2, 0.829658158561)
-        self.assertAlmostEquals(model.SSI, 0.688220359428)
-        self.assertAlmostEquals(model.pseudoR2, 0.81258943875)
-        self.assertAlmostEquals(model.adj_pseudoR2, 0.812555362188)
-        self.assertAlmostEquals(model.SRMSE, 1.0220094905985986)
+         [  2053.49248374,   2422.40705883,    197.17666947,    652.77645945,
+          372.46664089,    188.15630595,     62.62225447,     17.22633782,
+         1995.44179687,  12287.11927555,    806.92929317,   2643.59913196,
+         2353.33783354,    998.56216427,    335.77135891,     94.81498069,
+         3035.77484367,  15846.25211871,    890.511914  ,   2994.19536934,
+         2399.15053753,   1036.08892279,    345.71715146,     97.15537629,
+          273.27020389,   1150.87005074,    984.81363732,    948.91636667,
+          625.0285152 ,    556.41059801,    240.2714148 ,     67.32796418,
+          771.93257863,   3217.0998412 ,   2825.35215036,    809.66631035,
+         1204.76218438,    754.13231343,    258.03819482,     70.88540396,
+          575.70226041,   3743.25042014,   2959.00444172,    697.06556556,
+         1574.69697708,   1207.94322877,    447.3674688 ,    129.24387416,
+          272.27577768,   1487.02882957,   1196.36810195,    580.9635273 ,
+          922.83252627,   1130.90519845,    383.40648414,    105.94015788,
+           86.29277039,    476.14958977,    380.14055538,    238.89720288,
+          300.687118  ,    398.84078404,    365.10261002,    200.59513613,
+           23.66650989,    134.05168303,    106.50884151,     66.7421182 ,
+           82.35371404,    114.87900692,    100.58000293,    199.99352826])
+        self.assertAlmostEquals(model.D2, 0.88713874099960177)
+        self.assertAlmostEquals(model.adj_D2, 0.88215956780840776)
+        self.assertAlmostEquals(model.SSI, 0.72706171189789603)
+        self.assertAlmostEquals(model.pseudoR2, 0.88421303645743465)
+        self.assertAlmostEquals(model.adj_pseudoR2, 0.88416760104130376)
+        self.assertAlmostEquals(model.SRMSE, 0.62067966421627441)
 
     def test_local_Gravity(self):
         model = grav.Gravity(self.f, self.o_var, self.d_var, self.dij, 'exp')
@@ -254,7 +260,7 @@ class TestGravity(unittest.TestCase):
                                                 'adj_D2', 
                                                 'tvalue1', 
                                                 'SSI', 
-                                                'aic', 
+                                                'AIC', 
                                                 'param1', 
                                                 'param0', 
                                                 'D2',
@@ -263,73 +269,74 @@ class TestGravity(unittest.TestCase):
     
     def test_Production(self):
         model = grav.Production(self.f, self.o, self.d_var,
-                self.dij, 'exp')
-        np.testing.assert_allclose(model.params, [-1.11700938,  0.5696138 ,  
-            1.03487752, -0.51400641, -0.23320154, 0.09225167, -0.42761955,  
-            0.03771866, -0.0922097 ,  0.89278717, -0.00727113], atol = .0001)
-        self.assertAlmostEqual(model.aic, 15882.651018068489, delta = .0001)
+                self.dij, 'exp', constant=True)
+        np.testing.assert_allclose(model.params, 
+                [-1.11700938,  1.68662317, 2.15188689,  0.60300297,
+                 0.88380784,  1.20926104, 0.68938983,  1.15472804,  
+                 1.02479968,  0.89278717, -0.00727113], atol = .0001)
+        self.assertAlmostEqual(model.AIC, 15882.651018068489, delta = .0001)
         np.testing.assert_allclose(model.cov_params, 
-            [[ 2.58467540e-03,   2.25525153e-03,   2.25698879e-03,
-               2.27598630e-03,   2.28753498e-03,   2.29518139e-03,
-               2.26066086e-03,   2.28389856e-03,   2.30028223e-03,
-               -2.24000219e-04,  -9.64855587e-07],
-            [  2.25525153e-03,   2.22885311e-03,   2.18057451e-03,
-               2.19382566e-03,   2.20716973e-03,   2.21373933e-03,
-               2.17974121e-03,   2.19682475e-03,   2.20967384e-03,
-               -2.16966417e-04,  -8.72732269e-07],
-            [  2.25698879e-03,   2.18057451e-03,   2.21642787e-03,
-               2.19592307e-03,   2.20904148e-03,   2.21570366e-03,
-               2.18175104e-03,   2.19942376e-03,   2.21260234e-03,
-               -2.17060431e-04,  -8.79741394e-07],
-            [  2.27598630e-03,   2.19382566e-03,   2.19592307e-03,
-               2.43184109e-03,   2.23320408e-03,   2.24276394e-03,
-               2.21085295e-03,   2.24737607e-03,   2.27104133e-03,
-               -2.16513520e-04,  -1.09288157e-06],
-            [  2.28753498e-03,   2.20716973e-03,   2.20904148e-03,
-               2.23320408e-03,   2.35994849e-03,   2.25049809e-03,
-               2.21741622e-03,   2.24601728e-03,   2.26530460e-03,
-               -2.18641277e-04,  -1.00923831e-06],
-            [  2.29518139e-03,   2.21373933e-03,   2.21570366e-03,
-               2.24276394e-03,   2.25049809e-03,   2.35335488e-03,
-               2.22652875e-03,   2.25818713e-03,   2.27918210e-03,
-               -2.18996160e-04,  -1.04519353e-06],
-            [  2.26066086e-03,   2.17974121e-03,   2.18175104e-03,
-               2.21085295e-03,   2.21741622e-03,   2.22652875e-03,
-               2.36722952e-03,   2.22827572e-03,   2.25038328e-03,
-               -2.15375557e-04,  -1.05779552e-06],
-            [  2.28389856e-03,   2.19682475e-03,   2.19942376e-03,
-               2.24737607e-03,   2.24601728e-03,   2.25818713e-03,
-               2.22827572e-03,   2.51224347e-03,   2.31504070e-03,
-               -2.15113513e-04,  -1.28324145e-06],
-            [  2.30028223e-03,   2.20967384e-03,   2.21260234e-03,
-               2.27104133e-03,   2.26530460e-03,   2.27918210e-03,
-               2.25038328e-03,   2.31504070e-03,   2.81219776e-03,
-               -2.15302957e-04,  -1.40976210e-06],
-            [ -2.24000219e-04,  -2.16966417e-04,  -2.17060431e-04,
-              -2.16513520e-04,  -2.18641277e-04,  -2.18996160e-04,
-              -2.15375557e-04,  -2.15113513e-04,  -2.15302957e-04,
-               2.17985878e-05,   6.51339971e-08],
-            [ -9.64855587e-07,  -8.72732269e-07,  -8.79741394e-07,
-              -1.09288157e-06,  -1.00923831e-06,  -1.04519353e-06,
-              -1.05779552e-06,  -1.28324145e-06,  -1.40976210e-06,
-               6.51339971e-08,   2.77308674e-09]])
+        [[  2.58467540e-03,  -3.29423877e-04,  -3.27686611e-04,
+         -3.08689103e-04,  -2.97140418e-04,  -2.89494010e-04,
+         -3.24014540e-04,  -3.00776842e-04,  -2.84393168e-04,
+         -2.24000219e-04,  -9.64855587e-07],
+       [ -3.29423877e-04,   3.03025458e-04,   2.53009591e-04,
+          2.47263232e-04,   2.49058621e-04,   2.47981815e-04,
+          2.48504221e-04,   2.42350062e-04,   2.38815483e-04,
+          7.03380199e-06,   9.21233182e-08],
+       [ -3.27686611e-04,   2.53009591e-04,   2.87125687e-04,
+          2.47623385e-04,   2.49193103e-04,   2.48208882e-04,
+          2.48776786e-04,   2.43211814e-04,   2.40006717e-04,
+          6.93978830e-06,   8.51141937e-08],
+       [ -3.08689103e-04,   2.47263232e-04,   2.47623385e-04,
+          4.64543893e-04,   2.54358195e-04,   2.56271647e-04,
+          2.58881194e-04,   2.72166616e-04,   2.79448200e-04,
+          7.48669925e-06,  -1.28025978e-07],
+       [ -2.97140418e-04,   2.49058621e-04,   2.49193103e-04,
+          2.54358195e-04,   3.69553926e-04,   2.52457119e-04,
+          2.53895776e-04,   2.59259137e-04,   2.62162787e-04,
+          5.35894223e-06,  -4.43827259e-08],
+       [ -2.89494010e-04,   2.47981815e-04,   2.48208882e-04,
+          2.56271647e-04,   2.52457119e-04,   3.47667496e-04,
+          2.55361893e-04,   2.63782581e-04,   2.68393880e-04,
+          5.00405857e-06,  -8.03379392e-08],
+       [ -3.24014540e-04,   2.48504221e-04,   2.48776786e-04,
+          2.58881194e-04,   2.53895776e-04,   2.55361893e-04,
+          4.30583201e-04,   2.68391703e-04,   2.74115589e-04,
+          8.62466197e-06,  -9.29399372e-08],
+       [ -3.00776842e-04,   2.42350062e-04,   2.43211814e-04,
+          2.72166616e-04,   2.59259137e-04,   2.63782581e-04,
+          2.68391703e-04,   5.29121755e-04,   3.15535312e-04,
+          8.88670616e-06,  -3.18385859e-07],
+       [ -2.84393168e-04,   2.38815483e-04,   2.40006717e-04,
+          2.79448200e-04,   2.62162787e-04,   2.68393880e-04,
+          2.74115589e-04,   3.15535312e-04,   7.96308690e-04,
+          8.69726183e-06,  -4.44906514e-07],
+       [ -2.24000219e-04,   7.03380199e-06,   6.93978830e-06,
+          7.48669925e-06,   5.35894223e-06,   5.00405857e-06,
+          8.62466197e-06,   8.88670616e-06,   8.69726183e-06,
+          2.17985878e-05,   6.51339971e-08],
+       [ -9.64855587e-07,   9.21233182e-08,   8.51141937e-08,
+         -1.28025978e-07,  -4.43827259e-08,  -8.03379392e-08,
+         -9.29399372e-08,  -3.18385859e-07,  -4.44906514e-07,
+          6.51339971e-08,   2.77308674e-09]])
         self.assertAlmostEqual(model.deviance, 15279.974241770311, delta = .0001)
         self.assertAlmostEqual(model.llf, -7930.3255090342445, delta = .0001)
         self.assertAlmostEqual(model.llnull, -88037.0499629, delta = .0001)
         np.testing.assert_allclose(model.pvalues, 
-            [  5.43122294e-107,   1.60984652e-033,   4.30597019e-107,
-            1.94310017e-025,   1.58325196e-006,   5.72169717e-002,
-            1.50954058e-018,   4.51730708e-001,   8.20670992e-002,
-            0.00000000e+000,   0.00000000e+000])
+         [  5.43122293e-107,   0.00000000e+000,   0.00000000e+000,
+         3.06800447e-172,   0.00000000e+000,   0.00000000e+000,
+         5.04395549e-242,   0.00000000e+000,   9.03955976e-289,
+         0.00000000e+000,   0.00000000e+000])
         np.testing.assert_allclose(model.std_err, 
-            [  5.08397030e-02,   4.72107308e-02,   4.70789536e-02,
-            4.93137008e-02,   4.85793011e-02,   4.85113892e-02,
-            4.86541830e-02,   5.01222852e-02,   5.30301589e-02,
-            4.66889578e-03,   5.26601057e-05])
+         [  5.08397030e-02,   1.74076264e-02,   1.69447835e-02,
+         2.15532803e-02,   1.92237854e-02,   1.86458439e-02,
+         2.07504988e-02,   2.30026467e-02,   2.82189420e-02,
+         4.66889578e-03,   5.26601057e-05])
         np.testing.assert_allclose(model.tvalues, 
-            [ -21.97120187,   12.06534585,   21.98174424,  -10.4231968 ,
-            -4.80043014,    1.90164966,   -8.78895757,    0.75253281,
-            -1.73881619,  191.22019711, -138.07670549])
+         [ -21.97120187,   96.88989939,  126.99406254,   27.97731759,
+         45.97470357,   64.85418671,   33.22280753,   50.19979035,
+         36.31602055,  191.22019711, -138.07670549])
         np.testing.assert_allclose(model.yhat, 
             [  1.40705950e+03,   1.69457663e+03,   1.16508879e+02,
             4.27850723e+02,   2.23425179e+02,   1.08301078e+02,
@@ -376,7 +383,7 @@ class TestGravity(unittest.TestCase):
                                                 'adj_D2', 
                                                 'tvalue1', 
                                                 'SSI', 
-                                                'aic', 
+                                                'AIC', 
                                                 'param1', 
                                                 'param0', 
                                                 'D2',
@@ -385,74 +392,74 @@ class TestGravity(unittest.TestCase):
                                                   
     def test_Attraction(self):
         model = grav.Production(self.f, self.d, self.o_var,
-                self.dij, 'exp')
+                self.dij, 'exp', constant=True)
         np.testing.assert_allclose(model.params, 
-                [-0.88439723,  0.73740882,  1.04332355, -0.75977722, -0.26060911,
-                -0.1879365 , -0.67530313, -0.19871953, -0.39900098,  0.89235874,
-                -0.00693755], atol = .0001)
-        self.assertAlmostEqual(model.aic, 16275.899321893821, delta = .0001)
+         [-0.88439723,  1.62180605,  1.92772078,  0.12462001,  0.62378812,
+          0.69646073,  0.20909411,  0.6856777 ,  0.48539625,  0.89235874,
+          -0.00693755], atol = .001)
+        self.assertAlmostEqual(model.AIC, 16275.899321893821, delta = .0001)
         np.testing.assert_allclose(model.cov_params, 
-            [[  3.01436996e-03,   2.75262767e-03,   2.69617868e-03,
-            2.75263367e-03,   2.76096809e-03,   2.76082495e-03,
-            2.73320039e-03,   2.77096042e-03,   2.80156716e-03,
-            -2.71488782e-04,  -1.17108280e-06],
-            [  2.75262767e-03,   2.72725703e-03,   2.63241450e-03,
-            2.68345714e-03,   2.69359309e-03,   2.69264448e-03,
-            2.66538758e-03,   2.69705597e-03,   2.72384308e-03,
-            -2.65699549e-04,  -1.08479153e-06],
-            [  2.69617868e-03,   2.63241450e-03,   2.61511832e-03,
-            2.63025621e-03,   2.63909790e-03,   2.63860796e-03,
-            2.61206899e-03,   2.64590548e-03,   2.67381997e-03,
-            -2.59870000e-04,  -1.09419859e-06],
-            [  2.75263367e-03,   2.68345714e-03,   2.63025621e-03,
-            2.93687480e-03,   2.69787111e-03,   2.69944743e-03,
-            2.67310431e-03,   2.72096984e-03,   2.75739588e-03,
-            -2.63511222e-04,  -1.26675817e-06],
-            [  2.76096809e-03,   2.69359309e-03,   2.63909790e-03,
-            2.69787111e-03,   2.82012775e-03,   2.70486370e-03,
-            2.67807014e-03,   2.71951056e-03,   2.75213707e-03,
-            -2.65196970e-04,  -1.19678325e-06],
-            [  2.76082495e-03,   2.69264448e-03,   2.63860796e-03,
-            2.69944743e-03,   2.70486370e-03,   2.82788771e-03,
-            2.67918953e-03,   2.72327074e-03,   2.75746837e-03,
-            -2.64826047e-04,  -1.22641311e-06],
-            [  2.73320039e-03,   2.66538758e-03,   2.61206899e-03,
-            2.67310431e-03,   2.67807014e-03,   2.67918953e-03,
-            2.85686854e-03,   2.69753883e-03,   2.73200584e-03,
-            -2.62037343e-04,  -1.22568680e-06],
-            [  2.77096042e-03,   2.69705597e-03,   2.64590548e-03,
-            2.72096984e-03,   2.71951056e-03,   2.72327074e-03,
-            2.69753883e-03,   3.01269943e-03,   2.80463020e-03,
-            -2.63381525e-04,  -1.43182005e-06],
-            [  2.80156716e-03,   2.72384308e-03,   2.67381997e-03,
-            2.75739588e-03,   2.75213707e-03,   2.75746837e-03,
-            2.73200584e-03,   2.80463020e-03,   3.37945677e-03,
-            -2.64964684e-04,  -1.55786850e-06],
-            [ -2.71488782e-04,  -2.65699549e-04,  -2.59870000e-04,
-            -2.63511222e-04,  -2.65196970e-04,  -2.64826047e-04,
-            -2.62037343e-04,  -2.63381525e-04,  -2.64964684e-04,
-            2.64461183e-05,   8.70031728e-08],
-            [ -1.17108280e-06,  -1.08479153e-06,  -1.09419859e-06,
-            -1.26675817e-06,  -1.19678325e-06,  -1.22641311e-06,
-            -1.22568680e-06,  -1.43182005e-06,  -1.55786850e-06,
-            8.70031728e-08,   2.62593686e-09]])
+        [[  3.01436996e-03,  -2.61742292e-04,  -3.18191276e-04,
+         -2.61736294e-04,  -2.53401872e-04,  -2.53545012e-04,
+         -2.81169571e-04,  -2.43409544e-04,  -2.12802803e-04,
+         -2.71488782e-04,  -1.17108280e-06],
+       [ -2.61742292e-04,   2.36371652e-04,   1.97978106e-04,
+          1.92565769e-04,   1.94367290e-04,   1.93561823e-04,
+          1.93929484e-04,   1.87837851e-04,   1.84018218e-04,
+          5.78923328e-06,   8.62912701e-08],
+       [ -3.18191276e-04,   1.97978106e-04,   2.37130911e-04,
+          1.95813824e-04,   1.96321084e-04,   1.95974290e-04,
+          1.97059881e-04,   1.93136341e-04,   1.90444087e-04,
+          1.16187824e-05,   7.68842070e-08],
+       [ -2.61736294e-04,   1.92565769e-04,   1.95813824e-04,
+          4.45977428e-04,   1.98639315e-04,   2.00358776e-04,
+          2.01640218e-04,   2.11745720e-04,   2.17565021e-04,
+          7.97756072e-06,  -9.56753770e-08],
+       [ -2.53401872e-04,   1.94367290e-04,   1.96321084e-04,
+          1.98639315e-04,   3.12561535e-04,   1.97440629e-04,
+          1.98271627e-04,   2.01952018e-04,   2.03971780e-04,
+          6.29181262e-06,  -2.57004528e-08],
+       [ -2.53545012e-04,   1.93561823e-04,   1.95974290e-04,
+          2.00358776e-04,   1.97440629e-04,   3.20607776e-04,
+          1.99534150e-04,   2.05855338e-04,   2.09446226e-04,
+          6.66273501e-06,  -5.53303117e-08],
+       [ -2.81169571e-04,   1.93929484e-04,   1.97059881e-04,
+          2.01640218e-04,   1.98271627e-04,   1.99534150e-04,
+          4.04837719e-04,   2.07747990e-04,   2.11608257e-04,
+          9.45143925e-06,  -5.46040064e-08],
+       [ -2.43409544e-04,   1.87837851e-04,   1.93136341e-04,
+          2.11745720e-04,   2.01952018e-04,   2.05855338e-04,
+          2.07747990e-04,   4.85148555e-04,   2.46472592e-04,
+          8.10725781e-06,  -2.60737252e-07],
+       [ -2.12802803e-04,   1.84018218e-04,   1.90444087e-04,
+          2.17565021e-04,   2.03971780e-04,   2.09446226e-04,
+          2.11608257e-04,   2.46472592e-04,   7.90692415e-04,
+          6.52409863e-06,  -3.86785704e-07],
+       [ -2.71488782e-04,   5.78923328e-06,   1.16187824e-05,
+          7.97756072e-06,   6.29181262e-06,   6.66273501e-06,
+          9.45143925e-06,   8.10725781e-06,   6.52409863e-06,
+          2.64461183e-05,   8.70031728e-08],
+       [ -1.17108280e-06,   8.62912701e-08,   7.68842070e-08,
+         -9.56753770e-08,  -2.57004528e-08,  -5.53303117e-08,
+         -5.46040064e-08,  -2.60737252e-07,  -3.86785704e-07,
+          8.70031728e-08,   2.62593686e-09]])
         self.assertAlmostEqual(model.deviance, 15673.222613627502, delta = .0001)
         self.assertAlmostEqual(model.llf, -8126.9496609469106, delta = .0001)
         self.assertAlmostEqual(model.llnull, -88037.0499629, delta = .0001)
         np.testing.assert_allclose(model.pvalues, 
-            [  2.23154436e-58,   2.84596439e-45,   1.60422925e-92,
-            1.17853681e-44,   9.22717986e-07,   4.09150807e-04,
-            1.36480824e-36,   2.94090148e-04,   6.71572334e-12,
-            0.00000000e+00,   0.00000000e+00])
+         [  2.23154436e-058,   0.00000000e+000,   0.00000000e+000,
+         3.61133996e-009,   1.05877746e-272,   0.00000000e+000,
+         2.69492058e-025,   9.38664385e-213,   9.08121216e-067,
+         0.00000000e+000,   0.00000000e+000])
         np.testing.assert_allclose(model.std_err, 
-            [  5.49032782e-02,   5.22231465e-02,   5.11382276e-02,
-            5.41929405e-02,   5.31048750e-02,   5.31778874e-02,
-            5.34496823e-02,   5.48880627e-02,   5.81330953e-02,
-            5.14257895e-03,   5.12438958e-05])
+         [  5.49032782e-02,   1.53743830e-02,   1.53990555e-02,
+         2.11181777e-02,   1.76794099e-02,   1.79055236e-02,
+         2.01205795e-02,   2.20260880e-02,   2.81192535e-02,
+         5.14257895e-03,   5.12438958e-05])
         np.testing.assert_allclose(model.tvalues, 
-            [ -16.10827734,   14.12034455,   20.4020279 ,  -14.01985592,
-            -4.90744228,   -3.53410997,  -12.63437119,   -3.62045082,
-            -6.86357714,  173.52358548, -135.38293645])
+         [ -16.10827734,  105.487554  ,  125.18435157,    5.90107805,
+         35.28331128,   38.89641795,   10.39205191,   31.13025333,
+         17.2620603 ,  173.52358548, -135.38293645])
         np.testing.assert_allclose(model.yhat, 
             [  1.79502279e+03,   2.77690999e+03,   1.77376340e+02,
             5.41058308e+02,   3.28265191e+02,   1.61020145e+02,
@@ -499,7 +506,7 @@ class TestGravity(unittest.TestCase):
                                                 'adj_D2', 
                                                 'tvalue1', 
                                                 'SSI', 
-                                                'aic', 
+                                                'AIC', 
                                                 'param1', 
                                                 'param0', 
                                                 'D2',
@@ -508,147 +515,145 @@ class TestGravity(unittest.TestCase):
 
     def test_Doubly(self):
         model = grav.Doubly(self.f, self.o, self.d,
-                self.dij, 'exp')
+                self.dij, 'exp', constant=True)
         np.testing.assert_allclose(model.params, 
-            [  1.49709841e+00,   2.18492741e+00,   1.87848176e-01,
-            6.64345148e-01,   7.42649379e-01,   2.13345351e-01,
-            6.67657810e-01,   3.99860937e-01,   6.20471518e+00,
-            7.74962468e+00,   8.64614438e+00,   6.90395892e+00,
-            7.15340702e+00,   7.49439155e+00,   6.94741533e+00,
-            7.39940090e+00,   7.19345711e+00,  -7.91533311e-03])
-        self.assertAlmostEqual(model.aic, 9977.1591414502109, delta = .0001)
+            [ 6.20471518,  1.5449095,   2.4414292,   0.69924374,  
+              0.94869185,  1.28967637, 0.74270015,  1.19468573,  
+              0.98874193,  1.49709841,  2.18492741,  0.18784818,
+              0.66434515,  0.74264938,  0.21334535,  0.66765781,  
+              0.39986094, -0.00791533], atol=1e-05)
         np.testing.assert_allclose(model.cov_params, 
-            [[  2.42563703e-04,   1.84733809e-04,   1.89259451e-04,
-            1.91681710e-04,   1.89152965e-04,   1.92231256e-04,
-            1.87441436e-04,   1.86834624e-04,  -2.12557582e-04,
-            -1.85482863e-04,  -2.14024619e-04,  -2.11064638e-04,
-            -2.06862321e-04,  -2.13608850e-04,  -2.10640872e-04,
-            -2.17216459e-04,  -2.18470971e-04,   1.13843139e-07],
-            [  1.84733809e-04,   2.63915732e-04,   2.06737361e-04,
-            2.02941436e-04,   2.03812109e-04,   2.06876793e-04,
-            2.08793972e-04,   2.09473765e-04,  -2.30973877e-04,
-            -2.35038219e-04,  -1.70143798e-04,  -2.05817163e-04,
-            -2.09270447e-04,  -2.11179236e-04,  -2.07192858e-04,
-            -2.05101234e-04,  -2.04407823e-04,  -1.94248549e-08],
-            [  1.89259451e-04,   2.06737361e-04,   4.53792323e-04,
-            2.01217128e-04,   2.05155865e-04,   2.05806138e-04,
-            2.14332194e-04,   2.21550755e-04,  -1.98360054e-04,
-            -1.94813739e-04,  -1.74043824e-04,  -1.79955670e-04,
-            -2.00249554e-04,  -1.96708288e-04,  -2.09795316e-04,
-            -2.07058650e-04,  -1.99681815e-04,  -9.10506514e-08],
-            [  1.91681710e-04,   2.02941436e-04,   2.01217128e-04,
-            3.17290867e-04,   2.00121482e-04,   2.02120689e-04,
-            2.06522637e-04,   2.08554008e-04,  -2.04848380e-04,
-            -1.98117102e-04,  -1.83618154e-04,  -2.07840280e-04,
-            -1.82826360e-04,  -2.01083472e-04,  -2.03827844e-04,
-            -1.99372606e-04,  -1.97090647e-04,  -4.37219119e-08],
-            [  1.89152965e-04,   2.03812109e-04,   2.05155865e-04,
-            2.00121482e-04,   3.26458468e-04,   2.01391450e-04,
-            2.09628557e-04,   2.14889547e-04,  -1.97315240e-04,
-            -1.96966358e-04,  -1.78246708e-04,  -1.96030118e-04,
-            -1.93177196e-04,  -1.81632388e-04,  -2.08658217e-04,
-            -2.01831801e-04,  -1.96793054e-04,  -7.68167253e-08],
-            [  1.92231256e-04,   2.06876793e-04,   2.05806138e-04,
-            2.02120689e-04,   2.01391450e-04,   4.14676504e-04,
-            2.11496728e-04,   2.21430978e-04,  -2.04713619e-04,
-            -1.99872552e-04,  -1.81435387e-04,  -2.17387447e-04,
-            -2.03438822e-04,  -2.15975048e-04,  -1.94747314e-04,
-            -2.29253582e-04,  -2.19396689e-04,  -2.25147281e-08],
-            [  1.87441436e-04,   2.08793972e-04,   2.14332194e-04,
-            2.06522637e-04,   2.09628557e-04,   2.11496728e-04,
-            5.06851801e-04,   2.14569472e-04,  -1.92147501e-04,
-            -1.92256318e-04,  -1.67373803e-04,  -1.99536301e-04,
-            -1.85234692e-04,  -1.95220763e-04,  -2.12076508e-04,
-            -1.74748404e-04,  -3.15464930e-04,  -1.33183180e-07],
-            [  1.86834624e-04,   2.09473765e-04,   2.21550755e-04,
-            2.08554008e-04,   2.14889547e-04,   2.21430978e-04,
-            2.14569472e-04,   8.07696796e-04,  -1.90223393e-04,
-            -1.91005620e-04,  -1.64892620e-04,  -1.90136139e-04,
-            -1.80941924e-04,  -1.88390040e-04,  -1.99615358e-04,
-            -3.08949366e-04,  -1.73275263e-04,  -1.49419116e-07],
-            [ -2.12557582e-04,  -2.30973877e-04,  -1.98360054e-04,
-            -2.04848380e-04,  -1.97315240e-04,  -2.04713619e-04,
-            -1.92147501e-04,  -1.90223393e-04,   5.01690795e-04,
-            2.34604925e-04,   2.15829388e-04,   2.54545792e-04,
-            2.45346420e-04,   2.53731101e-04,   2.49832769e-04,
-            2.66780923e-04,   2.70158589e-04,  -2.88654296e-07],
-            [ -1.85482863e-04,  -2.35038219e-04,  -1.94813739e-04,
-            -1.98117102e-04,  -1.96966358e-04,  -1.99872552e-04,
-            -1.92256318e-04,  -1.91005620e-04,   2.34604925e-04,
-            2.77338030e-04,   1.86945338e-04,   2.28276363e-04,
-            2.22769121e-04,   2.28218883e-04,   2.25960817e-04,
-            2.36170239e-04,   2.38337459e-04,  -1.71284609e-07],
-            [ -2.14024619e-04,  -1.70143798e-04,  -1.74043824e-04,
-            -1.83618154e-04,  -1.78246708e-04,  -1.81435387e-04,
-            -1.67373803e-04,  -1.64892620e-04,   2.15829388e-04,
-            1.86945338e-04,   2.45803385e-04,   2.29398497e-04,
-            2.16802998e-04,   2.26157245e-04,   2.24998100e-04,
-            2.43491383e-04,   2.47501416e-04,  -2.99347493e-07],
-            [ -2.11064638e-04,  -2.05817163e-04,  -1.79955670e-04,
-            -2.07840280e-04,  -1.96030118e-04,  -2.17387447e-04,
-            -1.99536301e-04,  -1.90136139e-04,   2.54545792e-04,
-            2.28276363e-04,   2.29398497e-04,   4.81070964e-04,
-            2.56007624e-04,   2.69174189e-04,   2.66750505e-04,
-            2.96278814e-04,   3.07523359e-04,  -4.35727563e-07],
-            [ -2.06862321e-04,  -2.09270447e-04,  -2.00249554e-04,
-            -1.82826360e-04,  -1.93177196e-04,  -2.03438822e-04,
-            -1.85234692e-04,  -1.80941924e-04,   2.45346420e-04,
-            2.22769121e-04,   2.16802998e-04,   2.56007624e-04,
-            3.63658820e-04,   2.53530192e-04,   2.51566361e-04,
-            2.75202102e-04,   2.81144405e-04,  -3.64321585e-07],
-            [ -2.13608850e-04,  -2.11179236e-04,  -1.96708288e-04,
-            -2.01083472e-04,  -1.81632388e-04,  -2.15975048e-04,
-            -1.95220763e-04,  -1.88390040e-04,   2.53731101e-04,
-            2.28218883e-04,   2.26157245e-04,   2.69174189e-04,
-            2.53530192e-04,   3.60293800e-04,   2.60651465e-04,
-            2.88323917e-04,   2.97276990e-04,  -4.03684411e-07],
-            [ -2.10640872e-04,  -2.07192858e-04,  -2.09795316e-04,
-            -2.03827844e-04,  -2.08658217e-04,  -1.94747314e-04,
-            -2.12076508e-04,  -1.99615358e-04,   2.49832769e-04,
-            2.25960817e-04,   2.24998100e-04,   2.66750505e-04,
-            2.51566361e-04,   2.60651465e-04,   4.37541208e-04,
-            2.87192980e-04,   3.00841537e-04,  -3.80706214e-07],
-            [ -2.17216459e-04,  -2.05101234e-04,  -2.07058650e-04,
-            -1.99372606e-04,  -2.01831801e-04,  -2.29253582e-04,
-            -1.74748404e-04,  -3.08949366e-04,   2.66780923e-04,
-            2.36170239e-04,   2.43491383e-04,   2.96278814e-04,
-            2.75202102e-04,   2.88323917e-04,   2.87192980e-04,
-            5.80191216e-04,   3.22518390e-04,  -5.30363748e-07],
-            [ -2.18470971e-04,  -2.04407823e-04,  -1.99681815e-04,
-            -1.97090647e-04,  -1.96793054e-04,  -2.19396689e-04,
-            -3.15464930e-04,  -1.73275263e-04,   2.70158589e-04,
-            2.38337459e-04,   2.47501416e-04,   3.07523359e-04,
-            2.81144405e-04,   2.97276990e-04,   3.00841537e-04,
-            3.22518390e-04,   8.53001477e-04,  -5.59442560e-07],
-            [  1.13843139e-07,  -1.94248549e-08,  -9.10506514e-08,
-            -4.37219119e-08,  -7.68167253e-08,  -2.25147281e-08,
-            -1.33183180e-07,  -1.49419116e-07,  -2.88654296e-07,
-            -1.71284609e-07,  -2.99347493e-07,  -4.35727563e-07,
-            -3.64321585e-07,  -4.03684411e-07,  -3.80706214e-07,
-            -5.30363748e-07,  -5.59442560e-07,   2.56252122e-09]])
+        [[  5.01690795e-04,  -2.67085869e-04,  -2.85861407e-04,
+         -2.47145002e-04,  -2.56344375e-04,  -2.47959694e-04,
+         -2.51858026e-04,  -2.34909872e-04,  -2.31532205e-04,
+         -2.12557582e-04,  -2.30973877e-04,  -1.98360054e-04,
+         -2.04848380e-04,  -1.97315240e-04,  -2.04713619e-04,
+         -1.92147501e-04,  -1.90223393e-04,  -2.88654296e-07],
+       [ -2.67085869e-04,   3.09818975e-04,   2.38201819e-04,
+          2.40816440e-04,   2.44508571e-04,   2.41573651e-04,
+          2.43213918e-04,   2.36475186e-04,   2.35264739e-04,
+          2.70747190e-05,  -4.06434204e-06,   3.54631504e-06,
+          6.73127801e-06,   3.48881444e-07,   4.84106698e-06,
+         -1.08816401e-07,  -7.82227026e-07,   1.17369687e-07],
+       [ -2.85861407e-04,   2.38201819e-04,   3.15835404e-04,
+          2.60714112e-04,   2.57317985e-04,   2.58287551e-04,
+          2.61026738e-04,   2.62571867e-04,   2.63204233e-04,
+         -1.46703716e-06,   6.08300790e-05,   2.43162304e-05,
+          2.12302255e-05,   1.90685319e-05,   2.32782320e-05,
+          2.47736982e-05,   2.53307733e-05,  -1.06931968e-08],
+       [ -2.47145002e-04,   2.40816440e-04,   2.60714112e-04,
+          4.73670174e-04,   2.57806206e-04,   2.62588091e-04,
+          2.64062738e-04,   2.76642894e-04,   2.84509772e-04,
+          1.49294364e-06,   2.51567145e-05,   1.84043845e-05,
+         -2.99190057e-06,   1.28512200e-06,  -1.26738274e-05,
+         -7.38879982e-06,   8.72549111e-08,  -1.47073267e-07],
+       [ -2.56344375e-04,   2.44508571e-04,   2.57317985e-04,
+          2.57806206e-04,   3.74656775e-04,   2.56143467e-04,
+          2.58077967e-04,   2.64765554e-04,   2.67330191e-04,
+          5.69526013e-06,   2.17034297e-05,  -1.88949992e-06,
+          2.20220200e-05,   4.13804378e-06,   1.27479768e-06,
+          6.91280894e-06,   9.28146927e-06,  -7.56672892e-08],
+       [ -2.47959694e-04,   2.41573651e-04,   2.58287551e-04,
+          2.62588091e-04,   2.56143467e-04,   3.54522394e-04,
+          2.58778390e-04,   2.69502689e-04,   2.75078094e-04,
+         -1.05126847e-06,   1.97946415e-05,   1.65176617e-06,
+          3.76490799e-06,   1.56828518e-05,  -1.12614285e-05,
+         -3.07326187e-06,   1.83335365e-06,  -1.15030115e-07],
+       [ -2.51858026e-04,   2.43213918e-04,   2.61026738e-04,
+          2.64062738e-04,   2.58077967e-04,   2.58778390e-04,
+          4.39566465e-04,   2.72270083e-04,   2.82540973e-04,
+          1.91670954e-06,   2.37810191e-05,  -1.14352620e-05,
+          1.02053574e-06,  -1.13429776e-05,   9.96630546e-06,
+         -1.99290067e-05,  -9.39196494e-06,  -9.20519180e-08],
+       [ -2.34909872e-04,   2.36475186e-04,   2.62571867e-04,
+          2.76642894e-04,   2.64765554e-04,   2.69502689e-04,
+          2.72270083e-04,   5.48320166e-04,   2.87269673e-04,
+         -4.65887794e-06,   2.58726435e-05,  -8.69859569e-06,
+          5.47577328e-06,  -4.51656124e-06,  -2.45399627e-05,
+          1.73990976e-05,  -1.18725973e-04,  -2.41709452e-07],
+       [ -2.31532205e-04,   2.35264739e-04,   2.63204233e-04,
+          2.84509772e-04,   2.67330191e-04,   2.75078094e-04,
+          2.82540973e-04,   2.87269673e-04,   8.14375093e-04,
+         -5.91338987e-06,   2.65660547e-05,  -1.32176066e-06,
+          7.75773294e-06,   5.22185282e-07,  -1.46830696e-05,
+         -1.23317429e-04,   1.69481305e-05,  -2.70788264e-07],
+       [ -2.12557582e-04,   2.70747190e-05,  -1.46703716e-06,
+          1.49294364e-06,   5.69526013e-06,  -1.05126847e-06,
+          1.91670954e-06,  -4.65887794e-06,  -5.91338987e-06,
+          2.42563703e-04,   1.84733809e-04,   1.89259451e-04,
+          1.91681710e-04,   1.89152965e-04,   1.92231256e-04,
+          1.87441436e-04,   1.86834624e-04,   1.13843139e-07],
+       [ -2.30973877e-04,  -4.06434204e-06,   6.08300790e-05,
+          2.51567145e-05,   2.17034297e-05,   1.97946415e-05,
+          2.37810191e-05,   2.58726435e-05,   2.65660547e-05,
+          1.84733809e-04,   2.63915732e-04,   2.06737361e-04,
+          2.02941436e-04,   2.03812109e-04,   2.06876793e-04,
+          2.08793972e-04,   2.09473765e-04,  -1.94248549e-08],
+       [ -1.98360054e-04,   3.54631504e-06,   2.43162304e-05,
+          1.84043845e-05,  -1.88949992e-06,   1.65176617e-06,
+         -1.14352620e-05,  -8.69859569e-06,  -1.32176066e-06,
+          1.89259451e-04,   2.06737361e-04,   4.53792323e-04,
+          2.01217128e-04,   2.05155865e-04,   2.05806138e-04,
+          2.14332194e-04,   2.21550755e-04,  -9.10506514e-08],
+       [ -2.04848380e-04,   6.73127801e-06,   2.12302255e-05,
+         -2.99190057e-06,   2.20220200e-05,   3.76490799e-06,
+          1.02053574e-06,   5.47577328e-06,   7.75773294e-06,
+          1.91681710e-04,   2.02941436e-04,   2.01217128e-04,
+          3.17290867e-04,   2.00121482e-04,   2.02120689e-04,
+          2.06522637e-04,   2.08554008e-04,  -4.37219119e-08],
+       [ -1.97315240e-04,   3.48881444e-07,   1.90685319e-05,
+          1.28512200e-06,   4.13804378e-06,   1.56828518e-05,
+         -1.13429776e-05,  -4.51656124e-06,   5.22185282e-07,
+          1.89152965e-04,   2.03812109e-04,   2.05155865e-04,
+          2.00121482e-04,   3.26458468e-04,   2.01391450e-04,
+          2.09628557e-04,   2.14889547e-04,  -7.68167253e-08],
+       [ -2.04713619e-04,   4.84106698e-06,   2.32782320e-05,
+         -1.26738274e-05,   1.27479768e-06,  -1.12614285e-05,
+          9.96630546e-06,  -2.45399627e-05,  -1.46830696e-05,
+          1.92231256e-04,   2.06876793e-04,   2.05806138e-04,
+          2.02120689e-04,   2.01391450e-04,   4.14676504e-04,
+          2.11496728e-04,   2.21430978e-04,  -2.25147281e-08],
+       [ -1.92147501e-04,  -1.08816401e-07,   2.47736982e-05,
+         -7.38879982e-06,   6.91280894e-06,  -3.07326187e-06,
+         -1.99290067e-05,   1.73990976e-05,  -1.23317429e-04,
+          1.87441436e-04,   2.08793972e-04,   2.14332194e-04,
+          2.06522637e-04,   2.09628557e-04,   2.11496728e-04,
+          5.06851801e-04,   2.14569472e-04,  -1.33183180e-07],
+       [ -1.90223393e-04,  -7.82227026e-07,   2.53307733e-05,
+          8.72549111e-08,   9.28146927e-06,   1.83335365e-06,
+         -9.39196494e-06,  -1.18725973e-04,   1.69481305e-05,
+          1.86834624e-04,   2.09473765e-04,   2.21550755e-04,
+          2.08554008e-04,   2.14889547e-04,   2.21430978e-04,
+          2.14569472e-04,   8.07696796e-04,  -1.49419116e-07],
+       [ -2.88654296e-07,   1.17369687e-07,  -1.06931968e-08,
+         -1.47073267e-07,  -7.56672892e-08,  -1.15030115e-07,
+         -9.20519180e-08,  -2.41709452e-07,  -2.70788264e-07,
+          1.13843139e-07,  -1.94248549e-08,  -9.10506514e-08,
+         -4.37219119e-08,  -7.68167253e-08,  -2.25147281e-08,
+         -1.33183180e-07,  -1.49419116e-07,   2.56252122e-09]])
         self.assertAlmostEqual(model.deviance, 9360.482092561484, delta = .0001)
         self.assertAlmostEqual(model.llf, -4970.5795707251054, delta = .0001)
         self.assertAlmostEqual(model.llnull, -88037.0499629, delta = .0001)
         np.testing.assert_allclose(model.pvalues, 
-            [  0.00000000e+000,   0.00000000e+000,   1.16346714e-018,
-            1.88877600e-304,   0.00000000e+000,   1.10421926e-025,
-            2.83322217e-193,   5.83172788e-045,   0.00000000e+000,
-            0.00000000e+000,   0.00000000e+000,   0.00000000e+000,
-            0.00000000e+000,   0.00000000e+000,   0.00000000e+000,
-            0.00000000e+000,   0.00000000e+000,   0.00000000e+000])
+        [  0.00000000e+000,   0.00000000e+000,   0.00000000e+000,
+         1.76331083e-226,   0.00000000e+000,   0.00000000e+000,
+         7.21755436e-275,   0.00000000e+000,   4.88760299e-263,
+         0.00000000e+000,   0.00000000e+000,   1.16346714e-018,
+         1.88877600e-304,   0.00000000e+000,   1.10421926e-025,
+         2.83322217e-193,   5.83172788e-045,   0.00000000e+000])
         np.testing.assert_allclose(model.std_err, 
-            [  1.55744567e-02,   1.62454834e-02,   2.13024018e-02,
-            1.78126603e-02,   1.80681617e-02,   2.03636073e-02,
-            2.25133694e-02,   2.84200070e-02,   2.23984552e-02,
-            1.66534690e-02,   1.56781180e-02,   2.19333300e-02,
-            1.90698406e-02,   1.89814067e-02,   2.09174857e-02,
-            2.40871587e-02,   2.92061890e-02,   5.06213514e-05])
+        [  2.23984552e-02,   1.76016753e-02,   1.77717586e-02,
+         2.17639650e-02,   1.93560527e-02,   1.88287651e-02,
+         2.09658404e-02,   2.34162372e-02,   2.85372580e-02,
+         1.55744567e-02,   1.62454834e-02,   2.13024018e-02,
+         1.78126603e-02,   1.80681617e-02,   2.03636073e-02,
+         2.25133694e-02,   2.84200070e-02,   5.06213514e-05])
         np.testing.assert_allclose(model.tvalues, 
-            [  96.12524108,  134.49445277,    8.81816885,   37.29623407,
-            41.10265285,   10.47679558,   29.65605897,   14.06969877,
-            277.01531761,  465.34596906,  551.47845915,  314.77021149,
-            375.11624684,  394.828037  ,  332.13434099,  307.19276533,
-            246.2990671 , -156.36352821])
+        [ 277.01531761,   87.77059404,  137.37690538,   32.12850872,
+         49.0126713 ,   68.49500564,   35.42429674,   51.01954322,
+         34.64740487,   96.12524108,  134.49445277,    8.81816885,
+         37.29623407,   41.10265285,   10.47679558,   29.65605897,
+         14.06969877, -156.36352821])
         np.testing.assert_allclose(model.yhat, 
             [  9.78988280e+02,   2.26003279e+03,   1.04038742e+02,
             3.38382580e+02,   1.90458075e+02,   8.67908467e+01,
diff --git a/pysal/contrib/viz/Makefile b/pysal/contrib/viz/Makefile
new file mode 100644
index 0000000..f187651
--- /dev/null
+++ b/pysal/contrib/viz/Makefile
@@ -0,0 +1,2 @@
+test:
+	jupyter nbconvert --execute geotable_plot.ipynb
diff --git a/pysal/contrib/viz/color.py b/pysal/contrib/viz/color.py
new file mode 100644
index 0000000..e69b5d3
--- /dev/null
+++ b/pysal/contrib/viz/color.py
@@ -0,0 +1,77 @@
+"""
+color handling for mapping and geovisualization
+"""
+
+from warnings import warn
+try:
+    import palettable as pltt
+    from palettable.colorbrewer import qualitative, sequential, diverging
+except:
+    warn('palettable  not installed. Functionality '
+          'related to it will not work')
+
+def get_color_map(palette=None, name='BuGn', cmtype='sequential', k=5,
+                  color_encoding='hex'):
+    """
+    Get a brewer colormap from `palettable`
+
+    Arguments
+    ---------
+
+    palette         : `palettable` palette
+                      Palettable object for a given palette
+    name            : string
+                      colormap name
+
+    cmtype          : string
+                      colormap scale type  [sequential, diverging, qualitative]
+
+    k               : int
+                      number of classes
+
+    color_encoding  : string
+                      encoding of colors [hexc, rgb, mpl, mpl_colormap]
+                      * hex: list of hex strings
+                      * rgb: list of RGB 0-255 triplets
+                      * mpl: list of RGB 0-1 triplets as used by matplotlib
+                      * mpl_colormap: matplotlib color map
+
+    Returns
+    -------
+
+    colors:  color map in the specified color_encoding
+
+    """
+    encs = {'hex': 'hex_colors',
+            'rgb': 'colors',
+            'mpl': 'mpl_colors',
+            'mpl_colormap': 'mpl_colormap'}
+    if not palette:
+        cmtype = pltt2type[name.lower()]
+        if name[-2:] == '_r':
+            palette = pltt.colorbrewer.get_map(name[:-2], cmtype,
+                    k, reverse=True)
+        else:
+            palette = pltt.colorbrewer.get_map(name, cmtype, k)
+    colors = getattr(palette, encs[color_encoding.lower()])
+    return colors
+
+def _build_pltt2type():
+    types = ['sequential', 'diverging', 'qualitative']
+    pltt2type = {}
+    for t in types:
+        pals = list(set([
+            p.split('_')[0] for p in dir(getattr(pltt.colorbrewer, t))
+                            if p[0]!='_'
+                            ]))
+        pals = pals + [p+'_r' for p in pals]
+        for p in pals:
+            pltt2type[p.lower()] = t
+    return pltt2type
+
+pltt2type = _build_pltt2type()
+
+def get_maps_by_type(data_type):
+    names = [name for name in dir(data_type) if not name.startswith('_')]
+    return names
+
diff --git a/pysal/contrib/viz/color_picker.ipynb b/pysal/contrib/viz/color_picker.ipynb
new file mode 100644
index 0000000..0c964ca
--- /dev/null
+++ b/pysal/contrib/viz/color_picker.ipynb
@@ -0,0 +1,3988 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Install the lastest widgets code...\n",
+    "\n",
+    "```conda install -c conda-forge ipywidgets```"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 39,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [],
+   "source": [
+    "from ipywidgets import Dropdown, RadioButtons, IntSlider, VBox, FloatSlider, Button\n",
+    "from IPython.display import display"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 28,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [],
+   "source": [
+    "data_type = RadioButtons(options=['sequential', 'diverging', 'qualitative'])\n",
+    "\n",
+    "bindings = {'sequential': range(3,9+1),\n",
+    "            'diverging': range(3,11+1),\n",
+    "            'qualitative': range(3,12+1)}\n",
+    "\n",
+    "class_val = Dropdown(options=bindings[data_type.value])    \n",
+    "\n",
+    "def type_change(change):\n",
+    "    class_val.options = bindings[change['new']]\n",
+    "\n",
+    "data_type.observe(type_change, names=['value'])\n",
+    "\n",
+    "display(VBox([data_type, class_val]))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [],
+   "source": [
+    "\"\"\"\n",
+    "data_type = RadioButtons(options=['sequential', 'diverging', 'qualitative'])\n",
+    "\n",
+    "bindings = {'sequential': range(3,9+1),\n",
+    "            'diverging': range(3,11+1),\n",
+    "            'qualitative': range(3,12+1)}\n",
+    "\n",
+    "class_val = Dropdown(options=bindings[data_type.value])    \n",
+    "\n",
+    "def type_change(change):\n",
+    "    class_val.options = bindings[change['new']]\n",
+    "\n",
+    "data_type.observe(type_change, names=['value'])\n",
+    "\n",
+    "display(VBox([data_type, class_val]))\n",
+    "\"\"\"\n",
+    "# on data_type change update list of color maps\n",
+    "# based on class_val and data_type\n",
+    "\n",
+    "from pysal.contrib.viz.color import color_display_types\n",
+    "\n",
+    "dt = sorted(color_display_types.keys(), reverse=True)\n",
+    "data_type = RadioButtons(description='Data Type', options=dt)\n",
+    "bindings = {}\n",
+    "for t in dt:\n",
+    "    bindings[t] = color_display_types[t].keys()\n",
+    "    \n",
+    "cmap = Dropdown(description='CMap:', options=bindings[data_type.value])\n",
+    "\n",
+    "def type_change(change):\n",
+    "    with cmap.hold_trait_notifications():\n",
+    "        cmap.options = bindings[change['new']]\n",
+    "\n",
+    "data_type.observe(type_change, names=['value'])\n",
+    "\n",
+    "display(VBox([data_type, cmap]))\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [],
+   "source": [
+    "\"\"\"\n",
+    "data_type = RadioButtons(options=['sequential', 'diverging', 'qualitative'])\n",
+    "\n",
+    "bindings = {'sequential': range(3,9+1),\n",
+    "            'diverging': range(3,11+1),\n",
+    "            'qualitative': range(3,12+1)}\n",
+    "\n",
+    "class_val = Dropdown(options=bindings[data_type.value])    \n",
+    "\n",
+    "def type_change(change):\n",
+    "    class_val.options = bindings[change['new']]\n",
+    "\n",
+    "data_type.observe(type_change, names=['value'])\n",
+    "\n",
+    "display(VBox([data_type, class_val]))\n",
+    "\"\"\"\n",
+    "# on data_type change update list of color maps\n",
+    "# based on class_val and data_type\n",
+    "\n",
+    "from pysal.contrib.viz.color import color_display_types\n",
+    "from pysal.contrib.viz.color import plot_cmaps as pcmaps\n",
+    "\n",
+    "dt = sorted(color_display_types.keys(), reverse=True)\n",
+    "data_type = RadioButtons(description='Data Type', options=dt)\n",
+    "bindings = {}\n",
+    "for t in dt:\n",
+    "    bindings[t] = color_display_types[t].keys()\n",
+    "    \n",
+    "cmap = Dropdown(description='CMap:', options=bindings[data_type.value])\n",
+    "\n",
+    "def type_change(change):\n",
+    "    with cmap.hold_trait_notifications():\n",
+    "        cmap.options = bindings[change['new']]\n",
+    "\n",
+    "data_type.observe(type_change, names=['value'])  \n",
+    "\n",
+    "display(VBox([data_type, cmap]))\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 31,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAO0AAADtCAYAAABTTfKPAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAABidJREFUeJzt3EuIHWUax+Gq07f08bJSMjMi6MLLQo0iymwiRhCJOKIo\neNmIWQgiSBQvKHHhEAbEMVkMoogIrlyIMsxiXAhGEFEUwdtCQVAQnQmTjUbTbTo55cKtVeeE78sZ\n//F5tnV4365T/euu1dd2XdcAOUb/7x8AODaihTCihTCihTCihTCihTCLQxcv2P36f5um2Vy4Y/+n\nu67+w9AHznjmqip7vrn7jcE97RN/rrKne/jd3j3tKacfbX44UP7H8OTTJt3B/y30Xd62bVuVe9m3\nb9/gd3bhrteq7Plk9/bBPde/cl6VPf+66fPePXdsfa7GjqZpmv0vvnVX757R3+4v3jN5dE/bd20w\n2tLF [...]
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f3ff507ae10>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "%matplotlib inline\n",
+    "from pysal.contrib.viz.color import plot_cmaps \n",
+    "plot_cmaps('diverging', selected=3)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 90,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAO0AAADtCAYAAABTTfKPAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAABkhJREFUeJzt3EuoXeUZx+Fv73M/Su2kGm+gg3pBSioiOElpHLREvCBS\nrJkUMwiIkyBKaTGgrRSEkknphSJCO+lAVHSg4MAIIgoi1BaxgtCBlxjtoFGaHHNO9urATtdF1nd2\n9x+eZ7oW73vWXvntndE3aZqmADmm/+8/APh6RAthRAthRAthRAthRAthlrsurnzzwnM7pz4bFfby\nBd+abf/706Wuey79/c2flFIuGrOnlHLyo/te3tN1w+Txm6rsaX76Ruue1Qeeq7GjlFJOnj12R+ue\n/fv3V3mW48ePd35m33n4xSp7/v7Ygc49tz99dZU9z9/1Xuuen+z7Y7V386dXD7fumf7qgdF7Zj8/\nNmm7 [...]
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f3ff5d55410>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAO0AAADtCAYAAABTTfKPAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAABkhJREFUeJzt3EuoXeUZx+Fv73M/Su2kGm+gg3pBSioiOElpHLREvCBS\nrJkUMwiIkyBKaTGgrRSEkknphSJCO+lAVHSg4MAIIgoi1BaxgtCBlxjtoFGaHHNO9urATtdF1nd2\n9x+eZ7oW73vWXvntndE3aZqmADmm/+8/APh6RAthRAthRAthRAthRAthlrsurnzzwnM7pz4bFfby\nBd+abf/706Wuey79/c2flFIuGrOnlHLyo/te3tN1w+Txm6rsaX76Ruue1Qeeq7GjlFJOnj12R+ue\n/fv3V3mW48ePd35m33n4xSp7/v7Ygc49tz99dZU9z9/1Xuuen+z7Y7V386dXD7fumf7qgdF7Zj8/\nNmm7 [...]
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f3ff4cc5710>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "\"\"\"\n",
+    "data_type = RadioButtons(options=['sequential', 'diverging', 'qualitative'])\n",
+    "\n",
+    "bindings = {'sequential': range(3,9+1),\n",
+    "            'diverging': range(3,11+1),\n",
+    "            'qualitative': range(3,12+1)}\n",
+    "\n",
+    "class_val = Dropdown(options=bindings[data_type.value])    \n",
+    "\n",
+    "def type_change(change):\n",
+    "    class_val.options = bindings[change['new']]\n",
+    "\n",
+    "data_type.observe(type_change, names=['value'])\n",
+    "\n",
+    "display(VBox([data_type, class_val]))\n",
+    "\"\"\"\n",
+    "# on data_type change update list of color maps\n",
+    "# based on class_val and data_type\n",
+    "\n",
+    "from pysal.contrib.viz.color import color_display_types\n",
+    "from pysal.contrib.viz.color import plot_cmaps as pcmaps\n",
+    "from ipywidgets import interact\n",
+    "\n",
+    "dt = sorted(color_display_types.keys(), reverse=True)\n",
+    "data_type = RadioButtons(description='Data Type', options=dt)\n",
+    "bindings = {}\n",
+    "for t in dt:\n",
+    "    bindings[t] = color_display_types[t].keys()\n",
+    "    \n",
+    "cmap_dd = Dropdown(description='CMap:', options=bindings[data_type.value])\n",
+    "\n",
+    "def type_change(change):\n",
+    "    with cmap_dd.hold_trait_notifications():\n",
+    "        cmap_dd.options = bindings[change['new']]\n",
+    "        #plot_cmaps('diverging')\n",
+    "\n",
+    "def cmap_change(change):\n",
+    "        with cmap_dd.hold_trait_notifications():\n",
+    "            print('new cmap', str(change['new']))\n",
+    "\n",
+    "data_type.observe(type_change, names=['value'])  \n",
+    "cmap_dd.observe(cmap_change, names=['value'])\n",
+    "\n",
+    "#display(VBox([data_type, cmap]))\n",
+    "@interact(cmap=cmap_dd, data_type=data_type)\n",
+    "def plot_cmaps(data_type, cmap):\n",
+    "    #print(data_type,cmap)\n",
+    "    i = cmap_dd.options.index(cmap)\n",
+    "    pcmaps(data_type, i)\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 95,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAO0AAADtCAYAAABTTfKPAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAABihJREFUeJzt3DuIXGUYx+FvZi+zO4qmixcELbyASlAQK8UIIhFUJIWX\nRkghCBZBVLwWERULSaMoiAg2WoiCFloIRhAREQQvhVYW4iVgYRSz6yaZYyGW58yE8+0xf3me9izv\nu2fO/HZP9Y2apilAjvF//QsAJ0e0EEa0EEa0EEa0EEa0EGa56+JlT33wSyllZ88dh795/Iazun7g\n3Jeur7Lnx3s/7Nwz2jE5UY5s9ftDdebqrPntr6W2y6v3v1PjXkop5fDWwVtb72f37t1VPrNDhw51\nfmaXP/5+lT1fP7Wnc88tb11cZc+7e79r3XP3NS9XezavfXxP657xM/f33jN79OCo7VpntH0Xn8SM\nYfYc [...]
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f3ff4867d50>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "\"\"\"\n",
+    "data_type = RadioButtons(options=['sequential', 'diverging', 'qualitative'])\n",
+    "\n",
+    "bindings = {'sequential': range(3,9+1),\n",
+    "            'diverging': range(3,11+1),\n",
+    "            'qualitative': range(3,12+1)}\n",
+    "\n",
+    "class_val = Dropdown(options=bindings[data_type.value])    \n",
+    "\n",
+    "def type_change(change):\n",
+    "    class_val.options = bindings[change['new']]\n",
+    "\n",
+    "data_type.observe(type_change, names=['value'])\n",
+    "\n",
+    "display(VBox([data_type, class_val]))\n",
+    "\"\"\"\n",
+    "# on data_type change update list of color maps\n",
+    "# based on class_val and data_type\n",
+    "\n",
+    "from pysal.contrib.viz.color import color_display_types\n",
+    "from pysal.contrib.viz.color import plot_cmaps as pcmaps\n",
+    "from ipywidgets import interact\n",
+    "\n",
+    "dt = sorted(color_display_types.keys(), reverse=True)\n",
+    "data_type = RadioButtons(description='Data Type', options=dt)\n",
+    "bindings = {}\n",
+    "for t in dt:\n",
+    "    bindings[t] = color_display_types[t].keys()\n",
+    "    \n",
+    "cmap_dd = Dropdown(description='CMap:', options=bindings[data_type.value])\n",
+    "\n",
+    "def type_change(change):\n",
+    "    with cmap_dd.hold_trait_notifications():\n",
+    "        cmap_dd.options = bindings[change['new']]\n",
+    "        #plot_cmaps('diverging')\n",
+    "\n",
+    "def cmap_change(change):\n",
+    "        with cmap_dd.hold_trait_notifications():\n",
+    "            print('new cmap', str(change['new']))\n",
+    "\n",
+    "data_type.observe(type_change, names=['value'])  \n",
+    "cmap_dd.observe(cmap_change, names=['value'])\n",
+    "\n",
+    "display(VBox([data_type]))\n",
+    "@interact(cmap=cmap_dd)\n",
+    "def plot_cmaps(cmap):\n",
+    "    #print(data_type,cmap)\n",
+    "    i = cmap_dd.options.index(cmap)\n",
+    "    pcmaps(data_type.value, i)\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 103,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "('qualitative', u'Pastel1', 5)\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAO0AAADtCAYAAABTTfKPAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAABjVJREFUeJzt3M2LVXUcx/Ez1xkfMwgNHfChVRKIEJWQiD1skpCEREIR\nCirdVJRQQQTZSnDRJggtIhLKICgqCIJaS9bSRRJBaqCSTynN6Djd219wz7ne85uRj7xe23P4fu+Z\nM++Zu/qN9Hq9CsjRudUfALg5ooUwooUwooUwooUwooUwo3UXz0wcO1tV1bKWO86NL1y/vO6GVeNL\n/zt99kKrPyArly/pnjpzfk7dPXuOrC7yPId2nOz7PA+//E2JHVVVVeeOvr+1757pjz4s8iyjL+6u\nfTfVvpEie6p9vdo9R05sL7Jnx5ov++5599vjxd7NO0+trf+5zaDaaKsyD9g44/TZC53uic9bLems\n2TlI [...]
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f3ff4612090>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "# adding k\n",
+    "\n",
+    "# on data_type change update list of color maps\n",
+    "# based on class_val and data_type\n",
+    "\n",
+    "from pysal.contrib.viz.color import color_display_types\n",
+    "from pysal.contrib.viz.color import plot_cmaps as pcmaps\n",
+    "from pysal.contrib.viz.color import get_color_map\n",
+    "from ipywidgets import interact\n",
+    "\n",
+    "dt = sorted(color_display_types.keys(), reverse=True)\n",
+    "data_type = RadioButtons(description='Data Type', options=dt)\n",
+    "bindings = {}\n",
+    "for t in dt:\n",
+    "    bindings[t] = color_display_types[t].keys()\n",
+    "    \n",
+    "cmap_dd = Dropdown(description='CMap:', options=bindings[data_type.value])\n",
+    "\n",
+    "def type_change(change):\n",
+    "    with cmap_dd.hold_trait_notifications():\n",
+    "        cmap_dd.options = bindings[change['new']]\n",
+    "        k_dd.options = kbindings[change['new']]\n",
+    "        #plot_cmaps('diverging')\n",
+    "\n",
+    "def cmap_change(change):\n",
+    "        with cmap_dd.hold_trait_notifications():\n",
+    "            print('new cmap', str(change['new']))\n",
+    "\n",
+    "data_type.observe(type_change, names=['value'])  \n",
+    "cmap_dd.observe(cmap_change, names=['value'])\n",
+    "kbindings = {'sequential': range(3,9+1),\n",
+    "            'qualitative': range(3,12+1),\n",
+    "            'diverging': range(3,11+1)}\n",
+    "k_dd = Dropdown(description='k', options=kbindings[data_type.value])\n",
+    "\n",
+    "display(VBox([data_type, k_dd]))\n",
+    "@interact(cmap=cmap_dd)\n",
+    "def plot_cmaps(cmap):\n",
+    "    #print(data_type,cmap)\n",
+    "    i = cmap_dd.options.index(cmap)\n",
+    "    pcmaps(data_type.value, i)\n",
+    "    print(data_type.value,cmap, k_dd.value)\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 108,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAO0AAADtCAYAAABTTfKPAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAACFtJREFUeJzt3EGIHncZx/GZ9515NynVpqFk26TdmtpuG+x2NWli00Ct\naVpBKoJ60IonQSliD54E0YMieFKoSFHwaD3pRY/iWSk9FQ/m4kGQpkjdFmETGzMee5B33unOfyf7\nK5/P9Q3P03emX/Y9PXXXdRWQY3az/wOA90a0EEa0EEa0EEa0EEa0EKbp+/DlI8der6pqfeSOK8/t\nvHFn3z/4Y/1gkT0Xu7/27vnO7NtF9vzwxo+W7vnF2bbEjqqqqitfe+WdpXvqF7aKfJfuxdd6n9nm\n2Z8V2XP5lW/07jn8/G+K7Nl96fNL93z/yHeLvZvv7fxg6Z7Nzc3Rey5fvlwv+2zVX9oSX3DIjPfT\nnhI7 [...]
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f3ff4462050>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "('sequential', u'Purples', 4)\n",
+      "('sequential', u'Purples', 3)\n"
+     ]
+    }
+   ],
+   "source": [
+    "# adding button\n",
+    "\n",
+    "# on data_type change update list of color maps\n",
+    "# based on class_val and data_type\n",
+    "\n",
+    "from pysal.contrib.viz.color import color_display_types\n",
+    "from pysal.contrib.viz.color import plot_cmaps as pcmaps\n",
+    "from pysal.contrib.viz.color import get_color_map\n",
+    "from ipywidgets import interact\n",
+    "\n",
+    "dt = sorted(color_display_types.keys(), reverse=True)\n",
+    "data_type = RadioButtons(description='Data Type', options=dt)\n",
+    "bindings = {}\n",
+    "for t in dt:\n",
+    "    bindings[t] = color_display_types[t].keys()\n",
+    "    \n",
+    "cmap_dd = Dropdown(description='CMap:', options=bindings[data_type.value])\n",
+    "\n",
+    "def type_change(change):\n",
+    "    with cmap_dd.hold_trait_notifications():\n",
+    "        cmap_dd.options = bindings[change['new']]\n",
+    "        k_dd.options = kbindings[change['new']]\n",
+    "        #plot_cmaps('diverging')\n",
+    "\n",
+    "def cmap_change(change):\n",
+    "        with cmap_dd.hold_trait_notifications():\n",
+    "            print('new cmap', str(change['new']))\n",
+    "\n",
+    "data_type.observe(type_change, names=['value'])  \n",
+    "cmap_dd.observe(cmap_change, names=['value'])\n",
+    "kbindings = {'sequential': range(3,9+1),\n",
+    "            'qualitative': range(3,12+1),\n",
+    "            'diverging': range(3,11+1)}\n",
+    "k_dd = Dropdown(description='k', options=kbindings[data_type.value])\n",
+    "def button_clicked(btn):\n",
+    "    print(data_type.value, cmap_dd.value, k_dd.value)\n",
+    "\n",
+    "btn = Button(description=\"Display Map\")\n",
+    "btn.on_click(button_clicked)\n",
+    "display(btn)\n",
+    "display(VBox([data_type, k_dd]))\n",
+    "@interact(cmap=cmap_dd)\n",
+    "def plot_cmaps(cmap):\n",
+    "    #print(data_type,cmap)\n",
+    "    i = cmap_dd.options.index(cmap)\n",
+    "    pcmaps(data_type.value, i)\n",
+    "    #print(data_type.value,cmap, k_dd.value)\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 109,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAO0AAADtCAYAAABTTfKPAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAACIlJREFUeJzt3E+IXeUZx/H3nPOeeyeSmmS0mUnGmWRsnCQ2k7GTZOpk\naKr5o1BSBKXQKl0VlCAG6aogulAEV0UibVDo0roQ3SiupOuW4CoUmtm4ECHjnzGxhSQm3tNNIavz\nnje8z31zf+X72d7hebzn5OvM6imapnEAdJS3+z8AwK0hWkAM0QJiiBYQQ7SAGKIFxPjQh3eV1ffr\nzSAp7PGiHHw9+L4K/czfit0XnXMTKXucc2tHmwuToR94ofyDyZ5XB6+17nnrUG2xwznn1p4+d711\nT3F63uS7NGfOB5/Z3KE/mexZPfdscM+GU++Z7Lly9onWPS9vftHs3bx06ZXWPXNzc8l7VldXi7bP\ngtGu [...]
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f3ff4d70290>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "# adding map\n",
+    "\n",
+    "# on data_type change update list of color maps\n",
+    "# based on class_val and data_type\n",
+    "\n",
+    "from pysal.contrib.viz.color import color_display_types\n",
+    "from pysal.contrib.viz.color import plot_cmaps as pcmaps\n",
+    "from pysal.contrib.viz.color import get_color_map\n",
+    "from ipywidgets import interact\n",
+    "\n",
+    "dt = sorted(color_display_types.keys(), reverse=True)\n",
+    "data_type = RadioButtons(description='Data Type', options=dt)\n",
+    "bindings = {}\n",
+    "for t in dt:\n",
+    "    bindings[t] = color_display_types[t].keys()\n",
+    "    \n",
+    "cmap_dd = Dropdown(description='CMap:', options=bindings[data_type.value])\n",
+    "\n",
+    "def type_change(change):\n",
+    "    with cmap_dd.hold_trait_notifications():\n",
+    "        cmap_dd.options = bindings[change['new']]\n",
+    "        k_dd.options = kbindings[change['new']]\n",
+    "        #plot_cmaps('diverging')\n",
+    "\n",
+    "def cmap_change(change):\n",
+    "        with cmap_dd.hold_trait_notifications():\n",
+    "            print('new cmap', str(change['new']))\n",
+    "\n",
+    "data_type.observe(type_change, names=['value'])  \n",
+    "cmap_dd.observe(cmap_change, names=['value'])\n",
+    "kbindings = {'sequential': range(3,9+1),\n",
+    "            'qualitative': range(3,12+1),\n",
+    "            'diverging': range(3,11+1)}\n",
+    "k_dd = Dropdown(description='k', options=kbindings[data_type.value])\n",
+    "def button_clicked(btn):\n",
+    "    print(data_type.value, cmap_dd.value, k_dd.value)\n",
+    "\n",
+    "btn = Button(description=\"Display Map\")\n",
+    "btn.on_click(button_clicked)\n",
+    "display(btn)\n",
+    "display(VBox([data_type, k_dd]))\n",
+    "@interact(cmap=cmap_dd)\n",
+    "def plot_cmaps(cmap):\n",
+    "    #print(data_type,cmap)\n",
+    "    i = cmap_dd.options.index(cmap)\n",
+    "    pcmaps(data_type.value, i)\n",
+    "    #print(data_type.value,cmap, k_dd.value)\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAO0AAADtCAYAAABTTfKPAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAABkJJREFUeJzt3E+oZnUdx/Fznvv/KrYpZqZpQBdqkmAxDLSZ6A5EKJmI\nCOpCcRaCuBmkjMqICScIYjbRHyKE2rQQDV1Mi8AJIhJEsBBUCFr4ZxqajTN05869M89pYS3POc/w\n+92n+ejrtT0P3+8958x7OKtf23VdA+SY/L//AODqiBbCiBbCiBbCiBbCiBbCLA5dvP2ZP/yzaZo9\nhTvOvvH0V/YO/WD/z49U2fPe4y8P7ml/9MUqe7pvvdK7Z/nJF2vsaJqmObt98p7ePRsbG1Xu5fTp\n04PPbPkTn7qyc/5c0X/uSzd8crr9wb8Whn7z9edvrXI/L933du/9PHL4l9Xeza//9FjvnskPnyze\nM/3O [...]
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f3ff50fc450>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "plot_cmaps('diverging', 5)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAO0AAADtCAYAAABTTfKPAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAACGRJREFUeJzt3E+oZnUdx/Fznuc8z50Ry+tgc0dHr47oVcvr6IxzcxxI\nm1EDUYIiKKNVUEgk0SqIWhRBqwgjpKBluojaCK2idSGzkiBn0yIIx8RGC2Ym7T4tZ3X+yPnd43zk\n9drey/frec59O8/qW69WqwrIMfug/wOA90e0EEa0EEa0EEa0EEa0EKbp+uGL6wdfr6pqY+SO889c\neONQ1y/8sb6ryJ7Tq9c693x39p0ie360++PWPb88sSixo6qq6vzXXnm3dU/93HaRZ1k9/2rnZ7Z1\n4udF9px75Rude/Y/+9siey6+8PnWPT9Y/16xd/P9Cz9s3bO1tTV6z7lz5+q2n/X9S1viAYfM+DDt\nKbFj [...]
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f3ff4a053d0>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "plot_cmaps('sequential', 10)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 47,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "1\n",
+      "2\n",
+      "3\n",
+      "4\n",
+      "5\n",
+      "6\n",
+      "7\n"
+     ]
+    }
+   ],
+   "source": [
+    "from ipywidgets import Text\n",
+    "\n",
+    "int_range = IntSlider()\n",
+    "display(int_range)\n",
+    "\n",
+    "text = Text()\n",
+    "display(text)\n",
+    "\n",
+    "def on_value_change(change):\n",
+    "    print(change['new'])\n",
+    "    text.value = str(change['new'])\n",
+    "    \n",
+    "    \n",
+    "int_range.observe(on_value_change, names='value')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 35,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [],
+   "source": [
+    "\"\"\"\n",
+    "data_type = RadioButtons(options=['sequential', 'diverging', 'qualitative'])\n",
+    "\n",
+    "bindings = {'sequential': range(3,9+1),\n",
+    "            'diverging': range(3,11+1),\n",
+    "            'qualitative': range(3,12+1)}\n",
+    "\n",
+    "class_val = Dropdown(options=bindings[data_type.value])    \n",
+    "\n",
+    "def type_change(change):\n",
+    "    class_val.options = bindings[change['new']]\n",
+    "\n",
+    "data_type.observe(type_change, names=['value'])\n",
+    "\n",
+    "display(VBox([data_type, class_val]))\n",
+    "\"\"\"\n",
+    "# on data_type change update list of color maps\n",
+    "# based on class_val and data_type\n",
+    "\n",
+    "from pysal.contrib.viz.color import color_display_types\n",
+    "\n",
+    "dt = sorted(color_display_types.keys(), reverse=True)\n",
+    "data_type = RadioButtons(description='Data Type', options=dt)\n",
+    "bindings = {}\n",
+    "for t in dt:\n",
+    "    bindings[t] = color_display_types[t].keys()\n",
+    "    \n",
+    "cmap = Dropdown(description='CMap:', options=bindings[data_type.value])\n",
+    "\n",
+    "def type_change(change):\n",
+    "    with cmap.hold_trait_notifications():\n",
+    "        cmap.options = bindings[change['new']]\n",
+    "\n",
+    "data_type.observe(type_change, names=['value'])\n",
+    "\n",
+    "display(VBox([data_type, cmap]))\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {
+    "collapsed": false,
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "ename": "NameError",
+     "evalue": "name 'interact' is not defined",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
+      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
+      "\u001b[1;32m<ipython-input-12-6677e49d3878>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m      8\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mprinter\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0my\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      9\u001b[0m     \u001b[1;32mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0my\u001b[0m\u00 [...]
+      "\u001b[1;31mNameError\u001b[0m: name 'interact' is not defined"
+     ]
+    }
+   ],
+   "source": [
+    "x_widget = FloatSlider(min=0.0, max=10.0, step=0.05)\n",
+    "y_widget = FloatSlider(min=0.5, max=10.0, step=0.05, value=5.0)\n",
+    "\n",
+    "def update_x_range(*args):\n",
+    "    x_widget.max = 2.0 * y_widget.value\n",
+    "y_widget.observe(update_x_range, 'value')\n",
+    "\n",
+    "def printer(x, y):\n",
+    "    print(x, y)\n",
+    "interact(printer,x=x_widget, y=y_widget)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "import pysal as ps\n",
+    "import numpy as np\n",
+    "import matplotlib.pyplot as plt\n",
+    "from scipy.linalg import inv\n",
+    "%matplotlib inline"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [],
+   "source": [
+    "from ipywidgets import interact\n",
+    "interact(draw_map, lamb=(-0.9, 0.9))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "def draw_map(lamb):\n",
+    "    s = 20\n",
+    "    n = s**2\n",
+    "    w = ps.lat2W(s, s, rook=False)\n",
+    "    w.transform = 'R'\n",
+    "    e = np.random.random((n, 1))\n",
+    "    u = inv(np.eye(n) - lamb * w.full()[0])\n",
+    "    u = np.dot(u, e)\n",
+    "    ul = ps.lag_spatial(w, u)\n",
+    "    u = (u - u.mean()) / np.std(u)\n",
+    "    ul = (ul - ul.mean()) / np.std(ul)\n",
+    "    gu = u.reshape((s, s))\n",
+    "    # Figure\n",
+    "    f = plt.figure(figsize=(9, 4))\n",
+    "    ax1 = f.add_subplot(121)\n",
+    "    ax1.matshow(gu, cmap=plt.cm.YlGn)\n",
+    "    ax1.set_frame_on(False)\n",
+    "    ax1.axes.get_xaxis().set_visible(False)\n",
+    "    ax1.axes.get_yaxis().set_visible(False)\n",
+    "    #---\n",
+    "    ax2 = f.add_subplot(122)\n",
+    "    sc = ax2.scatter(u, ul, linewidth=0)\n",
+    "    ols = ps.spreg.OLS(ul, u)\n",
+    "    tag = \"b = %.3f\"%ols.betas[1][0]\n",
+    "    ax2.plot(u, ols.predy, c='red', label=tag)\n",
+    "    ax2.axvline(0, c='0.5')\n",
+    "    ax2.axhline(0, c='0.5')\n",
+    "    ax2.legend()\n",
+    "    plt.xlabel('u')\n",
+    "    plt.ylabel('Wu')\n",
+    "    plt.suptitle(\"$\\lambda$ = %.2f\"%lamb)\n",
+    "    plt.show()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "anaconda-cloud": {},
+  "kernelspec": {
+   "display_name": "Python 2",
+   "language": "python",
+   "name": "python2"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 2
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython2",
+   "version": "2.7.12"
+  },
+  "widgets": {
+   "state": {
+    "0016b3499cb04077af454de8eebf93f8": {
+     "views": []
+    },
+    "003a4715bb0c47c7a52217b176b5007b": {
+     "views": []
+    },
+    "008f077e9f08408e9908be98e1759ce6": {
+     "views": []
+    },
+    "00ba00bc942c4be1a608281b1dba9cc5": {
+     "views": []
+    },
+    "0104cac22ed447b4b9f07bcdfd3aee2b": {
+     "views": []
+    },
+    "01741527c0e940ce8dec4323f88f45cc": {
+     "views": []
+    },
+    "019222db4d6d4314873cb0d1ddea84c7": {
+     "views": []
+    },
+    "0196758498cf4beb97346aac74748755": {
+     "views": []
+    },
+    "0257eb76047e477491b579132de4d8e4": {
+     "views": []
+    },
+    "02e4fabe1de34a698e7102df3209dc54": {
+     "views": []
+    },
+    "0437be95374f4482a1bfd02d98a13367": {
+     "views": []
+    },
+    "0490d44a690640bc8984b31e62acfeea": {
+     "views": []
+    },
+    "04e65fb300dd45a78c515d93eccf3fb5": {
+     "views": []
+    },
+    "053c14e62119411d9fd60b759300f51e": {
+     "views": []
+    },
+    "0591ffe732764949ad8bee298a2e4eca": {
+     "views": [
+      {
+       "cell_index": 9
+      }
+     ]
+    },
+    "05c3b57412a14405b562296301afc485": {
+     "views": []
+    },
+    "05cfecde4da54ff8ae8b719c1ddffc87": {
+     "views": []
+    },
+    "064b6909676848b7a108353a02403a4d": {
+     "views": []
+    },
+    "068c09bea5504f99affeb85e1bd1e5e2": {
+     "views": []
+    },
+    "06a7bb44611d4eba98b05380c6772170": {
+     "views": []
+    },
+    "071dc6ac440c4a02b2f27feb49e441ff": {
+     "views": []
+    },
+    "0726a0d7f1d04575a438e5e51bec9600": {
+     "views": []
+    },
+    "07520e9ca6eb4e1b996f3f1f8be02e06": {
+     "views": []
+    },
+    "07a54e21785942bbb324a5450705baba": {
+     "views": []
+    },
+    "07c32854fac444b4ac3e0d68dbf44ae7": {
+     "views": []
+    },
+    "082f06328b4c41d69fbfa9aab163d91c": {
+     "views": []
+    },
+    "0939aea53eb04dc391bea781c81718e7": {
+     "views": []
+    },
+    "093f04d527f249668fe7ec10c79f5f99": {
+     "views": []
+    },
+    "09831ee9fa9142738894c27d82b6ec21": {
+     "views": []
+    },
+    "0997fc971cf54a0abca4653549d8ff1b": {
+     "views": []
+    },
+    "09a476e5746a42c988c35d5e6e22dc1f": {
+     "views": []
+    },
+    "09c2d301c8fe469cb0add3aeea54201b": {
+     "views": []
+    },
+    "09c3a2fb682e4a29911ef3630dd29d9a": {
+     "views": []
+    },
+    "09cb4054961547c481505698d075d05e": {
+     "views": []
+    },
+    "09cb5bb355cb4da5951eff847054084d": {
+     "views": []
+    },
+    "0a5b31ec51e34ecc9f1a1dac7c4e2433": {
+     "views": []
+    },
+    "0b2ee3297a3844f9b6c47c54ad6b816d": {
+     "views": []
+    },
+    "0b717104e4184345934417b2f7a825fe": {
+     "views": []
+    },
+    "0b7e163530ab48d6b8a38aee77219e01": {
+     "views": []
+    },
+    "0c18030d84934e79b166248cccdb6bc1": {
+     "views": []
+    },
+    "0c2c3ae1c1194ea080cb78c02a149ed8": {
+     "views": []
+    },
+    "0c4029fa99144882860562ad35f0b977": {
+     "views": []
+    },
+    "0c410f82d9f24811810519b4962240cd": {
+     "views": []
+    },
+    "0cd528b4341c48b9ac195d43fb6c299e": {
+     "views": []
+    },
+    "0cfbf66f866142ce86e9465f6c264b26": {
+     "views": []
+    },
+    "0cfe39142ae940f7b5acb9a58c2675e0": {
+     "views": []
+    },
+    "0d13003fc036450fb2b346a0a55b192e": {
+     "views": []
+    },
+    "0d2000c5fec24c39ab9469cf5a4edd11": {
+     "views": []
+    },
+    "0d65e0417c7641d19e0123690b1fcb9f": {
+     "views": []
+    },
+    "0d68b67cc9764f1f835f12e2afceba51": {
+     "views": [
+      {
+       "cell_index": 8
+      }
+     ]
+    },
+    "0de21fa0e9554f699184fea45af8e8a7": {
+     "views": []
+    },
+    "0df56fdf13bd4b2490dbd54445c5aaf6": {
+     "views": []
+    },
+    "0e1a9fb87b554a6abe133f10d9c3bc25": {
+     "views": []
+    },
+    "0e67e55533a94ebaa96a5ccbdd4ccdeb": {
+     "views": []
+    },
+    "0e7cfc958ef54e11984c17ad7064c998": {
+     "views": []
+    },
+    "0eb46f2c6e764166b721634040e33731": {
+     "views": []
+    },
+    "0ee099a07c2345beb249948c800c277a": {
+     "views": []
+    },
+    "0ef22c81e4d5425499301564aaae0ead": {
+     "views": []
+    },
+    "0f101c5a342c493cab99ca3edce2347c": {
+     "views": []
+    },
+    "0f4cb84c8885411aae40b8c5fb717f65": {
+     "views": [
+      {
+       "cell_index": 7
+      }
+     ]
+    },
+    "0ffe410b5cad4341bccd9674702049a5": {
+     "views": [
+      {
+       "cell_index": 7
+      }
+     ]
+    },
+    "100fd494416345f899694a43ab1c87a1": {
+     "views": []
+    },
+    "108d2357e3604f848b72cffa3b89f67b": {
+     "views": []
+    },
+    "108e3ebb7dbc49ae92ab242b9e5037f3": {
+     "views": []
+    },
+    "1096df6effdb437f91d858964737cce2": {
+     "views": []
+    },
+    "10a3d522cc6d4874afeec0bb315da6d3": {
+     "views": []
+    },
+    "10aee90e502b45fb985c19bb8ecdeeb8": {
+     "views": []
+    },
+    "113a45ae9c1b470a9e06efa1af2b8f8f": {
+     "views": []
+    },
+    "11cf40373eb04803903a20843e7f021f": {
+     "views": []
+    },
+    "123e9b45b7b540b8b7126075bbecdab0": {
+     "views": []
+    },
+    "12b35e4758f74ab494e29871b77b6bce": {
+     "views": []
+    },
+    "1397f67dd4b2488cb3827d85c4426f77": {
+     "views": []
+    },
+    "13b0729b752240479055bb325c291b9a": {
+     "views": []
+    },
+    "13b44f3699234fba8f6ca17747b51a7e": {
+     "views": []
+    },
+    "13effbca2c58402cb6d2fb5830d2eab6": {
+     "views": []
+    },
+    "149c3d65063d4002b22039609902baf8": {
+     "views": []
+    },
+    "14ddd7975a8e440fafcf32a1d673c894": {
+     "views": []
+    },
+    "165d2f3b17444417aeb2e4a494025e77": {
+     "views": []
+    },
+    "16d7f8ae93bf4b8089a218bf80bf9259": {
+     "views": [
+      {
+       "cell_index": 8
+      }
+     ]
+    },
+    "1729e425db554badb57631333ef91d44": {
+     "views": []
+    },
+    "174b683e944f4bcbb90652cae4446854": {
+     "views": []
+    },
+    "17a3604d73af4059af58bf58653290d8": {
+     "views": []
+    },
+    "17f1e70038ce4005a980796431bef14d": {
+     "views": []
+    },
+    "18517acdb40248089d4ad58d93331814": {
+     "views": []
+    },
+    "18567a6b41764c73a830d5ad80ad3ec6": {
+     "views": []
+    },
+    "18e41d9b07494be9940040de285cd154": {
+     "views": []
+    },
+    "1923d9ba63364101ad0c5f714f2a086a": {
+     "views": []
+    },
+    "19327f78b8ab484492346945dd266d03": {
+     "views": []
+    },
+    "194097923fed41bfb263ca9714079d45": {
+     "views": []
+    },
+    "19dd4cbfbc73487aac83137be14bef06": {
+     "views": []
+    },
+    "19e3b1b4474143f4b30295629792e679": {
+     "views": []
+    },
+    "1a19426060f3481ebb85b7ef890ff82d": {
+     "views": []
+    },
+    "1a691c87b1e04dfdb10c09653d3e3d51": {
+     "views": []
+    },
+    "1a791374f02b45f59abba842bda4f0a3": {
+     "views": [
+      {
+       "cell_index": 7
+      }
+     ]
+    },
+    "1a8152e9b6df491ab6e9fbd6d0c31c20": {
+     "views": []
+    },
+    "1aa62109306347fdb58345f94d03b037": {
+     "views": []
+    },
+    "1ac1d33196dc4e49b2a177f3d27715a5": {
+     "views": []
+    },
+    "1ac5680392ca4d4c99fc9b6b146b1839": {
+     "views": []
+    },
+    "1ade3f665ef14b93b6985d33bfdf578e": {
+     "views": []
+    },
+    "1afdfb26760041dca0d68842a889b813": {
+     "views": []
+    },
+    "1b1b874986f44b3fb36f638cedaa0064": {
+     "views": []
+    },
+    "1b96c75cff4749358fb1c59b9efc8cb2": {
+     "views": []
+    },
+    "1c1836dd8a0b46e0adb965a7f05d7574": {
+     "views": [
+      {
+       "cell_index": 9
+      }
+     ]
+    },
+    "1c342c3706b24b4eb2036aa80bc65723": {
+     "views": []
+    },
+    "1c35d7267c204ab9b2c940132a155b8e": {
+     "views": []
+    },
+    "1cf109e5b1a74cf1a997c0c18d56e1f7": {
+     "views": [
+      {
+       "cell_index": 7
+      }
+     ]
+    },
+    "1cf98f21636d4b3a9dd53c4fa2dc0a84": {
+     "views": []
+    },
+    "1d745293b92b46cc93b27826a31c946c": {
+     "views": []
+    },
+    "1dd5d6c8382047409acecea4b78a90ac": {
+     "views": []
+    },
+    "1dfca25f881d4da2bffbd5c76420dfd7": {
+     "views": []
+    },
+    "1e1526a580d64e16bb32ae6b0685486d": {
+     "views": []
+    },
+    "1e3f65d939ee44ca95955a1f49b5ce36": {
+     "views": []
+    },
+    "1e9b8120ff344c8dbf60545fa1bb6d24": {
+     "views": []
+    },
+    "1f631444abfe4b9cb3668185773bf2a6": {
+     "views": []
+    },
+    "1f9902d913e24ae3b5b58ea88ae32658": {
+     "views": []
+    },
+    "1f999f07b23b4467936558dd57b434ba": {
+     "views": []
+    },
+    "1faad7b4853042d0a80f1968a6d311e2": {
+     "views": []
+    },
+    "1fbcd2439db7440eb29c5f26875c04fd": {
+     "views": []
+    },
+    "1fe2fc90ec3d4710a7f90213f88c00ba": {
+     "views": []
+    },
+    "20576886f35e4906baf66531e23c6ad4": {
+     "views": []
+    },
+    "205dea2162824a4ab2f3a78230491195": {
+     "views": []
+    },
+    "207dc06b7a834b2fb637bd02cb2229af": {
+     "views": []
+    },
+    "20beb24f190b44a3be47048e8448c0e7": {
+     "views": []
+    },
+    "20cf126f434a4c4daa0496004cf0effa": {
+     "views": []
+    },
+    "20eff81f37664f749f1ea6ad441c5c57": {
+     "views": []
+    },
+    "2116a4ecfb324543ac96988bf186a5b6": {
+     "views": []
+    },
+    "21366ae27d1f4e8c9eb3b910e92bd419": {
+     "views": []
+    },
+    "21bff19ceecf4a8c82f0c6caa0670f7c": {
+     "views": []
+    },
+    "22509020cc324f5db9d4b38a74305a87": {
+     "views": []
+    },
+    "22c9f50922af42a09a82e88729505768": {
+     "views": []
+    },
+    "231381590a4043929d64672c6b19a8bd": {
+     "views": []
+    },
+    "23770bec03cb468db191cacb5f8efbc6": {
+     "views": []
+    },
+    "2378a1a65ce44a6c98da36ecd2f49285": {
+     "views": []
+    },
+    "238ef4008515485b8e368d9f5a77fe78": {
+     "views": []
+    },
+    "23d391a371e4408cbfd44b2ebbfcbc7b": {
+     "views": []
+    },
+    "244d92967eed4c6b9f19c383b912d6fa": {
+     "views": []
+    },
+    "2451c788a86542ba8278725bb3930137": {
+     "views": []
+    },
+    "2458108676a342659c944b636ba00f62": {
+     "views": []
+    },
+    "24b84e43a40b4c039607c883fc97688f": {
+     "views": []
+    },
+    "24fc1c3cbba24693ab5ff5840d2c7fc7": {
+     "views": []
+    },
+    "2599b56463dc45b6aadbff1c7ba2d5f9": {
+     "views": []
+    },
+    "259d073f0db94d7d96d8016abdb141c9": {
+     "views": []
+    },
+    "25cf716a722843d8a39c305c18536738": {
+     "views": []
+    },
+    "261e155108474bc7b4fb738f770d630e": {
+     "views": [
+      {
+       "cell_index": 9
+      }
+     ]
+    },
+    "27c52e53eb0f49a680f3940ea2a22f7e": {
+     "views": []
+    },
+    "27ce634f6a6f4f7cadc3a6bb213e838e": {
+     "views": []
+    },
+    "27e2e465540f4208b0127932840f5536": {
+     "views": []
+    },
+    "27e97be54c824403b014f131b66f3e02": {
+     "views": []
+    },
+    "28bedf261f1341d5874b69ad64e657a1": {
+     "views": [
+      {
+       "cell_index": 7
+      }
+     ]
+    },
+    "293b5268f3194baca3f6f2ed23ddb8a9": {
+     "views": []
+    },
+    "2a14a856c57742f0a727f6dd1fef961d": {
+     "views": []
+    },
+    "2a4c16eac17f46ebb9bfdaf54c0c84f2": {
+     "views": []
+    },
+    "2a8b0bdd996a482490b0ce54c87c344d": {
+     "views": []
+    },
+    "2a954fb560a94382bd60c193b8791869": {
+     "views": []
+    },
+    "2a994e8026634dcb809f394e9fe22b44": {
+     "views": []
+    },
+    "2accfad2d8f344d89ed0c59f05f04ab0": {
+     "views": [
+      {
+       "cell_index": 8
+      }
+     ]
+    },
+    "2aec0ab30b0f499b879633a25434b4c1": {
+     "views": []
+    },
+    "2afe5270681c446095a7fd399e62153f": {
+     "views": []
+    },
+    "2b7d87b399f64a19ac4c7cdf617827e9": {
+     "views": []
+    },
+    "2b8e00fdea7f473c93c73373f8f695ef": {
+     "views": []
+    },
+    "2bb46e6f581e4741a591708857a8fd98": {
+     "views": []
+    },
+    "2bd0234d4e31493285abcb1edc5eb7d6": {
+     "views": []
+    },
+    "2bd9d98c66fc45a09a2a90925e0fadff": {
+     "views": []
+    },
+    "2bdf8565e2c8476bbb64ffaa7547b4d8": {
+     "views": []
+    },
+    "2c37c873c9484dd495ac78819f0a03ab": {
+     "views": []
+    },
+    "2c94248856974040a1eed04defdf1505": {
+     "views": []
+    },
+    "2ca1f3e235d345da95497c501f8cbeca": {
+     "views": []
+    },
+    "2d40d16335614fa680eacd7442bfa4ae": {
+     "views": []
+    },
+    "2da3c606849d498b8133f6199020d8d6": {
+     "views": []
+    },
+    "2dd52fdd7f6f40f3a781ae6eb28cbc85": {
+     "views": []
+    },
+    "2e6d9ecbeb0d44d2be54d71dd38cc3a3": {
+     "views": []
+    },
+    "2e7d1ebcb5f04cab9d4ee34da945d861": {
+     "views": [
+      {
+       "cell_index": 9
+      }
+     ]
+    },
+    "2e99c7f738244d02a44e28a12ff5f903": {
+     "views": []
+    },
+    "2f76f7a4a04c4459b769c3535db34ff7": {
+     "views": []
+    },
+    "2f7ea5992be24c18b54017d5881cf2a5": {
+     "views": []
+    },
+    "301db2a8fca142f882c82079cd8f48d2": {
+     "views": []
+    },
+    "303a10e2ca874e16817614a1cada7646": {
+     "views": []
+    },
+    "30641cb639804d9da0fae1d500079e8b": {
+     "views": []
+    },
+    "3076fd74daab4191ba8831a0dcefa15c": {
+     "views": []
+    },
+    "3156f529793d43f880c9fd0c0ea61b06": {
+     "views": [
+      {
+       "cell_index": 9
+      }
+     ]
+    },
+    "3161fcc87a254ebab82dde405bb75720": {
+     "views": []
+    },
+    "318b8e00523d4e059b675c173d757a03": {
+     "views": []
+    },
+    "319a40558b4141ae912d9dd445175a7e": {
+     "views": []
+    },
+    "31f3c65fac4c454ba408a3414930f895": {
+     "views": []
+    },
+    "32139327e33247a3a964299587d5285f": {
+     "views": []
+    },
+    "321bbb8178ce4510a80a10609025d4c1": {
+     "views": []
+    },
+    "32298b87944c4fcc96ed7a08ef727576": {
+     "views": []
+    },
+    "32394da78517448885c67712fca8bde5": {
+     "views": []
+    },
+    "324551de1fe149f2b9858cad00a955c7": {
+     "views": []
+    },
+    "32598fc4a16b4bde8bcdb62f618e08cf": {
+     "views": []
+    },
+    "329c5252f8cf411e825ea0d18d2eb0a6": {
+     "views": []
+    },
+    "329cb6152fcc4675bcc463fd8badae0f": {
+     "views": []
+    },
+    "32c78536ec7e442e8cfe339238ff7000": {
+     "views": []
+    },
+    "32e9ba20061d41d7b42684039659816d": {
+     "views": []
+    },
+    "32fad3a0f18942e0a40dbd8819100975": {
+     "views": []
+    },
+    "3303aee6ca7d43ab8143b2abae2edc92": {
+     "views": []
+    },
+    "3350fa2abc66409aa8513f3a172931a0": {
+     "views": []
+    },
+    "33eec3d343f440aab86934d4b4d4e25c": {
+     "views": []
+    },
+    "33f6a7670519431680f72e2a7f1c2bb0": {
+     "views": []
+    },
+    "3446e7106cbc4b03b54a8f0883602094": {
+     "views": []
+    },
+    "350ba4be4a57464993336ddd1c2c8521": {
+     "views": []
+    },
+    "3546d9dc2a5e468fa7003499751e212f": {
+     "views": [
+      {
+       "cell_index": 7
+      }
+     ]
+    },
+    "356e39d6f8a646639094ad42a3db8ba7": {
+     "views": []
+    },
+    "366df8bee942470a90b7fae291548dd3": {
+     "views": []
+    },
+    "36fcc5a7dee14f1b9612049d446a299d": {
+     "views": []
+    },
+    "371d09b3fc3c4bb5810bb2a297f9ec80": {
+     "views": []
+    },
+    "371d7b43deb247d3ae7cc7b9b897d99c": {
+     "views": []
+    },
+    "379cafcd1d9543568d702c96ca21dedb": {
+     "views": []
+    },
+    "380a822784de4fa3ae88279d55810fba": {
+     "views": []
+    },
+    "38237c82ab2145d89bad49389131b1b6": {
+     "views": []
+    },
+    "384c409c23664766bb188c6fa66455ae": {
+     "views": []
+    },
+    "3856b2694d774484954b889c61984863": {
+     "views": []
+    },
+    "3858cdf894e44bcfbc67a87468483ca0": {
+     "views": []
+    },
+    "386ca45c778d46d3b98d322de7146074": {
+     "views": []
+    },
+    "3963ae77c4fb4ab09519b06d93e0af46": {
+     "views": []
+    },
+    "3977425517714ba3b063c53dd03e7614": {
+     "views": []
+    },
+    "39828964c9864ac8a41609f8b3092c79": {
+     "views": []
+    },
+    "39946305ab7a41af940682f9f1ef1624": {
+     "views": []
+    },
+    "399670537c644f0abff5f3328a8101a2": {
+     "views": []
+    },
+    "399ddb8ce0cf429f8b643994757f6e14": {
+     "views": []
+    },
+    "39d077032c284d09b91bf915ebeda851": {
+     "views": []
+    },
+    "3a596907eb1249e9b5bb6eda58fcd8db": {
+     "views": [
+      {
+       "cell_index": 10
+      }
+     ]
+    },
+    "3a851a045b9f48bab8110d22c413d813": {
+     "views": []
+    },
+    "3abddbcc614d495284c173bd8d82f1ff": {
+     "views": []
+    },
+    "3ae3574cb2604ec1832d19a789f5809c": {
+     "views": []
+    },
+    "3afa14d9682f4fb488f03f4d4a05864a": {
+     "views": []
+    },
+    "3b0b84834c1347c49cfbd6a4fa89aa0b": {
+     "views": []
+    },
+    "3b2095072bb941ca8e3c660f39d119b0": {
+     "views": []
+    },
+    "3b3629d640e04337a9ce800a12973400": {
+     "views": []
+    },
+    "3b7a4b2fbd1647c09de4e28dd8b7a0e3": {
+     "views": []
+    },
+    "3b7e1e36074d446ebe282bdcddbdcb98": {
+     "views": [
+      {
+       "cell_index": 7
+      }
+     ]
+    },
+    "3ba6b89f22c94728ba0dea574a2e58ff": {
+     "views": []
+    },
+    "3c0af60a45974ecdb886ee2bc1958310": {
+     "views": []
+    },
+    "3c1874ef3a08487bb1c087172028680e": {
+     "views": []
+    },
+    "3c3b1794792b4d51b595da4895fffcc0": {
+     "views": [
+      {
+       "cell_index": 7
+      }
+     ]
+    },
+    "3c3bfb2b62bf4b899646026c36b347da": {
+     "views": []
+    },
+    "3c8484a8c4de4ae09d09b6c3313a960e": {
+     "views": []
+    },
+    "3ca034cec9e94d70a487fadd56dac46b": {
+     "views": []
+    },
+    "3ced3b573c9b4a9499ac5d5f3f54fb2a": {
+     "views": []
+    },
+    "3d24f00c88c0488ca8ba312a1030862b": {
+     "views": []
+    },
+    "3d648cd851cb47f5a043c923b7dcb737": {
+     "views": []
+    },
+    "3d6c638d1b2d4489b57ff25c528ed7d7": {
+     "views": []
+    },
+    "3d78045be2f04140a8128f6ad1a2c587": {
+     "views": []
+    },
+    "3df9d2fdb6d34c86bed243602ffdf16b": {
+     "views": []
+    },
+    "3e7a1ec35b7d4e4e941afcdbcaf58f1f": {
+     "views": []
+    },
+    "3f345a449a404ed09cad6b4e169b3839": {
+     "views": []
+    },
+    "3f45ca49839b4b77b598552813d1cc96": {
+     "views": []
+    },
+    "3f520c2c544d4dc49cf7e63c84ccd020": {
+     "views": []
+    },
+    "3f5eff85afb24b5fbb0f879c9ca3a7e3": {
+     "views": []
+    },
+    "3fb948be6f1d416fba951eff9c31229b": {
+     "views": []
+    },
+    "3feeccb1d60245a88f184bdd002a511e": {
+     "views": []
+    },
+    "410630f4793148c3be51f59f2d7138ab": {
+     "views": []
+    },
+    "414bb178e6bb4b3abb17463a942ba795": {
+     "views": []
+    },
+    "41d7a47572bb4720b359b0c00f09838a": {
+     "views": []
+    },
+    "4222f82ea8474d31906331f2713c65cc": {
+     "views": []
+    },
+    "42c37c92923d4422ba3ee6c3b08a234d": {
+     "views": []
+    },
+    "42ce1143d9ca419c885695774006d629": {
+     "views": []
+    },
+    "42e424f6cefe4d3e9c89a95e4c151dc6": {
+     "views": []
+    },
+    "43185cebb0154eefb0de591f7c6ffe0d": {
+     "views": []
+    },
+    "433ff2fe1743461cbcce1b2938cc1288": {
+     "views": []
+    },
+    "439d72f6dfcc4f8a80c48ba286a7c89d": {
+     "views": []
+    },
+    "43c9adebf7a7473ca9ca58887a841c3a": {
+     "views": []
+    },
+    "43e73bcc1c804e3fb018e50a9c1d1432": {
+     "views": []
+    },
+    "44267d929caf45eeb1c1bb6380ffd57e": {
+     "views": []
+    },
+    "448e994c6ac142a69c672a8b812016fb": {
+     "views": []
+    },
+    "44a512942f33409d85a2baa929dfdee2": {
+     "views": []
+    },
+    "44abe8c93f1a4bcc853e1bf9d0d446d4": {
+     "views": []
+    },
+    "44f2e4aab49041e887be03055f88d778": {
+     "views": []
+    },
+    "451af899617441638d24f370644d5bba": {
+     "views": []
+    },
+    "458bf7053b174004b03ee77c412ffd42": {
+     "views": []
+    },
+    "45b14b4e18ad41e284b62833254642d3": {
+     "views": []
+    },
+    "45d20a6da82e4f5eae720216e9247f7c": {
+     "views": []
+    },
+    "45f20e663b1d47c6b810c4b995d65ac3": {
+     "views": []
+    },
+    "45ff7a5847c048a6aa76d5e870205376": {
+     "views": []
+    },
+    "461843a9f73d48bab6de2e494a596d13": {
+     "views": []
+    },
+    "461d903cd20544eeb72f7b2600ee3d88": {
+     "views": []
+    },
+    "4629f98d775c420e8c2ab2f2bf96fd9b": {
+     "views": []
+    },
+    "463c441144394afdb3662568f56364b2": {
+     "views": [
+      {
+       "cell_index": 6
+      }
+     ]
+    },
+    "4641590134a64ada9e7de44ad3b2d788": {
+     "views": []
+    },
+    "468ff1263bc044f1acdbcbdce4a3f9c8": {
+     "views": []
+    },
+    "46a229570aab4b0db1dc9e39f3e5408e": {
+     "views": []
+    },
+    "4763876d0af14768a103a27e28e1b0e9": {
+     "views": []
+    },
+    "4799a349ff694f6da9a7fa76848c69e8": {
+     "views": []
+    },
+    "47c1054153344f76aba1603e55fd854b": {
+     "views": []
+    },
+    "481ab10e062a49b29cbec841082911f2": {
+     "views": []
+    },
+    "482219d26d7e475f9db3e2a66f056344": {
+     "views": []
+    },
+    "48a3bb5a75e644dbb693016fd65e25b3": {
+     "views": []
+    },
+    "48f39da2fc194a0c8ab01916ba9a231e": {
+     "views": []
+    },
+    "4903bca960644a2e993885adf4fcbf63": {
+     "views": []
+    },
+    "4904c1c6bf4c44199d8209613254127d": {
+     "views": []
+    },
+    "4966fddcd3414efbb1a2b4c8496b0040": {
+     "views": []
+    },
+    "496ca910b6a94b8fa48b02962288ac63": {
+     "views": []
+    },
+    "4972fb2bd5c64d50912dcc289c87ee8e": {
+     "views": []
+    },
+    "49785d35078a4121a3a44a11ad0779ee": {
+     "views": [
+      {
+       "cell_index": 7
+      }
+     ]
+    },
+    "49b5e01be7f94127b76ea604be844389": {
+     "views": []
+    },
+    "49ebcc4169634f889c53e7a17fdb1f44": {
+     "views": []
+    },
+    "49fde4e690574c968000fdeaed558fc7": {
+     "views": []
+    },
+    "4a0ce6de54934638aa156da679bc5720": {
+     "views": [
+      {
+       "cell_index": 10
+      }
+     ]
+    },
+    "4a1639dd756e4b639496326a532174db": {
+     "views": []
+    },
+    "4a2f26f963fb4fc0bb367d6fc6f31218": {
+     "views": []
+    },
+    "4a600dd02b384c16a6581dbebfdaf501": {
+     "views": []
+    },
+    "4a6206ddaf644d97ab9c28df6cadb1b8": {
+     "views": []
+    },
+    "4a653a143dc54eb78337059d0e363521": {
+     "views": []
+    },
+    "4a84b87b075045b4a4cf657a186d9886": {
+     "views": []
+    },
+    "4ad0fce530e74b7485e6d25c6f2d9a06": {
+     "views": []
+    },
+    "4b09472b017844bea20dd82c843927d3": {
+     "views": []
+    },
+    "4b5e807559364bcc8b83bff483dcdd7e": {
+     "views": []
+    },
+    "4ba8eff2c0594b219063672e0ff57cd2": {
+     "views": []
+    },
+    "4c6a2b131e904e2ca162d288750e31c0": {
+     "views": []
+    },
+    "4c74914879b84542b223eecc197e190b": {
+     "views": []
+    },
+    "4cb4d5f4ccde41b3a73f03d0a70bb8da": {
+     "views": []
+    },
+    "4cef9033016049519a4bd17fbf479673": {
+     "views": []
+    },
+    "4d7600ecb03b442cb89109636d147d88": {
+     "views": []
+    },
+    "4da806b158b04a47a5775e7ebeed8fd2": {
+     "views": []
+    },
+    "4dd3c7d4f155413896534b96242abfab": {
+     "views": []
+    },
+    "4dd5aef3fe3b47acb6e55dc55319f416": {
+     "views": []
+    },
+    "4e0e2225c290423bbc813204a70d57a8": {
+     "views": []
+    },
+    "4e327235ea764269a9952b0581bf1213": {
+     "views": []
+    },
+    "4e752ff9ea73488f8623259c24ab206d": {
+     "views": [
+      {
+       "cell_index": 10
+      }
+     ]
+    },
+    "4e8d9c189b234f51ac87612501f22518": {
+     "views": []
+    },
+    "4ea118f609054d44849e4b30d525f668": {
+     "views": []
+    },
+    "4eb26d17f83b4086a9ab77561656904c": {
+     "views": [
+      {
+       "cell_index": 6
+      }
+     ]
+    },
+    "4f17c47fff6b4abb87bc98251b86d487": {
+     "views": [
+      {
+       "cell_index": 6
+      }
+     ]
+    },
+    "4f47c23e517441b993f657e27789096d": {
+     "views": [
+      {
+       "cell_index": 2
+      }
+     ]
+    },
+    "4f79663ace4b4205a5b470532fc83322": {
+     "views": [
+      {
+       "cell_index": 8
+      }
+     ]
+    },
+    "4f9510ae9651469788da360b7b255ff1": {
+     "views": []
+    },
+    "4fdbd806ebeb472f84e7435383887b74": {
+     "views": []
+    },
+    "50050e37d64444a383011510fe024886": {
+     "views": []
+    },
+    "50065f2d00c4418c9c953978aeeeba9a": {
+     "views": []
+    },
+    "5034255825c74ca5b8ef27066b2f7f16": {
+     "views": []
+    },
+    "50bf38d2ba004d30bd8524196aaa74fb": {
+     "views": []
+    },
+    "511ff16fd38e4f2d81ca72de7e4b7449": {
+     "views": []
+    },
+    "5134840c91f74c89947ea50f09fecafd": {
+     "views": []
+    },
+    "5150fb6d0bcd42b4aaffbd6ca00bb01f": {
+     "views": []
+    },
+    "51849f2dc5d24aac8c62ba589a1f14f1": {
+     "views": []
+    },
+    "519c55f153004ff39aa40e07ff529219": {
+     "views": []
+    },
+    "51a4dab5aec249b090319cb42b51e45a": {
+     "views": []
+    },
+    "51a4f8d030d4487da7fcb3ac41b6fd75": {
+     "views": []
+    },
+    "51b6400fecc74e828734d94919ea3cae": {
+     "views": []
+    },
+    "522e029cb5a8443db23f0510848cbd5d": {
+     "views": []
+    },
+    "524ae90027ec47b7917915625c361549": {
+     "views": [
+      {
+       "cell_index": 6
+      }
+     ]
+    },
+    "52a4a9192de5478197ccd9c7db4cf1e3": {
+     "views": []
+    },
+    "52a4dfc6dc364d80851db3c15a7422b6": {
+     "views": []
+    },
+    "52f9011b2be24467bed6f19b9b690832": {
+     "views": []
+    },
+    "533708d7245e46b3afc7f53cf967a607": {
+     "views": []
+    },
+    "53d5bfa2228e4a2382f7d00a8f50f878": {
+     "views": []
+    },
+    "549914e9796e457fbd6f02f4ed77aa6c": {
+     "views": []
+    },
+    "5545e9f0a4a74691a61d3e1f133377ea": {
+     "views": []
+    },
+    "5578feb64dd6441bbf791aa9ac566dd9": {
+     "views": []
+    },
+    "55998f4ceba845b89809fe373f70766f": {
+     "views": []
+    },
+    "55a67dcf444a45f4a5deaa1134790628": {
+     "views": []
+    },
+    "5688a4b5bf5c4fa3b0db3f52b28b0def": {
+     "views": []
+    },
+    "56bafaafa97147f098bd78d4405324c0": {
+     "views": []
+    },
+    "56e0467644ad4bf18f2e0c1f77bf9c14": {
+     "views": []
+    },
+    "56e87b4d510c4d9db46ea2bdfed0c0ed": {
+     "views": []
+    },
+    "56f83f96395340d283afd1b692c35f56": {
+     "views": []
+    },
+    "57394d6a21c64877804660710c6eb8c4": {
+     "views": []
+    },
+    "57603fe39f7b4e8c8b49e18dfc2e3691": {
+     "views": []
+    },
+    "5871a7fa1198496aade9adf8c7cc1cb7": {
+     "views": []
+    },
+    "58d90d7de5de43429db8d5d55c9f8de3": {
+     "views": []
+    },
+    "593a6660b6b64cf78cc285328acd9ced": {
+     "views": []
+    },
+    "59aba7176f50469a83a0129b22fb807b": {
+     "views": []
+    },
+    "5a6819703c484d9898b761de6f41803e": {
+     "views": []
+    },
+    "5b1db126a5874324b7e029aec93b964e": {
+     "views": []
+    },
+    "5b3691a0b8e643b5954673470e3b24ec": {
+     "views": []
+    },
+    "5b6c6a18ba9940c2b411e07e1cb7b126": {
+     "views": []
+    },
+    "5b92730889554b8cb45fcf25e23d0c31": {
+     "views": []
+    },
+    "5bb29b54c9bd4b6580aeca8aebd70763": {
+     "views": []
+    },
+    "5c2f42fd0cf947dc8dcdaebf88e74659": {
+     "views": []
+    },
+    "5c2f8867a35d430aa58fe30d008de9a9": {
+     "views": []
+    },
+    "5c5279a0d5b04b43843610bdfde0f3c2": {
+     "views": []
+    },
+    "5c9c84394b844b64b7b12bf88b7c7924": {
+     "views": []
+    },
+    "5ccddc15fe3b4a54b43e2bd94fbff24d": {
+     "views": []
+    },
+    "5ce87fca7b6746ae9ad7b91fc6141d57": {
+     "views": []
+    },
+    "5d329f4d2d444a1389235e6f3eeecf8c": {
+     "views": []
+    },
+    "5d3d45fc5c4445bf9863c65fc9ed8a40": {
+     "views": []
+    },
+    "5d853a56fa8c4241a150d508e4540d14": {
+     "views": []
+    },
+    "5d9287a7322445f59cc3f24b9130772b": {
+     "views": []
+    },
+    "5d93472fc08f44189af5c2b492d3378b": {
+     "views": []
+    },
+    "5eb20e84da96451aadafb1ca19863fb8": {
+     "views": []
+    },
+    "5f2160298a604cce943f538354e9d4fe": {
+     "views": []
+    },
+    "5f4828e0c7144a498943a486aed5b79d": {
+     "views": []
+    },
+    "5ff1161e6a4c4178b3c7467ede7dfe8e": {
+     "views": []
+    },
+    "602b580a0ab5451e8a4a80365d993344": {
+     "views": []
+    },
+    "605c75c9074144d0b93636a36bc17fcd": {
+     "views": []
+    },
+    "606ee329b52543078f6bd4383b163364": {
+     "views": []
+    },
+    "609788e2242f4d818be28b1c5b4eb160": {
+     "views": []
+    },
+    "60a1b05a417f4f2cbe39e91960889eaf": {
+     "views": []
+    },
+    "60cbea8039f743618abcd5ffa6e58a00": {
+     "views": []
+    },
+    "61118bedaa734bd7af1908be1781eb3e": {
+     "views": []
+    },
+    "61483932655f4f7f88a10d3be0db93fa": {
+     "views": []
+    },
+    "6265bbd95ce845c59c051c2729cec0aa": {
+     "views": []
+    },
+    "6298f7464bb74b9b84e9f2f29ef2bc87": {
+     "views": []
+    },
+    "62ba61ccc5f346b3ac0f56a707ebef45": {
+     "views": []
+    },
+    "638f3ecbc5c041579c5db72b6c62cd5b": {
+     "views": []
+    },
+    "63cc7767f81546d1a794b48dbb1a5bb3": {
+     "views": []
+    },
+    "6454100e344c4ac49e4a0f76702fac16": {
+     "views": []
+    },
+    "64b7ccaf9ac64b86b9f8cbef312e70af": {
+     "views": []
+    },
+    "64d3e47b512c4336b557e349d900cf56": {
+     "views": []
+    },
+    "64d657265f784e928cf5aa28ec8ea3bb": {
+     "views": [
+      {
+       "cell_index": 9
+      }
+     ]
+    },
+    "64f1d8e5906f4841aa395a8062498153": {
+     "views": []
+    },
+    "653ed549a039434d9b5a2ccd72d0a01d": {
+     "views": []
+    },
+    "656b964178f948f392d603733a55e440": {
+     "views": []
+    },
+    "657ee3586fd0497890e07446fe4e6303": {
+     "views": []
+    },
+    "65ce4899b0df47deadcbe09e6d615825": {
+     "views": []
+    },
+    "65d633f3cb0f49318fa9c5f6667fc69e": {
+     "views": [
+      {
+       "cell_index": 7
+      }
+     ]
+    },
+    "666a634afbd441129b01cbfc60ef98eb": {
+     "views": []
+    },
+    "6696083fe8e04c13975355c463339c2f": {
+     "views": []
+    },
+    "66a8d17224b84388977730891e59e365": {
+     "views": []
+    },
+    "66d328af4c874a2394fc397d0abe9b5f": {
+     "views": []
+    },
+    "679bd6baef684ddd8f20eb081333c1ec": {
+     "views": []
+    },
+    "67d348d593ba448cafdc623ea8e4b4ff": {
+     "views": []
+    },
+    "6810ca8d851e425bb77751d91d1ea732": {
+     "views": [
+      {
+       "cell_index": 7
+      }
+     ]
+    },
+    "687cc7f354ad4bcfa82d87fb6d600c3a": {
+     "views": []
+    },
+    "68831458a25b43bd821205d79629e16e": {
+     "views": []
+    },
+    "688fbd299a2a4f1e9655c7a9bf16db56": {
+     "views": []
+    },
+    "68b9fb648b2a4b2fb6aaf1e883ef88e8": {
+     "views": []
+    },
+    "68e7eb1d966d4aab95ec5bf487f67be8": {
+     "views": []
+    },
+    "694bd57d9392484d889e6eea94a35c3f": {
+     "views": []
+    },
+    "694c5d71b7ae498ab7dcb7f326b3d262": {
+     "views": []
+    },
+    "69546fb94b734ed7ac17c0cd23095df6": {
+     "views": []
+    },
+    "6969fdc5151d46c0b58172588a3c83b0": {
+     "views": []
+    },
+    "69fdd65b3bec4083a4dc75cd8f040a15": {
+     "views": []
+    },
+    "6a0d2cd452c8447e807a7791344f4f3c": {
+     "views": []
+    },
+    "6a1a384acf7e4cf2ae8266ba267d16cd": {
+     "views": []
+    },
+    "6a3be9268af344b89bba9dff65de322d": {
+     "views": []
+    },
+    "6a99b7cfdc5747c4b38dab74632f5a59": {
+     "views": []
+    },
+    "6a9df68924f44b7bb9fda609b3c420ad": {
+     "views": []
+    },
+    "6af8abe9df154637857b6eaf70922ff9": {
+     "views": []
+    },
+    "6b1636e228484c1891af32d1d274c7f8": {
+     "views": []
+    },
+    "6b32c4ea7edf4038ac23955d9210e93d": {
+     "views": []
+    },
+    "6b4fc87cadab4d2ab389f9d64dbe8702": {
+     "views": []
+    },
+    "6b6e1d2ccb34410b95b477241e1a6fe1": {
+     "views": []
+    },
+    "6c6ee6b3c8b747229109f28bf372565d": {
+     "views": []
+    },
+    "6c7e616e37fd4da59682a6c7d0bd5af8": {
+     "views": []
+    },
+    "6c9bc49e89494f6c8661a45273e6a49a": {
+     "views": [
+      {
+       "cell_index": 9
+      }
+     ]
+    },
+    "6ce5753cfd0d4bbdb236e40691942e6b": {
+     "views": []
+    },
+    "6d1af0c6109e4b2aaf2b7ec8dcd6628f": {
+     "views": []
+    },
+    "6d684a90534c4a0a9398722235977623": {
+     "views": []
+    },
+    "6d6f53f891db43c9be678e8cf704af81": {
+     "views": []
+    },
+    "6d7ddb093a4647b8b1def9e0ea02881c": {
+     "views": []
+    },
+    "6de90a4787a34d3783d19dd5a56f075a": {
+     "views": []
+    },
+    "6debe51b7a724b3a92249e67fe3f89ac": {
+     "views": []
+    },
+    "6e098b2b7f504155817a262441af68c6": {
+     "views": []
+    },
+    "6e10a4347fe743be8fb8a69f0e80fe5a": {
+     "views": []
+    },
+    "6e52cc30a49a4f62aee0f695c97c34c1": {
+     "views": []
+    },
+    "6e72a35c01d4428ca4d1c01097d66375": {
+     "views": []
+    },
+    "6ea5a6fd6d514ea28789134a797e2cb0": {
+     "views": []
+    },
+    "6f2f2a25330e4d9399e3ed8095de8365": {
+     "views": []
+    },
+    "6faee92865d047b98930a3082d75d02b": {
+     "views": []
+    },
+    "6fb2bcc44b154061adf035dd4c35b4ec": {
+     "views": []
+    },
+    "6fb7f76cda2340f3a3347238276288c0": {
+     "views": []
+    },
+    "6fc437e8f6e445d7a6f47fa4b17f3507": {
+     "views": []
+    },
+    "6fee47676e3a48b5860d513179150f72": {
+     "views": []
+    },
+    "700801578387493da18b703ea26c2d8d": {
+     "views": []
+    },
+    "70081bd3a52d4969baf12e34ba6939e2": {
+     "views": []
+    },
+    "701ab2efe1d245279d414daea63ac007": {
+     "views": []
+    },
+    "70a47a79e2cd4f338e2637a0a5265408": {
+     "views": []
+    },
+    "70fdddf9b64145bfa10d4b59bcac9e71": {
+     "views": []
+    },
+    "7109af41679f41ebbdec05dfffd192bf": {
+     "views": []
+    },
+    "71690c54c54b4453861a8d68f7d02b38": {
+     "views": []
+    },
+    "718c397eae934e188c791f51bb908f7a": {
+     "views": []
+    },
+    "719a6258fd474bb2a6eedb229bb72d03": {
+     "views": []
+    },
+    "71c8b5b860624355a061b58dd517347b": {
+     "views": []
+    },
+    "72150c4619a64bc4988ec6404799c724": {
+     "views": []
+    },
+    "7269963149dd4457aafbe0b8d1d50465": {
+     "views": []
+    },
+    "74378e357ac143348d13709a059b329c": {
+     "views": []
+    },
+    "7447bc651831499e9e16d640e3b3aa40": {
+     "views": []
+    },
+    "74897385cd384811a292efb16f3c03af": {
+     "views": []
+    },
+    "74964de816604edeb0b19ba9a1306529": {
+     "views": []
+    },
+    "74bcd805a4fa4405b2b413ba3c441a1d": {
+     "views": []
+    },
+    "75b367c04e1d471aad5d76b0dc36e4c6": {
+     "views": []
+    },
+    "76770695f41341fd8be2223b16bfc86e": {
+     "views": []
+    },
+    "769fe76a12a34f77b6f1dee442483cdd": {
+     "views": []
+    },
+    "76d607bc55264c55a26b46d2b7f4ae1f": {
+     "views": []
+    },
+    "77192af271b24fd8b5bda54be3a626a4": {
+     "views": []
+    },
+    "774ec32baff7499fb38c47d9710cce78": {
+     "views": []
+    },
+    "77520fdadf8b489a8c172e35855d82d1": {
+     "views": []
+    },
+    "777056244ecf4b14a1bc0ef9745891bd": {
+     "views": []
+    },
+    "77c7441a4a3748debb658bf826cf48a5": {
+     "views": []
+    },
+    "77c7d6e755664f6794924925d1ac5a48": {
+     "views": []
+    },
+    "783a2fe38f9c4925807042bedf58e36b": {
+     "views": []
+    },
+    "788708c0615e467c9bac8bbbe624d99e": {
+     "views": []
+    },
+    "78a4b4ac80d54667b7c28d845ae319e6": {
+     "views": []
+    },
+    "78ffb74626a64639a21f318e0bafd45a": {
+     "views": []
+    },
+    "7922b6b6ee1146fe91ce600c5bde9566": {
+     "views": [
+      {
+       "cell_index": 7
+      }
+     ]
+    },
+    "792ac03149cd428e96ff262e6ba9cef3": {
+     "views": []
+    },
+    "7930e9d278cf41929a6f5f021ee8ac8b": {
+     "views": []
+    },
+    "796909f2f0ed4a8ab88f9bc67a166813": {
+     "views": []
+    },
+    "7970efe915cf4e72b28177facee3570b": {
+     "views": [
+      {
+       "cell_index": 7
+      }
+     ]
+    },
+    "7ac344b7602a4125aa6ace8e3c89290b": {
+     "views": []
+    },
+    "7acf33c1fc6e47c9ac908ed500920ece": {
+     "views": []
+    },
+    "7b0bf96d63f0471787baeb39499ad8ae": {
+     "views": []
+    },
+    "7b8f8032940e46f7bbe2581f7262bbbe": {
+     "views": []
+    },
+    "7bbccb3fb8d04b029b2da10673d0be5b": {
+     "views": []
+    },
+    "7bc82ea6843d48838c1832d161b70117": {
+     "views": []
+    },
+    "7bd2eea592334395a7c6f2c6894971f9": {
+     "views": []
+    },
+    "7cb0c56ffa08411f84cf99d77c656368": {
+     "views": [
+      {
+       "cell_index": 8
+      }
+     ]
+    },
+    "7cd6729391b746cf9310b90acd101b7e": {
+     "views": []
+    },
+    "7d364ec94ea640e398dc17dadfb5c2d6": {
+     "views": []
+    },
+    "7d72d4783c4a449d9f0a8ae3e60aea80": {
+     "views": []
+    },
+    "7dc3db1a7aa540b8b2851a558ae042a0": {
+     "views": [
+      {
+       "cell_index": 3
+      }
+     ]
+    },
+    "7ea7495da25a430997017c0b8bc18a2c": {
+     "views": []
+    },
+    "7ec24e103f8743dc9391238c2f8dec92": {
+     "views": []
+    },
+    "7ecdac438f3f4649a14c735710677f94": {
+     "views": []
+    },
+    "7f2e165e43ed497fb791931525fbbf61": {
+     "views": []
+    },
+    "7f3e3c95b4d1490b9f1ffd4aee0f8eb5": {
+     "views": []
+    },
+    "7f91a295bd814914b2ffea34f2631ee2": {
+     "views": []
+    },
+    "7fa1fa440439472ba7ef3fab9f1db239": {
+     "views": []
+    },
+    "800b8b8e54f246a5a356f865a148e6a8": {
+     "views": []
+    },
+    "80238ad30d1f4666b9f3c3d637903a09": {
+     "views": []
+    },
+    "803f492ba1594213a290ab22876500ff": {
+     "views": []
+    },
+    "80646da878204f9cb3aaf41bfc85dce2": {
+     "views": []
+    },
+    "809e39bc77e04dde82465de18ceeb03a": {
+     "views": []
+    },
+    "80b32d44421c45d4a9b18779d94d8c15": {
+     "views": []
+    },
+    "814a91a80cf24e9c9fc9eefd71f5514c": {
+     "views": []
+    },
+    "8181e53322004cc5a6dce4b263e8a238": {
+     "views": []
+    },
+    "81c6d23c48894d8db017497940392369": {
+     "views": []
+    },
+    "81c7add6032e4190905039b5c25855f9": {
+     "views": []
+    },
+    "822ae02952954df29231345583f07d1d": {
+     "views": []
+    },
+    "823a3e00c6604907bc70b8b8c088e0b8": {
+     "views": []
+    },
+    "82984d473ffb4a57843e6ee5e198c8e8": {
+     "views": []
+    },
+    "83053b3dc6ec4467ad487a91b194eecb": {
+     "views": []
+    },
+    "83f0794a7dc34c52af028031bc6bb183": {
+     "views": []
+    },
+    "8405481fb5a6435983765df7b5a74c6d": {
+     "views": []
+    },
+    "84072514670045b7a6a41cd0856038f3": {
+     "views": []
+    },
+    "84f5e7cb7ad247f788a3f01b4b5d9606": {
+     "views": []
+    },
+    "85969a34813e4f4c815cc4ed703743fe": {
+     "views": []
+    },
+    "861c370ab6b7467da5c87b64abec3c65": {
+     "views": []
+    },
+    "86a2c32586cb472b8ee77d8797e7d326": {
+     "views": []
+    },
+    "86eaaae80e864222bc1aa492de2c58c8": {
+     "views": []
+    },
+    "8726cea909a945c69351b45a101fb0dd": {
+     "views": []
+    },
+    "87349333fdf548ac95bf96a72b7d614b": {
+     "views": [
+      {
+       "cell_index": 8
+      }
+     ]
+    },
+    "87bb065442554c4d94133dc5b687a7bd": {
+     "views": []
+    },
+    "87df37c668c3473c8e05ce20b6fdc306": {
+     "views": []
+    },
+    "87e48879a44d4f5ca0ec122071f948b1": {
+     "views": []
+    },
+    "87f0e1b9b09b4285928e49bdce5b43c2": {
+     "views": []
+    },
+    "88fbdc13df5a4abcb496af352dafaa00": {
+     "views": []
+    },
+    "8921953aea4143d88a1bce20cf93dad1": {
+     "views": [
+      {
+       "cell_index": 8
+      }
+     ]
+    },
+    "892421621ee048b9bbb674c5ab9eaf6f": {
+     "views": []
+    },
+    "8937b7050a94485c8b54f6d4f4fab3be": {
+     "views": [
+      {
+       "cell_index": 7
+      }
+     ]
+    },
+    "89595c0ef232498dad1e586058360b23": {
+     "views": []
+    },
+    "8981c47ce4dd4f18afbd95128f8a50ca": {
+     "views": []
+    },
+    "898fee7c63134cb49108f73b66bfc309": {
+     "views": []
+    },
+    "89bbc8de930345e3b10b35dc0ed134af": {
+     "views": []
+    },
+    "89c40f96a8e34e91bf89597232f73601": {
+     "views": []
+    },
+    "89c6ee4376544624ac1e1b03fb796401": {
+     "views": []
+    },
+    "89e732c0396a4d5489e862cb48e56ce6": {
+     "views": []
+    },
+    "8a5d7e78302646fdb29a4388e7cb0dad": {
+     "views": []
+    },
+    "8a66c98e437f4b649f5d7b286214a02b": {
+     "views": []
+    },
+    "8abef175e6494a9c8a5566641d4aad1b": {
+     "views": []
+    },
+    "8b1d3ed6145e4b55b3545c7359e5f8e9": {
+     "views": []
+    },
+    "8b97790e70e3457cb75b2df41aad0ed3": {
+     "views": []
+    },
+    "8c15a0dc19c94b8bbcc698b7b1a7affe": {
+     "views": []
+    },
+    "8c65ba95c48d40c499b816c4144aa27b": {
+     "views": []
+    },
+    "8c68d89a503e427a947a76d5f6e0d9ce": {
+     "views": []
+    },
+    "8cf72ac7bbfb4313a82691bf5993e27d": {
+     "views": []
+    },
+    "8d063edad998438484172ecd085c775f": {
+     "views": []
+    },
+    "8d541d2ea5bc483ab419111a11fd2d70": {
+     "views": []
+    },
+    "8d6592d0ab024b1a93febe4278d70bbd": {
+     "views": []
+    },
+    "8d6b0090cbb7487fb2022e8893dc7d53": {
+     "views": []
+    },
+    "8db9b40f36c84c2fbee481885e3329cd": {
+     "views": []
+    },
+    "8dc806076f684a93825a0e02e9b23b46": {
+     "views": []
+    },
+    "8e83ce6b2b714b0b9fdbcf5a3873ca09": {
+     "views": []
+    },
+    "8ed3863b53124cf18cdad4b499ded973": {
+     "views": []
+    },
+    "8f49b85e60434344a8a3d8d0b5668b4e": {
+     "views": []
+    },
+    "8f526277484047b9be6d733721a6c6c0": {
+     "views": []
+    },
+    "8f82b2f0beec4e2f9ffcb86fbfd9ca24": {
+     "views": []
+    },
+    "900e749111da41cda1d7f97bbe65f214": {
+     "views": []
+    },
+    "9012ce18d8974ea0a35cf9c8714e6e2e": {
+     "views": []
+    },
+    "901c55b78f4f4266bd2daaaa467e8ed0": {
+     "views": []
+    },
+    "907e8732d4fc4dc0b36bbbcc2de2a659": {
+     "views": []
+    },
+    "90b410c7c6be4b5ea049a5b7138bdb3e": {
+     "views": []
+    },
+    "90d9193eaa3e4876888db744504c79f4": {
+     "views": []
+    },
+    "9116696d8a8f437daf80463150c533df": {
+     "views": []
+    },
+    "9178012c65d34ceea2b2ef21f545b288": {
+     "views": []
+    },
+    "926741b579074bf0a67899ef0cd4f67e": {
+     "views": []
+    },
+    "92ac283aaee64a009ce2850ae8277741": {
+     "views": []
+    },
+    "92c64d3f18b64010a269fee8d27ac862": {
+     "views": []
+    },
+    "9334c22730f44e15b2f1558583615c93": {
+     "views": []
+    },
+    "93fc4e6cc7af416f9b6fdde9f7f64705": {
+     "views": []
+    },
+    "940e474d634d4b01b86ddc6f5b635455": {
+     "views": []
+    },
+    "94324ce218f24c7f84377a8dc9d288ae": {
+     "views": []
+    },
+    "9441b13fa31b444a8eef4a8a5890433c": {
+     "views": [
+      {
+       "cell_index": 7
+      }
+     ]
+    },
+    "9470a912a4164709b2b1153d6eb8d5b0": {
+     "views": []
+    },
+    "948a0b5029174f07b2c79f29c2bcbbc3": {
+     "views": []
+    },
+    "948ac45796554db19cb5fe713fb632af": {
+     "views": []
+    },
+    "94b5a2b620dd42bc9b519579e60708a8": {
+     "views": []
+    },
+    "954f9efcf8854ab8a819844bfc65e3ce": {
+     "views": []
+    },
+    "95ce7ca9853e426ea417a851e600b444": {
+     "views": []
+    },
+    "962c2c214de74f2ab8c36c2d9c7cd6b8": {
+     "views": []
+    },
+    "96358f9f0fe74ea295e9412ded569644": {
+     "views": []
+    },
+    "9637c82b171d4d7c853a891d60c6b151": {
+     "views": []
+    },
+    "96c8260dcf654554868379e6c2437090": {
+     "views": []
+    },
+    "9746602008f44807b89b63e9e1bb389b": {
+     "views": []
+    },
+    "97cd02dfd0e94de3bc683d12493ad086": {
+     "views": []
+    },
+    "97fda887e89641b0a113468da80ed6fd": {
+     "views": []
+    },
+    "986086a36c81498c9c262b0643b80e0e": {
+     "views": []
+    },
+    "98ac908bbf3347b3be5bda0937aace84": {
+     "views": []
+    },
+    "99b29beae78048d7b5de0813e9b90b4c": {
+     "views": []
+    },
+    "9a0f666604a843efad8ea0695722967f": {
+     "views": []
+    },
+    "9a38b0dec113498cad2eab9d26e5290a": {
+     "views": []
+    },
+    "9a3c7468cb1e4d32a8052813b8f17ae7": {
+     "views": []
+    },
+    "9a79856a76a0465f8599a07689f46cb6": {
+     "views": []
+    },
+    "9aa589c9bd1a4c2fa4df17fef9c94172": {
+     "views": []
+    },
+    "9ad029d1398a46b7b42e06ddbb3b140b": {
+     "views": []
+    },
+    "9b2588b438964de1b9dc04093a52a7c0": {
+     "views": []
+    },
+    "9b922c19616a436d907f27744815a087": {
+     "views": []
+    },
+    "9c2de036d4a9439387e504e630845fa8": {
+     "views": []
+    },
+    "9c3fc1f4ed7c41c997cb6b564af88930": {
+     "views": []
+    },
+    "9d1c9e49d78746eb973639039f737a21": {
+     "views": []
+    },
+    "9d1f8732b36a42db82c1d3fad366e6ed": {
+     "views": []
+    },
+    "9e059332735d4224aca114f77435e5b7": {
+     "views": []
+    },
+    "9e7abd287e0849d289da926de3cd7354": {
+     "views": []
+    },
+    "9e7e1dc680f1434397544c982b4fa267": {
+     "views": []
+    },
+    "9f19716035e648ce94e7659c5f20b427": {
+     "views": []
+    },
+    "9f2ae827da5843c3af3e0aa5f691c8db": {
+     "views": []
+    },
+    "9f5d0bc4f56e4beeb03857e1027b98b6": {
+     "views": []
+    },
+    "9f7b7da1f5434b6c8764bcfd733a9407": {
+     "views": [
+      {
+       "cell_index": 7
+      }
+     ]
+    },
+    "9fc435d2150840eebeecc430800b22a5": {
+     "views": []
+    },
+    "9fe14dca14fc4c0d898be1f15f666911": {
+     "views": [
+      {
+       "cell_index": 6
+      }
+     ]
+    },
+    "a053f7b2c65b4740a5b81d60616eede4": {
+     "views": []
+    },
+    "a0d79a00c2534ff18e76c5ed64a7b801": {
+     "views": []
+    },
+    "a11b2dc3131d450a8f7e23eb09b19cef": {
+     "views": []
+    },
+    "a16164194915483b9aac478ca7709cd1": {
+     "views": []
+    },
+    "a1793aa9ecd94c44acae8f7e2ed4b7d1": {
+     "views": []
+    },
+    "a18bac2336cd40c2b79af9e935f3b93f": {
+     "views": []
+    },
+    "a1e88babd8454804a628cd63e1af81dc": {
+     "views": []
+    },
+    "a1fb1ef7e91d4f27b2d26a823052ca78": {
+     "views": []
+    },
+    "a2286455335d40a4b5110428f4f92d90": {
+     "views": []
+    },
+    "a230bc2d286e4cf5af702329aa56c1bb": {
+     "views": []
+    },
+    "a2c786b3f3e248e18ce6ef02ece6df3e": {
+     "views": []
+    },
+    "a2dc4239e5e145f497331bb33a7dd666": {
+     "views": []
+    },
+    "a3523d46e3bf489eb88ee81a3d5c092f": {
+     "views": []
+    },
+    "a36f13636c9d46c3a3184c781790cb2f": {
+     "views": []
+    },
+    "a37677f6a20a4b7180043464b2e4fade": {
+     "views": []
+    },
+    "a3c0e7f190f24936baaaa6c746dddffb": {
+     "views": []
+    },
+    "a49aa9603d934be1942cdb8289399d5e": {
+     "views": []
+    },
+    "a4c2539ec4e44f21bccd842a77e500ef": {
+     "views": []
+    },
+    "a4d0e03acc934ef2a6801c19cee9385c": {
+     "views": []
+    },
+    "a5d299cce9034ccf8beb04b9f0cdd953": {
+     "views": [
+      {
+       "cell_index": 9
+      }
+     ]
+    },
+    "a720ec9884e34558b8b467cbc0fc553d": {
+     "views": []
+    },
+    "a76fb0b53ce64204a8285346957bec05": {
+     "views": []
+    },
+    "a7e75908fc944a46a14867197156b28e": {
+     "views": []
+    },
+    "a7f9c19ee6ce4eaa9dc48eb89144c856": {
+     "views": []
+    },
+    "a7fab3707f504531af76c48843da5081": {
+     "views": []
+    },
+    "a824b8cb4c494331991213dda61ef22a": {
+     "views": []
+    },
+    "a88f14b8bdbe4566b199d32578a52674": {
+     "views": []
+    },
+    "a9b1d24d49ed4fcfb0e67416257a57e7": {
+     "views": []
+    },
+    "a9e57a571b25471f8af3edc03c06771a": {
+     "views": []
+    },
+    "aa02337023ca4b0bae5edef0c05614b9": {
+     "views": []
+    },
+    "aa13930b1ec34c38b3f9473b70d17062": {
+     "views": []
+    },
+    "aa24701f95164775b211129f2108ef00": {
+     "views": []
+    },
+    "aa92cac7052446dab5c902c5bfbe7b5b": {
+     "views": []
+    },
+    "aab57f0fbc7940d68c7850b23eb8ad52": {
+     "views": []
+    },
+    "aae355de544d48a688cfed6e21a0c62d": {
+     "views": []
+    },
+    "ab901ce51d5946299d4689fc16268202": {
+     "views": []
+    },
+    "abae7a4034084d42ab80ddd94128ec5e": {
+     "views": []
+    },
+    "abdd5505e47e46cb817f9b69d4023c38": {
+     "views": [
+      {
+       "cell_index": 7
+      }
+     ]
+    },
+    "ac63ca3c968b4ac3a46e8c4a3d739a29": {
+     "views": []
+    },
+    "ac903264357d41b7b60803612ed023f4": {
+     "views": []
+    },
+    "ac9ab3f133cf458eaf5dcbd04905e840": {
+     "views": []
+    },
+    "ac9bf9c7eefc49668f751afc2c5aa465": {
+     "views": []
+    },
+    "acde8f70945946058988b4bdb95535e4": {
+     "views": []
+    },
+    "ad247c76746e448b8a1f65e009d872de": {
+     "views": []
+    },
+    "ad532442f22b4836840342d596b94839": {
+     "views": []
+    },
+    "ada3f078f3714afa88663be598a0552c": {
+     "views": []
+    },
+    "ade1e993fa434e24b499e7a36fa82e72": {
+     "views": []
+    },
+    "adf65b4f6e004543b8a593beea70edec": {
+     "views": []
+    },
+    "ae11f3a1612e4b54ae398df66911f563": {
+     "views": []
+    },
+    "ae48ad8c1d6e48418b7dae239be532ae": {
+     "views": []
+    },
+    "af4a43c2031d412695750fcdb6c2666a": {
+     "views": []
+    },
+    "b09f318fae5146cfa46deaa7b9e9bd38": {
+     "views": []
+    },
+    "b0a5266dedc84151888f519e374efbaa": {
+     "views": []
+    },
+    "b14eaec752e8485f8ce174b6e24dfbc9": {
+     "views": []
+    },
+    "b18617cebf8147f98bd35f47829fbcae": {
+     "views": []
+    },
+    "b1af57926a3c4d388ee58bb77b815637": {
+     "views": []
+    },
+    "b1bef2b1cb2d4683a14a7b5859f53a4c": {
+     "views": []
+    },
+    "b1c686c8791b42a7a9d796647ecb0d10": {
+     "views": []
+    },
+    "b25cc3b8126944dab7b95c3773919f1a": {
+     "views": []
+    },
+    "b2838e2a54f744fbacd0f7caed876f32": {
+     "views": []
+    },
+    "b325ef9f64e443169aecbb25e76bdba2": {
+     "views": []
+    },
+    "b3967637f8dc46b6adddc85aabf4ef80": {
+     "views": []
+    },
+    "b3de0c48b9bd41739f388dd0923164bd": {
+     "views": []
+    },
+    "b414f3561e084641b931fff1fefeba50": {
+     "views": []
+    },
+    "b419feb4b950432196e5eb87d437e4f9": {
+     "views": [
+      {
+       "cell_index": 9
+      }
+     ]
+    },
+    "b43eef81e4e3432e9a56babfacd8e3d4": {
+     "views": []
+    },
+    "b457df6535b14ed7b438645d52bbf6bc": {
+     "views": []
+    },
+    "b49121dc30de4effb1444ad6f82ac93a": {
+     "views": []
+    },
+    "b4c14bc360964cd0825b27a8f4505f9c": {
+     "views": []
+    },
+    "b4d2cf36fc464cb08b56fcce898bb768": {
+     "views": []
+    },
+    "b55c4cb899ae4f0fa779ca90f8af4177": {
+     "views": []
+    },
+    "b55f66647cc343d8a6658badd61c32b9": {
+     "views": []
+    },
+    "b5a06fcc8a2348dea09b9c9529b6e987": {
+     "views": []
+    },
+    "b5b39c54a5574814a86b4d9d9106efed": {
+     "views": []
+    },
+    "b5ce4781be524ee2bd7268cc989a205f": {
+     "views": []
+    },
+    "b5e02501a86540c3b2b462562343c797": {
+     "views": [
+      {
+       "cell_index": 9
+      }
+     ]
+    },
+    "b60ddc4aada444c2933b0e9f6c5745f8": {
+     "views": []
+    },
+    "b60e48d7e80b4c5e92eb55eec0bc5485": {
+     "views": []
+    },
+    "b6830dd5debb44869325da307a839a74": {
+     "views": []
+    },
+    "b69faa3f868f4a7191f02bf773040599": {
+     "views": []
+    },
+    "b6a74f88fb7f4c0f8fe042093e2bc426": {
+     "views": []
+    },
+    "b7016cc1fc16433ba0b933013b9ebc2a": {
+     "views": []
+    },
+    "b765e9c6ff8f41249f64b47dcf546656": {
+     "views": []
+    },
+    "b77e8b5c881a49dc8e77fca1c464746c": {
+     "views": []
+    },
+    "b858756d359a4cc3be8b60c74cbe4423": {
+     "views": []
+    },
+    "b872953c70924a7382c683fe061352e0": {
+     "views": []
+    },
+    "b888ff26912a46ac9c1565f1d220a479": {
+     "views": []
+    },
+    "b8c8e11ab6d74872a8005ceef365f9d8": {
+     "views": []
+    },
+    "b951d56e420044f18a3f81ee523078c1": {
+     "views": []
+    },
+    "b959c7421d3c4ee688b79a938149352e": {
+     "views": []
+    },
+    "ba788ba9babe4b4296e46f03339e04a2": {
+     "views": []
+    },
+    "bae52b5af8a14299a2b2aceaa0381d2e": {
+     "views": []
+    },
+    "baf36606ddb54bab9636493a3820b2d8": {
+     "views": []
+    },
+    "bafe7d4522f641c081fb54e525ddbbba": {
+     "views": []
+    },
+    "bb0b2d0e82884145afa8d433409b8272": {
+     "views": []
+    },
+    "bb1ce244ff874dc9a0a6911b0a26da5a": {
+     "views": [
+      {
+       "cell_index": 7
+      }
+     ]
+    },
+    "bc65c1b14f4d4b7683c0ce33af43f51a": {
+     "views": []
+    },
+    "bcb7d1154db24719a15be62d5b91ded0": {
+     "views": []
+    },
+    "bcee5f4a9e374422833a52589b498d79": {
+     "views": []
+    },
+    "bcf6115b9dcb43de94dc351bf294731f": {
+     "views": []
+    },
+    "bd5d7d428a654b5186659f21f5505f27": {
+     "views": []
+    },
+    "bd95a4554eed46daa633f7ca6b908181": {
+     "views": []
+    },
+    "bdb773058d6541f99aeaf10212ac97bf": {
+     "views": []
+    },
+    "bdcaeeb966fc4c98bfe54d11fdb294a5": {
+     "views": []
+    },
+    "bdf34686381b44f19f94dcebb6989199": {
+     "views": []
+    },
+    "be3874742c114139b1eca36dede20ccb": {
+     "views": []
+    },
+    "be4d23c4c52a47e398abb6e4385f3285": {
+     "views": []
+    },
+    "bec3ba4e985c490999462724a6d22f9d": {
+     "views": []
+    },
+    "bf167e26d7ee4b4fa9e69742535c49dc": {
+     "views": []
+    },
+    "bf31ab9283364f5386c096bdd0bb168e": {
+     "views": []
+    },
+    "c00d02e7ca6c488f8a9a4195e4c7c6c5": {
+     "views": []
+    },
+    "c0185ea5ec3f41839c1983c86e7b5e26": {
+     "views": []
+    },
+    "c0973876f4e54bc9b846bdb6dbaa1d5a": {
+     "views": []
+    },
+    "c356a72f3f1143fb85637e46cdb1fe14": {
+     "views": []
+    },
+    "c360568d7f0e49f09ca01612fb2c8a9a": {
+     "views": []
+    },
+    "c39241af95ca44e3ba9d7414c2c37163": {
+     "views": []
+    },
+    "c46f538d823748c68b55be1dcd253b5e": {
+     "views": []
+    },
+    "c46f6aeeb78f463b85000e3f43694c5c": {
+     "views": []
+    },
+    "c47d3e2db45d433dbaa68bd5b88e2a5a": {
+     "views": []
+    },
+    "c4e40220e2834198b3a2e64816513474": {
+     "views": []
+    },
+    "c4f171a5356f4dc383de992104736213": {
+     "views": []
+    },
+    "c56e6b2bd13146c0b362ee8f2c5af051": {
+     "views": []
+    },
+    "c57239474dfe49719e16c6b0168241df": {
+     "views": []
+    },
+    "c579fdcfb7c5480791c50b41787a503c": {
+     "views": []
+    },
+    "c57d33342cb74a2abeada973be1d68c6": {
+     "views": []
+    },
+    "c586be274a8d4b569b106edfe5849d35": {
+     "views": []
+    },
+    "c58ee670a44848a5836a8a54287b70d4": {
+     "views": []
+    },
+    "c5994c6a71af4201b3cf2ee9a881c6e8": {
+     "views": []
+    },
+    "c59aeea30c1c485dba3042e5a661cea8": {
+     "views": []
+    },
+    "c62b066aad2748b599d029808d23cbd9": {
+     "views": []
+    },
+    "c66c4721762b46fda59a7a4fb9ee0d5d": {
+     "views": [
+      {
+       "cell_index": 6
+      }
+     ]
+    },
+    "c66decbd305e4d01aabbfdd57cd5e6b6": {
+     "views": []
+    },
+    "c698f34c19924c518df5367f99642f8c": {
+     "views": []
+    },
+    "c702eb403fe4475e8bd7e70b911e9eb1": {
+     "views": []
+    },
+    "c7161ea262104adc807403c7c2e4e0b3": {
+     "views": []
+    },
+    "c75802467e524ad3b4818183f407d095": {
+     "views": []
+    },
+    "c79879386e704b2084b8e7a22f2c270b": {
+     "views": []
+    },
+    "c7a2e7cbb3504343a85a46bbf7f00b55": {
+     "views": []
+    },
+    "c7b055305f4f48179f5f7240cf47ec3c": {
+     "views": []
+    },
+    "c7f00b3d7ec142b89ec38736fbded88a": {
+     "views": []
+    },
+    "c87f387aa28c4a06a1f7f568f8dc2020": {
+     "views": []
+    },
+    "c91be87955154dfc933880c6e93efe38": {
+     "views": []
+    },
+    "c97107a32f2c46dfb8fd931c8a7a2df3": {
+     "views": []
+    },
+    "c9955c0b89a042feac5f0fb0b74de2a3": {
+     "views": []
+    },
+    "c9f58327de8f4f8a86e4c2b9bbf3b484": {
+     "views": []
+    },
+    "c9f85add27384fa1bf01d3d75fa7b755": {
+     "views": []
+    },
+    "ca0529c0c20b42d4bc9cd689186c41d9": {
+     "views": []
+    },
+    "ca278e2c40b043ae93a734cb39252af4": {
+     "views": []
+    },
+    "ca634c8e99bc4bed9de1591e38649330": {
+     "views": []
+    },
+    "cac64fb28c3543c899f0dbb1e57003cc": {
+     "views": []
+    },
+    "cb0dce609b8e48dc97d0df311bbe66b1": {
+     "views": []
+    },
+    "cbdf279f0f4845a3a44c3ca9f815048e": {
+     "views": []
+    },
+    "cc1b8837727c414b9ff377244f0a8432": {
+     "views": []
+    },
+    "cc4a26a1062c42ad9ce50651d0a075bd": {
+     "views": []
+    },
+    "cc7184bb1161489a959c6a925ab38bf2": {
+     "views": []
+    },
+    "cd398682e7e84f18bc73dcccbc26abf8": {
+     "views": []
+    },
+    "cd40538aa4a94525b0dc870a0a007fbc": {
+     "views": []
+    },
+    "cd4d9d556d004977adf8f14b743586d0": {
+     "views": []
+    },
+    "cd70ac07c06b4ee582ec810454fad0b5": {
+     "views": []
+    },
+    "cd75861add0e4867b566bc4b145904b5": {
+     "views": []
+    },
+    "cdc6eec5e64c4305b5061a58296fbb45": {
+     "views": []
+    },
+    "ce0570f6756641d99020faffb414b125": {
+     "views": []
+    },
+    "ce06cc8cef1048c7a80c03c326447fcd": {
+     "views": []
+    },
+    "ce9935f4298140a38cd552889fbde385": {
+     "views": []
+    },
+    "cec34b088ef6448fba44c92bb8c3d1fa": {
+     "views": []
+    },
+    "ced1f97d79624a558a7bbe744a2e6ce1": {
+     "views": []
+    },
+    "ced8c54d1e0f4aa1a70129f76250422d": {
+     "views": []
+    },
+    "cf10a4af7ea340cdbe7467f0d6b7c51d": {
+     "views": []
+    },
+    "cf4b83aaed1f4e53982b749da997b82b": {
+     "views": []
+    },
+    "cf8ad1b1bfb149cdafd8e81131d2741b": {
+     "views": []
+    },
+    "d01e88688e2e40b0997c2e546829d3b1": {
+     "views": []
+    },
+    "d0351ea7f38645dd8aae04ecda3b671b": {
+     "views": []
+    },
+    "d0b998cd0b424b2db52d79d6064b5e23": {
+     "views": []
+    },
+    "d0e6389cedd942028c4f8707f06af0a2": {
+     "views": []
+    },
+    "d1c05331544e42ebbaecc68e341217cd": {
+     "views": []
+    },
+    "d1c7c2dc811548a2a67bd10b94b59a58": {
+     "views": []
+    },
+    "d1db0bfcdfae4c6b830be60793c555f9": {
+     "views": []
+    },
+    "d1e87b70ae5b48108c0f91e0149875e2": {
+     "views": []
+    },
+    "d219f971eee94508b302dc6528c8c48c": {
+     "views": []
+    },
+    "d22e7343ff614071a3227cc8ee4204ee": {
+     "views": []
+    },
+    "d23c80deffee4a0888bf0a360bd864ec": {
+     "views": []
+    },
+    "d264dbb0d45d4934b0acf773b2c5880f": {
+     "views": []
+    },
+    "d299f31ec9cc4bf899a79f8a368d37bc": {
+     "views": []
+    },
+    "d2f66ead992045dcb9328b9e9c64afeb": {
+     "views": []
+    },
+    "d3395ca8309c4490a0832ec40e0268e9": {
+     "views": []
+    },
+    "d3c3a52f70794fa1800b221d4618fc34": {
+     "views": []
+    },
+    "d3ec0b6a91074a8f9534f42782f3f9b4": {
+     "views": []
+    },
+    "d49647fa6d4347f688eab255ea93c548": {
+     "views": []
+    },
+    "d4a0a9ae9a5b4266bdee8ea1d480ee07": {
+     "views": []
+    },
+    "d4b553b217d2475290132253ba224365": {
+     "views": []
+    },
+    "d4be3080e3c54ec6968d14f7ac52328f": {
+     "views": []
+    },
+    "d4c0438810ef445681685369d2a88b18": {
+     "views": []
+    },
+    "d4d2f473433248aa8bac61d9c5a01c95": {
+     "views": []
+    },
+    "d51180e4fe604b8f8be4e32dc56567aa": {
+     "views": []
+    },
+    "d517e94b7844437c88b846d22fa3b8c9": {
+     "views": []
+    },
+    "d6a2fcb694f44fb8b56c0ff14fef3ba9": {
+     "views": []
+    },
+    "d711b4d90ba8470eb6ece1f876db7610": {
+     "views": []
+    },
+    "d71e634587c44d60a902e910e07a87dc": {
+     "views": []
+    },
+    "d7520d4a3b6c425eb9793a2a985d3959": {
+     "views": []
+    },
+    "d7a1e6ed084b475a99642847089a7b2c": {
+     "views": []
+    },
+    "d7b01a634b004fad808456e21df2259f": {
+     "views": []
+    },
+    "d920b514fad64db1be4f07cc4b3d191c": {
+     "views": []
+    },
+    "d944843ad4ba44698baac50b3f08538c": {
+     "views": [
+      {
+       "cell_index": 7
+      }
+     ]
+    },
+    "d9580331624a41088a94d33ed72e9cae": {
+     "views": []
+    },
+    "d9595c7286ca419e9109c645cb5dad68": {
+     "views": []
+    },
+    "d95f93b719214efdb9008791f7c09cd7": {
+     "views": []
+    },
+    "da06f07731a049e6849ab6d6ac974d96": {
+     "views": []
+    },
+    "da3660063c0f43c09434a1530b17ceb1": {
+     "views": []
+    },
+    "da576e663f7948debc96af7bf6d3d397": {
+     "views": []
+    },
+    "da838430996649ba88cc162f3cbf0014": {
+     "views": []
+    },
+    "dae351dd5ee04956a3dac330f388bb5e": {
+     "views": []
+    },
+    "db120a66d3c34e4f9c376b30bf45ccd1": {
+     "views": []
+    },
+    "db169084d6764be1a4def66575c2271c": {
+     "views": []
+    },
+    "db33c8163ad14275bf4f7d17547684a2": {
+     "views": []
+    },
+    "db725316d1364e58ba7562d20f05f896": {
+     "views": []
+    },
+    "dbc4a7e05f8f490c966cb340340acb80": {
+     "views": []
+    },
+    "dc17dd855dad40fa9978a3eca96d2ff3": {
+     "views": []
+    },
+    "dc8381d216d846ab8039ec360aa34e08": {
+     "views": []
+    },
+    "dccaea82e07243479cde68000aacd646": {
+     "views": []
+    },
+    "dd197668d5424dea98b5862d0b3ec621": {
+     "views": []
+    },
+    "dd3654dd541f4eee8cea5d211c9bc2b0": {
+     "views": []
+    },
+    "dd80b840c8164669925174ea3eb03f91": {
+     "views": [
+      {
+       "cell_index": 6
+      }
+     ]
+    },
+    "dde09a48f3a34f22a3f3a281d296b321": {
+     "views": []
+    },
+    "de29029974a74d0787c97c0c61d0df7c": {
+     "views": []
+    },
+    "deaa3f51449a4c70955b2eb84b8c7a7f": {
+     "views": []
+    },
+    "dede5c4c62214842982e26e857165e5b": {
+     "views": []
+    },
+    "df4b0d2966c8472a81017a909efe9951": {
+     "views": []
+    },
+    "dfd334cac9bc419dae464507f5343c59": {
+     "views": []
+    },
+    "dffadb3967684c05a8546749e805f78e": {
+     "views": []
+    },
+    "e05855c5c6db4682b5cb664cbc5f0afb": {
+     "views": []
+    },
+    "e07f135062ff48deb7be87e105a0ac91": {
+     "views": []
+    },
+    "e1171fd182864aaeaaaff0b431def129": {
+     "views": []
+    },
+    "e1ba8ab6a86e445e9c9ceb29f3004237": {
+     "views": []
+    },
+    "e1f964595bcd4b6c834e936900086d1f": {
+     "views": []
+    },
+    "e314e75b142545c3ba5cdb5887398a24": {
+     "views": [
+      {
+       "cell_index": 7
+      }
+     ]
+    },
+    "e3d0de33870e41f1b0a98a74f4fb81ae": {
+     "views": []
+    },
+    "e54a0528f44b47e789a84689079e6d43": {
+     "views": [
+      {
+       "cell_index": 8
+      }
+     ]
+    },
+    "e5ddac556f704ea7bf2c1c809d11615e": {
+     "views": []
+    },
+    "e655322819894c5cbd1ec79cacb9f574": {
+     "views": []
+    },
+    "e67f0d93cb2f4cc2b3bba06151d83853": {
+     "views": []
+    },
+    "e6ad6e2ca72040ee953fa90f6ff4bb31": {
+     "views": []
+    },
+    "e75b9fe5b2844c49a5eeffaedb1a47cc": {
+     "views": []
+    },
+    "e7f543df60594fc5bfbc4d6be39ac278": {
+     "views": []
+    },
+    "e83893a2bec040cbb91743d747f3b340": {
+     "views": []
+    },
+    "e83914fad92e4fd9ae16271496eee887": {
+     "views": []
+    },
+    "e87b1a64edeb438f84ab18e938410d22": {
+     "views": []
+    },
+    "e934de3e52284897b1e0157a6724fbad": {
+     "views": []
+    },
+    "e9ba80e3a8ab4b589ba88af4fd2c253e": {
+     "views": []
+    },
+    "e9dc1f54bb774da6b22ee35b583264ff": {
+     "views": []
+    },
+    "ea188a9c90684ae0863b0e53c0ef515e": {
+     "views": []
+    },
+    "eab277364d83400b83c50244c3a8a865": {
+     "views": []
+    },
+    "eacc708b6cb64a989c84d2ac96b5bb67": {
+     "views": []
+    },
+    "eae11535f0f14d7dae1e39da941e2e0c": {
+     "views": []
+    },
+    "ec28a4a3850d40e397d557eef59ab191": {
+     "views": []
+    },
+    "ed093bb0589e4786b4e533212c328154": {
+     "views": []
+    },
+    "ed242e66714c40659045ad47203bd0ad": {
+     "views": []
+    },
+    "ed4d1b7480e04573b79266b95672e7fa": {
+     "views": []
+    },
+    "ed91acdc4ad34d54a1359fd81faf2c8d": {
+     "views": []
+    },
+    "ede6cdb717b24b7a8e6234235659cf5b": {
+     "views": []
+    },
+    "ee06c800d2a246429625776e7492c060": {
+     "views": []
+    },
+    "ee88baad1101470b85f30458e7eb30d5": {
+     "views": []
+    },
+    "eec2768157514b81ba230c16e20b01c4": {
+     "views": []
+    },
+    "ef14b888355b4692b1b15ef3413be313": {
+     "views": []
+    },
+    "ef29aca411b54bcdbb6f8d69e8157bfa": {
+     "views": []
+    },
+    "efbd7aeb967b47d6b83d4a80a47a791f": {
+     "views": []
+    },
+    "f031a4a0f2694c3ea975624fd4df4575": {
+     "views": [
+      {
+       "cell_index": 9
+      }
+     ]
+    },
+    "f0401509eea141e0978136d747501a34": {
+     "views": []
+    },
+    "f07dedf818ac4379ba2133d1b6145b70": {
+     "views": []
+    },
+    "f0a58e647bb549d782ec277708ba5bad": {
+     "views": []
+    },
+    "f0d9074ab6ea4981a015977c942a66d6": {
+     "views": []
+    },
+    "f0fb8ebaabeb4f279c90872213a1ad82": {
+     "views": []
+    },
+    "f12c9e4c234d47a98b89aa0ef03a2099": {
+     "views": []
+    },
+    "f1730462381a4c13a0c8a11cd7fa858c": {
+     "views": []
+    },
+    "f1e1b60c5c7646deb69883eae1c9bafd": {
+     "views": []
+    },
+    "f1f33afeda84471bb6ad780333d02f91": {
+     "views": []
+    },
+    "f21881e9d2654f4a835064c30a0598b2": {
+     "views": []
+    },
+    "f22d011d366945e7b77ae16ed8039986": {
+     "views": []
+    },
+    "f275b965d50143c0afce2abdbe97f529": {
+     "views": []
+    },
+    "f28e69532bd54a43954fd7bd870d7881": {
+     "views": []
+    },
+    "f296e245f7c649e782d621fa1fb51a13": {
+     "views": []
+    },
+    "f335b600e75f4205a84816c5b1075b38": {
+     "views": []
+    },
+    "f371eb0656394a8985b9ff8e354d5d33": {
+     "views": []
+    },
+    "f38793ef9f4a42d7bc6eb0f419247f14": {
+     "views": []
+    },
+    "f43acdd425d944d697deff1fac3b1f32": {
+     "views": []
+    },
+    "f48e5a24a7ca43dc8f03c8361121f1ce": {
+     "views": [
+      {
+       "cell_index": 7
+      }
+     ]
+    },
+    "f4ad744de54d4e5c823e9b92fc1e4b95": {
+     "views": []
+    },
+    "f4d363e1ec1249c29b7f4bbf11976d63": {
+     "views": []
+    },
+    "f506413ae67e4addb700ab3a395b5025": {
+     "views": [
+      {
+       "cell_index": 4
+      }
+     ]
+    },
+    "f5e328f5ae824595905c82629f599aed": {
+     "views": []
+    },
+    "f727e56360a547e5bbd1d5c7815da0b9": {
+     "views": [
+      {
+       "cell_index": 9
+      }
+     ]
+    },
+    "f72e311da14d4047b97fa639ee1a94b3": {
+     "views": []
+    },
+    "f7779af276714844ac041e81e901c748": {
+     "views": []
+    },
+    "f7ca4d89786a4f05976d1c1656e111cf": {
+     "views": []
+    },
+    "f7e3dd9ea689466d90776126f1d751c6": {
+     "views": []
+    },
+    "f86439fc327b44d2ac115ef369927738": {
+     "views": []
+    },
+    "f8b14f3457fc41cf92e0cd803d54d6d2": {
+     "views": []
+    },
+    "f8fa5197610c4bf794e7647f7368b7c7": {
+     "views": []
+    },
+    "f934390fec76432780cb382439cca710": {
+     "views": []
+    },
+    "f99b94b724d64cf5a7d16888b8ec79dd": {
+     "views": []
+    },
+    "f9c3f1213909430297a0099664ba683c": {
+     "views": []
+    },
+    "f9f4159b007240dda6cb6798d783f296": {
+     "views": []
+    },
+    "fa218fbd583443bb9599d4d149357e88": {
+     "views": []
+    },
+    "fa304b80767f4eb487ab2848af2c1d7d": {
+     "views": []
+    },
+    "fab54549175543f898304c61edb9289e": {
+     "views": []
+    },
+    "fae54b5792304a72ae5b852e77e73d60": {
+     "views": []
+    },
+    "fae696cea5b643d3b5025187b906a892": {
+     "views": []
+    },
+    "fb0c8d405c4b43529b3dea73b3f87e30": {
+     "views": []
+    },
+    "fc9c2ed29bb24823808f0160a09f4d1d": {
+     "views": []
+    },
+    "fd212f49562d41f390de322300db4115": {
+     "views": []
+    },
+    "fde68a85876a42128e62d276aa3be7f8": {
+     "views": []
+    },
+    "fdea5414b3444f5fa6060f9974812820": {
+     "views": []
+    },
+    "fdfed123f00142f3bfac011850f086e5": {
+     "views": []
+    },
+    "fe22751e825f41598e7923f5d6444c58": {
+     "views": []
+    },
+    "fe72daed230d48bab294c53999c1276b": {
+     "views": []
+    },
+    "ff136b8bc1bc41a4b980224bd5e98d2f": {
+     "views": []
+    },
+    "ff30567099ac47d1b86ff211cc75e275": {
+     "views": []
+    },
+    "ff5cfa4e02184798843736d59232fac4": {
+     "views": []
+    },
+    "ff71f112c19440b4b02d740af63401b9": {
+     "views": []
+    },
+    "ff970f5319964ff49bd837d7aa7ddee1": {
+     "views": []
+    },
+    "ffcf5f9dd0234042bc001a7dbd86e02c": {
+     "views": []
+    },
+    "ffd4081a872d4afeb6a41334bc295817": {
+     "views": []
+    }
+   },
+   "version": "1.1.2"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 0
+}
diff --git a/pysal/contrib/viz/geotable_plot.ipynb b/pysal/contrib/viz/geotable_plot.ipynb
new file mode 100644
index 0000000..ddebed9
--- /dev/null
+++ b/pysal/contrib/viz/geotable_plot.ipynb
@@ -0,0 +1,3400 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Plotting from geotables"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [],
+   "source": [
+    "%matplotlib inline"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {
+    "collapsed": false,
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "import pysal as ps\n",
+    "import numpy as np\n",
+    "from pysal.contrib import pdio\n",
+    "from pysal.contrib.viz import mapping as maps\n",
+    "import matplotlib.pyplot as plt\n",
+    "import seaborn as sns\n",
+    "import pandas as pd"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['arcgis',\n",
+       " 'wmat',\n",
+       " 'mexico',\n",
+       " 'stl',\n",
+       " 'street_net_pts',\n",
+       " 'geodanet',\n",
+       " 'us_income',\n",
+       " 'snow_maps',\n",
+       " 'sids2',\n",
+       " 'baltim',\n",
+       " 'nat',\n",
+       " 'taz',\n",
+       " 'Line',\n",
+       " 'juvenile',\n",
+       " 'virginia',\n",
+       " 'newHaven',\n",
+       " 'book',\n",
+       " '10740',\n",
+       " 'calemp',\n",
+       " 'columbus',\n",
+       " 'Point',\n",
+       " 'networks',\n",
+       " 'Polygon_Holes',\n",
+       " 'chicago',\n",
+       " 'south',\n",
+       " 'Polygon',\n",
+       " 'desmith',\n",
+       " 'burkitt',\n",
+       " 'sacramento2']"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ps.examples.available()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "<class 'pandas.core.frame.DataFrame'>\n",
+      "RangeIndex: 49 entries, 0 to 48\n",
+      "Data columns (total 21 columns):\n",
+      "AREA          49 non-null float64\n",
+      "PERIMETER     49 non-null float64\n",
+      "COLUMBUS_     49 non-null int64\n",
+      "COLUMBUS_I    49 non-null int64\n",
+      "POLYID        49 non-null int64\n",
+      "NEIG          49 non-null int64\n",
+      "HOVAL         49 non-null float64\n",
+      "INC           49 non-null float64\n",
+      "CRIME         49 non-null float64\n",
+      "OPEN          49 non-null float64\n",
+      "PLUMB         49 non-null float64\n",
+      "DISCBD        49 non-null float64\n",
+      "X             49 non-null float64\n",
+      "Y             49 non-null float64\n",
+      "NSA           49 non-null float64\n",
+      "NSB           49 non-null float64\n",
+      "EW            49 non-null float64\n",
+      "CP            49 non-null float64\n",
+      "THOUS         49 non-null float64\n",
+      "NEIGNO        49 non-null float64\n",
+      "geometry      49 non-null object\n",
+      "dtypes: float64(16), int64(4), object(1)\n",
+      "memory usage: 8.1+ KB\n"
+     ]
+    }
+   ],
+   "source": [
+    "db = pdio.read_files(ps.examples.get_path('columbus.shp'))\n",
+    "db.info()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## `matplotlib` interface"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Basic functionality\n",
+    "\n",
+    "The easiest way to obtain a plot of the geometries in a `geotable` is to simply pass the table:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAvEAAALlCAYAAABNf7lsAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAAPYQAAD2EBqD+naQAAIABJREFUeJzs3WlsHPd9//HPzOzJ+xYpiqJE0pQoybYsRZYcW4ft2LkP\n5HATB01RpEGCAkWfNAUK5HmBPGiBJECBtkHq9u/GMOrWZxM7lyxZh21Z92HJOiyJOilKPPc+/g9U\nbkSJx5Lc2dmZfb+AhSju7syX1Ir8zG+/v9/PyGazWQEAAABwDdPpAgAAAADMDSEeAAAAcBlCPAAA\nAOAyhHgAAADAZQjxAAAAgMsQ4gEAAACXIcQDAAAALkOIBwAAAFyGEA8AAAC4DCEeAAAAcBlCPAAA\nAOAyhHgAAADAZQjxAAAAgMsQ4gEAAACXIcQDAAAALkOIBwAAAFyGEA8AAAC4DCEeAAAAcBlCPAAA\nAOAy [...]
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7fc688d8d810>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "maps.geoplot(db)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "If you want a choropleth, you can also add the variable you want to encode:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAvEAAALlCAYAAABNf7lsAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAAPYQAAD2EBqD+naQAAIABJREFUeJzs3Xl4ZPdd5/vP75xTm0q71C21eu+2u9t2u922k9ixk0BC\nErIAIQmEARJmCMsAMyyTwDAT8lzu5XIh3AzPwDOEmTzDBQJhSUhCApg4cUI228GO4z1ee1/UrW6p\ntauWs/zuH1K3e9FSkqrq1Kl6v/JUpC6VzvmqrS596qfv+f6MtdYKAAAAQGI4cRcAAAAAYHUI8QAA\nAEDCEOIBAACAhCHEAwAAAAlDiAcAAAAShhAPAAAAJAwhHgAAAEgYQjwAAACQMIR4AAAAIGEI8QAA\nAEDCEOIBAACAhCHEAwAAAAlDiAcAAAAShhAPAAAAJAwhHgAAAEgYQjwAAACQMIR4AAAAIGEI8QAA\nAEDC [...]
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7fc6865aaf50>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "maps.geoplot(db, 'HOVAL')"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "If you want a specific palette from [Color Brewer](http://colorbrewer2.org), just pass the string with the name:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAvEAAALlCAYAAABNf7lsAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAAPYQAAD2EBqD+naQAAIABJREFUeJzs3Xl0ZOld5vnnvffGJoX2TEm571XlWl3lpcq7zdLY0OyY\nhoZhgJ5mtp4e2scsPdMD9GnOoU/PcGb6ND000A1tsxnwYGMWG2OMAS/l8lK7y1W5ZyozlVKmtlDs\n977v/BHKrFykzJAU273x/ZyjlDIUce+r7cZz3/i9v2ucc04AAAAAYsPr9gAAAAAAbA4hHgAAAIgZ\nQjwAAAAQM4R4AAAAIGYI8QAAAEDMEOIBAACAmCHEAwAAADFDiAcAAABihhAPAAAAxAwhHgAAAIgZ\nQjwAAAAQM4R4AAAAIGYI8QAAAEDMEOIBAACAmCHEAwAAADFDiAcAAABihhAPAAAAxAwhHgAAAIgZ\nQjwA [...]
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7fc68575ebd0>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "maps.geoplot(db, 'HOVAL', palette='Blues')"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "By default, we use 5 groups, but you can get a different number modifying `k`:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAvEAAALlCAYAAABNf7lsAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAAPYQAAD2EBqD+naQAAIABJREFUeJzs3Xl8JOld5/nvExF5KnVLJdXVdXVXVVdXX26722fb2OsL\nMOADwzCDMTBmXzDAi/GyA+wB7K5ndhcDy7mDgdlhwIAxxoa2wTbQtrHbdlf7aNt9d92n7tKZd0Q8\n+4dU5apqSZWSMjMyMj/vl2VlSZkRP6lTEd988hfPY6y1VgAAAABiw4m6AAAAAAAbQ4gHAAAAYoYQ\nDwAAAMQMIR4AAACIGUI8AAAAEDOEeAAAACBmCPEAAABAzBDiAQAAgJghxAMAAAAxQ4gHAAAAYoYQ\nDwAAAMQMIR4AAACIGUI8AAAAEDOEeAAAACBmCPEAAABAzBDiAQAAgJghxAMAAAAxQ4gHAAAAYoYQ\nDwAA [...]
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7fc688d8d5d0>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "maps.geoplot(db, 'HOVAL', palette='Blues', k=9)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "For every Color Brewer palette, you can also call its reverse by specifying `_r` at the end of the name:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAvEAAALlCAYAAABNf7lsAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAAPYQAAD2EBqD+naQAAIABJREFUeJzs3WlwJOl95/ffk5mVdeJGA2igu6fPuWd4i6KG1EGRokiK\n0tor0YdWqw1RVijsFxvesGIj/MLvvbGx63A4pNhwhLwrhbWy1wpZodW1XkvmUBQ5pCiSc5PD6en7\nROOuMzOfxy+A7kZ3A40CUFdmfT8RaACFQtWDRiHrl0/9n/9jnHNOAAAAAFLD6/cAAAAAAOwPIR4A\nAABIGUI8AAAAkDKEeAAAACBlCPEAAABAyhDiAQAAgJQhxAMAAAApQ4gHAAAAUoYQDwAAAKQMIR4A\nAABIGUI8AAAAkDKEeAAAACBlCPEAAABAyhDiAQAAgJQhxAMAAAApQ4gHAAAAUoYQDwAAAKQMIR4A\nAABI [...]
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7fc685b02690>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "maps.geoplot(db, 'HOVAL', palette='Blues_r')"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "And, if you really want control, you can pass the `palettable` palette object of your choice directly! Note however that you'll need to figure out yourself the right number of colors. For example the Wes Anderson's `Chevalier_4` palette contains four colors. To display how to use it, we will generate random labels and plot them:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "import palettable as pltt\n",
+    "p = pltt.wesanderson.Chevalier_4"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {
+    "collapsed": false,
+    "scrolled": false
+   },
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/home/serge/anaconda3/envs/pysal2/lib/python2.7/site-packages/ipykernel/__main__.py:1: DeprecationWarning: This function is deprecated. Please call randint(0, 3 + 1) instead\n",
+      "  if __name__ == '__main__':\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAvEAAALlCAYAAABNf7lsAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAAPYQAAD2EBqD+naQAAIABJREFUeJzs3etzZMl95vcnM8+lbgD63nPlzJCcGVKUSJmkaMqSvLIi\nvG/8Zv/VDUc4Ym3veh27DodiZdG0VtJSJJekZjgz3Q10N4C6nVumXxSARvfgUijU5ZxT309EBQpA\noU6iu1D1nKxf/tKEEIIAAAAANIbd9AAAAAAA3AwhHgAAAGgYQjwAAADQMIR4AAAAoGEI8QAAAEDD\nEOIBAACAhiHEAwAAAA1DiAcAAAAahhAPAAAANAwhHgAAAGgYQjwAAADQMIR4AAAAoGEI8QAAAEDD\nEOIBAACAhiHEAwAAAA1DiAcAAAAahhAPAAAANAwhHgAAAGgYQjwAAADQMIR4AAAAoGEI8QAAAEDD\nEOIB [...]
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7fc685160110>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "lbls = np.random.random_integers(0, 3, db.shape[0])\n",
+    "# `alpha` is not necessary but is cool (and possible)!\n",
+    "maps.geoplot(db.assign(lbls=lbls), 'lbls', palette=p, k=4, alpha=0.5)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Other examples include:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAvEAAALlCAYAAABNf7lsAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAAPYQAAD2EBqD+naQAAIABJREFUeJzs3XeUXOd95vnnvaFCV2egGxkEARIACWZRgZRISZZkjS17\nPVpZssfH4ViW7ZVkOchpRXtnNDNe2zpej1czDrPjWXlk2V4ncSzZkqOsY+XEBIqZABE7oXOodMO7\nfzRAInSo7q6qW7fq+zmnTzWqb937a6DR9dRb7/t7jbXWCgAAAEBqOEkXAAAAAGBjCPEAAABAyhDi\nAQAAgJQhxAMAAAApQ4gHAAAAUoYQDwAAAKQMIR4AAABIGUI8AAAAkDKEeAAAACBlCPEAAABAyhDi\nAQAAgJQhxAMAAAApQ4gHAAAAUoYQDwAAAKQMIR4AAABIGUI8AAAAkDKEeAAAACBlCPEAAABAyhDi\nAQAA [...]
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7fc685b0b4d0>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "maps.geoplot(db, 'HOVAL', k=7, palette='OrRd')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAvEAAALlCAYAAABNf7lsAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAAPYQAAD2EBqD+naQAAIABJREFUeJzs3XmQbOld3vnnPUsulbXvd1/79pW6JXVLgFYQg5CGRWwT\niAnsmTH2AA6QWUY4zIzCESYmPCNkPEzA2AyeAEWAATMGZA8gCyGBJJBoIVpq7eq+3bdv991q36ty\nPed954+svn2XWrKqMvPkyfx+QqnKyjp5zq9uZ2U++ebvfY9xzjkBAAAASA0v6QIAAAAAHAwhHgAA\nAEgZQjwAAACQMoR4AAAAIGUI8QAAAEDKEOIBAACAlCHEAwAAAClDiAcAAABShhAPAAAApAwhHgAA\nAEgZQjwAAACQMoR4AAAAIGUI8QAAAEDKEOIBAACAlCHEAwAAAClDiAcAAABShhAPAAAApAwhHgAA\nAEgZ [...]
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7fc6860bee50>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "maps.geoplot(db, 'HOVAL', k=7, palette='OrRd', classi='fisher_jenks')"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Advanced capabilities"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/home/serge/anaconda3/envs/pysal2/lib/python2.7/site-packages/ipykernel/__main__.py:4: DeprecationWarning: This function is deprecated. Please call randint(0, 4 + 1) instead\n"
+     ]
+    }
+   ],
+   "source": [
+    "colors = [\"windows blue\", \"amber\", \"greyish\", \"faded green\", \"dusty purple\"]\n",
+    "pal = sns.xkcd_palette(colors)\n",
+    "\n",
+    "colors = np.array(pal)[np.random.random_integers(0, high=len(pal)-1, size=db.shape[0])]\n",
+    "colors = pd.Series(colors.tolist(), index=db.index)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "0    (0.509803921569, 0.372549019608, 0.529411764706)\n",
+       "1    (0.482352941176, 0.698039215686, 0.454901960784)\n",
+       "2     (0.658823529412, 0.643137254902, 0.58431372549)\n",
+       "3     (0.658823529412, 0.643137254902, 0.58431372549)\n",
+       "4     (0.658823529412, 0.643137254902, 0.58431372549)\n",
+       "dtype: object"
+      ]
+     },
+     "execution_count": 15,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "reload(maps);\n",
+    "y = db['HOVAL']\n",
+    "colors, classification = maps.value_classifier(y, 'percentiles')\n",
+    "colors = colors.map({i:j for i,j in enumerate(pal)})\n",
+    "colors.head()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "0    (0.509803921569, 0.372549019608, 0.529411764706)\n",
+       "1    (0.482352941176, 0.698039215686, 0.454901960784)\n",
+       "2     (0.658823529412, 0.643137254902, 0.58431372549)\n",
+       "3     (0.658823529412, 0.643137254902, 0.58431372549)\n",
+       "4     (0.658823529412, 0.643137254902, 0.58431372549)\n",
+       "dtype: object"
+      ]
+     },
+     "execution_count": 16,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "reload(maps);\n",
+    "y = db['HOVAL']\n",
+    "colors, classification = maps.value_classifier(y, 'percentiles')\n",
+    "colors = colors.map({i:j for i,j in enumerate(pal)})\n",
+    "colors.head()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [],
+   "source": [
+    "from mapping import classifier"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "array([ 27.733   ,  41.75    ,  96.400002])"
+      ]
+     },
+     "execution_count": 18,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "q = classifier['quantiles'](y, k=3)\n",
+    "q.bins"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "0     (0.509803921569, 0.372549019608, 0.529411764706)\n",
+       "1      (0.658823529412, 0.643137254902, 0.58431372549)\n",
+       "2    (0.996078431373, 0.701960784314, 0.0313725490196)\n",
+       "3    (0.996078431373, 0.701960784314, 0.0313725490196)\n",
+       "4      (0.21568627451, 0.470588235294, 0.749019607843)\n",
+       "dtype: object"
+      ]
+     },
+     "execution_count": 19,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "reload(maps);\n",
+    "y = db['HOVAL']\n",
+    "colors0, classification = maps.value_classifier(y, 'fisher_jenks', k=5)\n",
+    "colors = colors0.map({i:j for i,j in enumerate(pal)})\n",
+    "colors.head()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'Fisher_Jenks'"
+      ]
+     },
+     "execution_count": 20,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "classification.name"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAvEAAALlCAYAAABNf7lsAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAAPYQAAD2EBqD+naQAAIABJREFUeJzs3WmQJGd+3/ffk0cdfVTf95yYweAGFgsssPdS3IuXuSYZ\nFCWKFBWyxZAlBRW2Q0GF6ZAcVtiSXjgs642tCNIUFaGgKAavJVfeE4sFsAD2xOJaYGZwzAzm6p7p\nnp6+6sjM5/GL7hkMMH1Ud1dVVlZ9Pxu9fVVl/nvQXfXLp/75T+OccwIAAACQGV7aBQAAAADYHUI8\nAAAAkDGEeAAAACBjCPEAAABAxhDiAQAAgIwhxAMAAAAZQ4gHAAAAMoYQDwAAAGQMIR4AAADIGEI8\nAAAAkDGEeAAAACBjCPEAAABAxhDiAQAAgIwhxAMAAAAZQ4gHAAAAMoYQDwAAAGQMIR4AAADIGEI8\nAAAA [...]
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7fc6860be890>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "reload(maps);\n",
+    "\n",
+    "maps.plot_geocol_mpl(db.loc[:, 'geometry'], facecolor=colors)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## `bokeh` interface"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Basic functionality"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div class=\"bk-root\">\n",
+       "        <a href=\"http://bokeh.pydata.org\" target=\"_blank\" class=\"bk-logo bk-logo-small bk-logo-notebook\"></a>\n",
+       "        <span id=\"4c5f5355-a6d5-44fb-ae41-7d11e18dfe90\">Loading BokehJS ...</span>\n",
+       "    </div>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "\n",
+       "(function(global) {\n",
+       "  function now() {\n",
+       "    return new Date();\n",
+       "  }\n",
+       "\n",
+       "  var force = \"1\";\n",
+       "\n",
+       "  if (typeof (window._bokeh_onload_callbacks) === \"undefined\" || force !== \"\") {\n",
+       "    window._bokeh_onload_callbacks = [];\n",
+       "    window._bokeh_is_loading = undefined;\n",
+       "  }\n",
+       "\n",
+       "\n",
+       "  \n",
+       "  if (typeof (window._bokeh_timeout) === \"undefined\" || force !== \"\") {\n",
+       "    window._bokeh_timeout = Date.now() + 5000;\n",
+       "    window._bokeh_failed_load = false;\n",
+       "  }\n",
+       "\n",
+       "  var NB_LOAD_WARNING = {'data': {'text/html':\n",
+       "     \"<div style='background-color: #fdd'>\\n\"+\n",
+       "     \"<p>\\n\"+\n",
+       "     \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n",
+       "     \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n",
+       "     \"</p>\\n\"+\n",
+       "     \"<ul>\\n\"+\n",
+       "     \"<li>re-rerun `output_notebook()` to attempt to load from CDN again, or</li>\\n\"+\n",
+       "     \"<li>use INLINE resources instead, as so:</li>\\n\"+\n",
+       "     \"</ul>\\n\"+\n",
+       "     \"<code>\\n\"+\n",
+       "     \"from bokeh.resources import INLINE\\n\"+\n",
+       "     \"output_notebook(resources=INLINE)\\n\"+\n",
+       "     \"</code>\\n\"+\n",
+       "     \"</div>\"}};\n",
+       "\n",
+       "  function display_loaded() {\n",
+       "    if (window.Bokeh !== undefined) {\n",
+       "      Bokeh.$(\"#4c5f5355-a6d5-44fb-ae41-7d11e18dfe90\").text(\"BokehJS successfully loaded.\");\n",
+       "    } else if (Date.now() < window._bokeh_timeout) {\n",
+       "      setTimeout(display_loaded, 100)\n",
+       "    }\n",
+       "  }\n",
+       "\n",
+       "  function run_callbacks() {\n",
+       "    window._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n",
+       "    delete window._bokeh_onload_callbacks\n",
+       "    console.info(\"Bokeh: all callbacks have finished\");\n",
+       "  }\n",
+       "\n",
+       "  function load_libs(js_urls, callback) {\n",
+       "    window._bokeh_onload_callbacks.push(callback);\n",
+       "    if (window._bokeh_is_loading > 0) {\n",
+       "      console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n",
+       "      return null;\n",
+       "    }\n",
+       "    if (js_urls == null || js_urls.length === 0) {\n",
+       "      run_callbacks();\n",
+       "      return null;\n",
+       "    }\n",
+       "    console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n",
+       "    window._bokeh_is_loading = js_urls.length;\n",
+       "    for (var i = 0; i < js_urls.length; i++) {\n",
+       "      var url = js_urls[i];\n",
+       "      var s = document.createElement('script');\n",
+       "      s.src = url;\n",
+       "      s.async = false;\n",
+       "      s.onreadystatechange = s.onload = function() {\n",
+       "        window._bokeh_is_loading--;\n",
+       "        if (window._bokeh_is_loading === 0) {\n",
+       "          console.log(\"Bokeh: all BokehJS libraries loaded\");\n",
+       "          run_callbacks()\n",
+       "        }\n",
+       "      };\n",
+       "      s.onerror = function() {\n",
+       "        console.warn(\"failed to load library \" + url);\n",
+       "      };\n",
+       "      console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n",
+       "      document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
+       "    }\n",
+       "  };var element = document.getElementById(\"4c5f5355-a6d5-44fb-ae41-7d11e18dfe90\");\n",
+       "  if (element == null) {\n",
+       "    console.log(\"Bokeh: ERROR: autoload.js configured with elementid '4c5f5355-a6d5-44fb-ae41-7d11e18dfe90' but no matching script tag was found. \")\n",
+       "    return false;\n",
+       "  }\n",
+       "\n",
+       "  var js_urls = ['https://cdn.pydata.org/bokeh/release/bokeh-0.12.2.min.js', 'https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.2.min.js', 'https://cdn.pydata.org/bokeh/release/bokeh-compiler-0.12.2.min.js'];\n",
+       "\n",
+       "  var inline_js = [\n",
+       "    function(Bokeh) {\n",
+       "      Bokeh.set_log_level(\"info\");\n",
+       "    },\n",
+       "    \n",
+       "    function(Bokeh) {\n",
+       "      \n",
+       "      Bokeh.$(\"#4c5f5355-a6d5-44fb-ae41-7d11e18dfe90\").text(\"BokehJS is loading...\");\n",
+       "    },\n",
+       "    function(Bokeh) {\n",
+       "      console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-0.12.2.min.css\");\n",
+       "      Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-0.12.2.min.css\");\n",
+       "      console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.2.min.css\");\n",
+       "      Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.2.min.css\");\n",
+       "    }\n",
+       "  ];\n",
+       "\n",
+       "  function run_inline_js() {\n",
+       "    \n",
+       "    if ((window.Bokeh !== undefined) || (force === \"1\")) {\n",
+       "      for (var i = 0; i < inline_js.length; i++) {\n",
+       "        inline_js[i](window.Bokeh);\n",
+       "      }if (force === \"1\") {\n",
+       "        display_loaded();\n",
+       "      }} else if (Date.now() < window._bokeh_timeout) {\n",
+       "      setTimeout(run_inline_js, 100);\n",
+       "    } else if (!window._bokeh_failed_load) {\n",
+       "      console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n",
+       "      window._bokeh_failed_load = true;\n",
+       "    } else if (!force) {\n",
+       "      var cell = $(\"#4c5f5355-a6d5-44fb-ae41-7d11e18dfe90\").parents('.cell').data().cell;\n",
+       "      cell.output_area.append_execute_result(NB_LOAD_WARNING)\n",
+       "    }\n",
+       "\n",
+       "  }\n",
+       "\n",
+       "  if (window._bokeh_is_loading === 0) {\n",
+       "    console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n",
+       "    run_inline_js();\n",
+       "  } else {\n",
+       "    load_libs(js_urls, function() {\n",
+       "      console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n",
+       "      run_inline_js();\n",
+       "    });\n",
+       "  }\n",
+       "}(this));"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "from bokeh.models import HoverTool\n",
+    "from bokeh.palettes import Viridis6\n",
+    "from bokeh.plotting import figure, show, output_file, output_notebook, ColumnDataSource\n",
+    "output_notebook()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "<class 'pandas.core.frame.DataFrame'>\n",
+      "RangeIndex: 49 entries, 0 to 48\n",
+      "Data columns (total 21 columns):\n",
+      "AREA          49 non-null float64\n",
+      "PERIMETER     49 non-null float64\n",
+      "COLUMBUS_     49 non-null int64\n",
+      "COLUMBUS_I    49 non-null int64\n",
+      "POLYID        49 non-null int64\n",
+      "NEIG          49 non-null int64\n",
+      "HOVAL         49 non-null float64\n",
+      "INC           49 non-null float64\n",
+      "CRIME         49 non-null float64\n",
+      "OPEN          49 non-null float64\n",
+      "PLUMB         49 non-null float64\n",
+      "DISCBD        49 non-null float64\n",
+      "X             49 non-null float64\n",
+      "Y             49 non-null float64\n",
+      "NSA           49 non-null float64\n",
+      "NSB           49 non-null float64\n",
+      "EW            49 non-null float64\n",
+      "CP            49 non-null float64\n",
+      "THOUS         49 non-null float64\n",
+      "NEIGNO        49 non-null float64\n",
+      "geometry      49 non-null object\n",
+      "dtypes: float64(16), int64(4), object(1)\n",
+      "memory usage: 8.1+ KB\n"
+     ]
+    }
+   ],
+   "source": [
+    "db.info()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "metadata": {
+    "collapsed": false,
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "\n",
+       "    <div class=\"bk-root\">\n",
+       "        <div class=\"plotdiv\" id=\"79177b40-d8e3-40ed-9599-21c9822849e3\"></div>\n",
+       "    </div>\n",
+       "<script type=\"text/javascript\">\n",
+       "  \n",
+       "  (function(global) {\n",
+       "    function now() {\n",
+       "      return new Date();\n",
+       "    }\n",
+       "  \n",
+       "    var force = \"\";\n",
+       "  \n",
+       "    if (typeof (window._bokeh_onload_callbacks) === \"undefined\" || force !== \"\") {\n",
+       "      window._bokeh_onload_callbacks = [];\n",
+       "      window._bokeh_is_loading = undefined;\n",
+       "    }\n",
+       "  \n",
+       "  \n",
+       "    \n",
+       "    if (typeof (window._bokeh_timeout) === \"undefined\" || force !== \"\") {\n",
+       "      window._bokeh_timeout = Date.now() + 0;\n",
+       "      window._bokeh_failed_load = false;\n",
+       "    }\n",
+       "  \n",
+       "    var NB_LOAD_WARNING = {'data': {'text/html':\n",
+       "       \"<div style='background-color: #fdd'>\\n\"+\n",
+       "       \"<p>\\n\"+\n",
+       "       \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n",
+       "       \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n",
+       "       \"</p>\\n\"+\n",
+       "       \"<ul>\\n\"+\n",
+       "       \"<li>re-rerun `output_notebook()` to attempt to load from CDN again, or</li>\\n\"+\n",
+       "       \"<li>use INLINE resources instead, as so:</li>\\n\"+\n",
+       "       \"</ul>\\n\"+\n",
+       "       \"<code>\\n\"+\n",
+       "       \"from bokeh.resources import INLINE\\n\"+\n",
+       "       \"output_notebook(resources=INLINE)\\n\"+\n",
+       "       \"</code>\\n\"+\n",
+       "       \"</div>\"}};\n",
+       "  \n",
+       "    function display_loaded() {\n",
+       "      if (window.Bokeh !== undefined) {\n",
+       "        Bokeh.$(\"#79177b40-d8e3-40ed-9599-21c9822849e3\").text(\"BokehJS successfully loaded.\");\n",
+       "      } else if (Date.now() < window._bokeh_timeout) {\n",
+       "        setTimeout(display_loaded, 100)\n",
+       "      }\n",
+       "    }\n",
+       "  \n",
+       "    function run_callbacks() {\n",
+       "      window._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n",
+       "      delete window._bokeh_onload_callbacks\n",
+       "      console.info(\"Bokeh: all callbacks have finished\");\n",
+       "    }\n",
+       "  \n",
+       "    function load_libs(js_urls, callback) {\n",
+       "      window._bokeh_onload_callbacks.push(callback);\n",
+       "      if (window._bokeh_is_loading > 0) {\n",
+       "        console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n",
+       "        return null;\n",
+       "      }\n",
+       "      if (js_urls == null || js_urls.length === 0) {\n",
+       "        run_callbacks();\n",
+       "        return null;\n",
+       "      }\n",
+       "      console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n",
+       "      window._bokeh_is_loading = js_urls.length;\n",
+       "      for (var i = 0; i < js_urls.length; i++) {\n",
+       "        var url = js_urls[i];\n",
+       "        var s = document.createElement('script');\n",
+       "        s.src = url;\n",
+       "        s.async = false;\n",
+       "        s.onreadystatechange = s.onload = function() {\n",
+       "          window._bokeh_is_loading--;\n",
+       "          if (window._bokeh_is_loading === 0) {\n",
+       "            console.log(\"Bokeh: all BokehJS libraries loaded\");\n",
+       "            run_callbacks()\n",
+       "          }\n",
+       "        };\n",
+       "        s.onerror = function() {\n",
+       "          console.warn(\"failed to load library \" + url);\n",
+       "        };\n",
+       "        console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n",
+       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
+       "      }\n",
+       "    };var element = document.getElementById(\"79177b40-d8e3-40ed-9599-21c9822849e3\");\n",
+       "    if (element == null) {\n",
+       "      console.log(\"Bokeh: ERROR: autoload.js configured with elementid '79177b40-d8e3-40ed-9599-21c9822849e3' but no matching script tag was found. \")\n",
+       "      return false;\n",
+       "    }\n",
+       "  \n",
+       "    var js_urls = [];\n",
+       "  \n",
+       "    var inline_js = [\n",
+       "      function(Bokeh) {\n",
+       "        Bokeh.$(function() {\n",
+       "            var docs_json = {\"7e8602ff-252b-4569-9c6c-bee94077e821\":{\"roots\":{\"references\":[{\"attributes\":{\"fill_color\":{\"value\":\"#4D4D4D\"},\"line_color\":{\"value\":\"#B3B3B3\"},\"line_width\":{\"value\":0.2},\"xs\":{\"field\":\"x\"},\"ys\":{\"field\":\"y\"}},\"id\":\"175f98c4-df13-4714-baad-c1da8b7f3a42\",\"type\":\"Patches\"},{\"attributes\":{\"dimension\":1,\"grid_line_color\":{\"value\":null},\"plot\":{\"id\":\"e59df963-e7dc-43b1-a85d-12fc35c56e85\",\"subtype\" [...]
+       "            var render_items = [{\"docid\":\"7e8602ff-252b-4569-9c6c-bee94077e821\",\"elementid\":\"79177b40-d8e3-40ed-9599-21c9822849e3\",\"modelid\":\"e59df963-e7dc-43b1-a85d-12fc35c56e85\"}];\n",
+       "            \n",
+       "            Bokeh.embed.embed_items(docs_json, render_items);\n",
+       "        });\n",
+       "      },\n",
+       "      function(Bokeh) {\n",
+       "      }\n",
+       "    ];\n",
+       "  \n",
+       "    function run_inline_js() {\n",
+       "      \n",
+       "      if ((window.Bokeh !== undefined) || (force === \"1\")) {\n",
+       "        for (var i = 0; i < inline_js.length; i++) {\n",
+       "          inline_js[i](window.Bokeh);\n",
+       "        }if (force === \"1\") {\n",
+       "          display_loaded();\n",
+       "        }} else if (Date.now() < window._bokeh_timeout) {\n",
+       "        setTimeout(run_inline_js, 100);\n",
+       "      } else if (!window._bokeh_failed_load) {\n",
+       "        console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n",
+       "        window._bokeh_failed_load = true;\n",
+       "      } else if (!force) {\n",
+       "        var cell = $(\"#79177b40-d8e3-40ed-9599-21c9822849e3\").parents('.cell').data().cell;\n",
+       "        cell.output_area.append_execute_result(NB_LOAD_WARNING)\n",
+       "      }\n",
+       "  \n",
+       "    }\n",
+       "  \n",
+       "    if (window._bokeh_is_loading === 0) {\n",
+       "      console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n",
+       "      run_inline_js();\n",
+       "    } else {\n",
+       "      load_libs(js_urls, function() {\n",
+       "        console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n",
+       "        run_inline_js();\n",
+       "      });\n",
+       "    }\n",
+       "  }(this));\n",
+       "</script>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "maps.geoplot(db, backend='bk')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "\n",
+       "    <div class=\"bk-root\">\n",
+       "        <div class=\"plotdiv\" id=\"fc9c89d4-b2de-4f44-905a-8655fdc42af5\"></div>\n",
+       "    </div>\n",
+       "<script type=\"text/javascript\">\n",
+       "  \n",
+       "  (function(global) {\n",
+       "    function now() {\n",
+       "      return new Date();\n",
+       "    }\n",
+       "  \n",
+       "    var force = \"\";\n",
+       "  \n",
+       "    if (typeof (window._bokeh_onload_callbacks) === \"undefined\" || force !== \"\") {\n",
+       "      window._bokeh_onload_callbacks = [];\n",
+       "      window._bokeh_is_loading = undefined;\n",
+       "    }\n",
+       "  \n",
+       "  \n",
+       "    \n",
+       "    if (typeof (window._bokeh_timeout) === \"undefined\" || force !== \"\") {\n",
+       "      window._bokeh_timeout = Date.now() + 0;\n",
+       "      window._bokeh_failed_load = false;\n",
+       "    }\n",
+       "  \n",
+       "    var NB_LOAD_WARNING = {'data': {'text/html':\n",
+       "       \"<div style='background-color: #fdd'>\\n\"+\n",
+       "       \"<p>\\n\"+\n",
+       "       \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n",
+       "       \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n",
+       "       \"</p>\\n\"+\n",
+       "       \"<ul>\\n\"+\n",
+       "       \"<li>re-rerun `output_notebook()` to attempt to load from CDN again, or</li>\\n\"+\n",
+       "       \"<li>use INLINE resources instead, as so:</li>\\n\"+\n",
+       "       \"</ul>\\n\"+\n",
+       "       \"<code>\\n\"+\n",
+       "       \"from bokeh.resources import INLINE\\n\"+\n",
+       "       \"output_notebook(resources=INLINE)\\n\"+\n",
+       "       \"</code>\\n\"+\n",
+       "       \"</div>\"}};\n",
+       "  \n",
+       "    function display_loaded() {\n",
+       "      if (window.Bokeh !== undefined) {\n",
+       "        Bokeh.$(\"#fc9c89d4-b2de-4f44-905a-8655fdc42af5\").text(\"BokehJS successfully loaded.\");\n",
+       "      } else if (Date.now() < window._bokeh_timeout) {\n",
+       "        setTimeout(display_loaded, 100)\n",
+       "      }\n",
+       "    }\n",
+       "  \n",
+       "    function run_callbacks() {\n",
+       "      window._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n",
+       "      delete window._bokeh_onload_callbacks\n",
+       "      console.info(\"Bokeh: all callbacks have finished\");\n",
+       "    }\n",
+       "  \n",
+       "    function load_libs(js_urls, callback) {\n",
+       "      window._bokeh_onload_callbacks.push(callback);\n",
+       "      if (window._bokeh_is_loading > 0) {\n",
+       "        console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n",
+       "        return null;\n",
+       "      }\n",
+       "      if (js_urls == null || js_urls.length === 0) {\n",
+       "        run_callbacks();\n",
+       "        return null;\n",
+       "      }\n",
+       "      console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n",
+       "      window._bokeh_is_loading = js_urls.length;\n",
+       "      for (var i = 0; i < js_urls.length; i++) {\n",
+       "        var url = js_urls[i];\n",
+       "        var s = document.createElement('script');\n",
+       "        s.src = url;\n",
+       "        s.async = false;\n",
+       "        s.onreadystatechange = s.onload = function() {\n",
+       "          window._bokeh_is_loading--;\n",
+       "          if (window._bokeh_is_loading === 0) {\n",
+       "            console.log(\"Bokeh: all BokehJS libraries loaded\");\n",
+       "            run_callbacks()\n",
+       "          }\n",
+       "        };\n",
+       "        s.onerror = function() {\n",
+       "          console.warn(\"failed to load library \" + url);\n",
+       "        };\n",
+       "        console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n",
+       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
+       "      }\n",
+       "    };var element = document.getElementById(\"fc9c89d4-b2de-4f44-905a-8655fdc42af5\");\n",
+       "    if (element == null) {\n",
+       "      console.log(\"Bokeh: ERROR: autoload.js configured with elementid 'fc9c89d4-b2de-4f44-905a-8655fdc42af5' but no matching script tag was found. \")\n",
+       "      return false;\n",
+       "    }\n",
+       "  \n",
+       "    var js_urls = [];\n",
+       "  \n",
+       "    var inline_js = [\n",
+       "      function(Bokeh) {\n",
+       "        Bokeh.$(function() {\n",
+       "            var docs_json = {\"2dc0a25a-0717-470b-a3a2-7e228e4ca133\":{\"roots\":{\"references\":[{\"attributes\":{\"plot\":{\"id\":\"3e3a0208-1bc2-4417-ab4e-a3ea20ee742d\",\"subtype\":\"Figure\",\"type\":\"Plot\"}},\"id\":\"b4d2705a-596d-4cb4-b233-7a8675163c89\",\"type\":\"PanTool\"},{\"attributes\":{},\"id\":\"e1b08334-4eec-4985-ac9d-f4c708c43f54\",\"type\":\"BasicTicker\"},{\"attributes\":{\"fill_color\":{\"field\":\"facecolor\"},\"line_color\":{\"value\":\"#B3B3B3\"},\"line_w [...]
+       "            var render_items = [{\"docid\":\"2dc0a25a-0717-470b-a3a2-7e228e4ca133\",\"elementid\":\"fc9c89d4-b2de-4f44-905a-8655fdc42af5\",\"modelid\":\"3e3a0208-1bc2-4417-ab4e-a3ea20ee742d\"}];\n",
+       "            \n",
+       "            Bokeh.embed.embed_items(docs_json, render_items);\n",
+       "        });\n",
+       "      },\n",
+       "      function(Bokeh) {\n",
+       "      }\n",
+       "    ];\n",
+       "  \n",
+       "    function run_inline_js() {\n",
+       "      \n",
+       "      if ((window.Bokeh !== undefined) || (force === \"1\")) {\n",
+       "        for (var i = 0; i < inline_js.length; i++) {\n",
+       "          inline_js[i](window.Bokeh);\n",
+       "        }if (force === \"1\") {\n",
+       "          display_loaded();\n",
+       "        }} else if (Date.now() < window._bokeh_timeout) {\n",
+       "        setTimeout(run_inline_js, 100);\n",
+       "      } else if (!window._bokeh_failed_load) {\n",
+       "        console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n",
+       "        window._bokeh_failed_load = true;\n",
+       "      } else if (!force) {\n",
+       "        var cell = $(\"#fc9c89d4-b2de-4f44-905a-8655fdc42af5\").parents('.cell').data().cell;\n",
+       "        cell.output_area.append_execute_result(NB_LOAD_WARNING)\n",
+       "      }\n",
+       "  \n",
+       "    }\n",
+       "  \n",
+       "    if (window._bokeh_is_loading === 0) {\n",
+       "      console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n",
+       "      run_inline_js();\n",
+       "    } else {\n",
+       "      load_libs(js_urls, function() {\n",
+       "        console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n",
+       "        run_inline_js();\n",
+       "      });\n",
+       "    }\n",
+       "  }(this));\n",
+       "</script>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "maps.geoplot(db, 'HOVAL', palette='RdPu', backend='bk')"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Advanced capabilities"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "\n",
+       "    <div class=\"bk-root\">\n",
+       "        <div class=\"plotdiv\" id=\"2b0d78b6-5d9b-40fe-8684-08c52484d994\"></div>\n",
+       "    </div>\n",
+       "<script type=\"text/javascript\">\n",
+       "  \n",
+       "  (function(global) {\n",
+       "    function now() {\n",
+       "      return new Date();\n",
+       "    }\n",
+       "  \n",
+       "    var force = \"\";\n",
+       "  \n",
+       "    if (typeof (window._bokeh_onload_callbacks) === \"undefined\" || force !== \"\") {\n",
+       "      window._bokeh_onload_callbacks = [];\n",
+       "      window._bokeh_is_loading = undefined;\n",
+       "    }\n",
+       "  \n",
+       "  \n",
+       "    \n",
+       "    if (typeof (window._bokeh_timeout) === \"undefined\" || force !== \"\") {\n",
+       "      window._bokeh_timeout = Date.now() + 0;\n",
+       "      window._bokeh_failed_load = false;\n",
+       "    }\n",
+       "  \n",
+       "    var NB_LOAD_WARNING = {'data': {'text/html':\n",
+       "       \"<div style='background-color: #fdd'>\\n\"+\n",
+       "       \"<p>\\n\"+\n",
+       "       \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n",
+       "       \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n",
+       "       \"</p>\\n\"+\n",
+       "       \"<ul>\\n\"+\n",
+       "       \"<li>re-rerun `output_notebook()` to attempt to load from CDN again, or</li>\\n\"+\n",
+       "       \"<li>use INLINE resources instead, as so:</li>\\n\"+\n",
+       "       \"</ul>\\n\"+\n",
+       "       \"<code>\\n\"+\n",
+       "       \"from bokeh.resources import INLINE\\n\"+\n",
+       "       \"output_notebook(resources=INLINE)\\n\"+\n",
+       "       \"</code>\\n\"+\n",
+       "       \"</div>\"}};\n",
+       "  \n",
+       "    function display_loaded() {\n",
+       "      if (window.Bokeh !== undefined) {\n",
+       "        Bokeh.$(\"#2b0d78b6-5d9b-40fe-8684-08c52484d994\").text(\"BokehJS successfully loaded.\");\n",
+       "      } else if (Date.now() < window._bokeh_timeout) {\n",
+       "        setTimeout(display_loaded, 100)\n",
+       "      }\n",
+       "    }\n",
+       "  \n",
+       "    function run_callbacks() {\n",
+       "      window._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n",
+       "      delete window._bokeh_onload_callbacks\n",
+       "      console.info(\"Bokeh: all callbacks have finished\");\n",
+       "    }\n",
+       "  \n",
+       "    function load_libs(js_urls, callback) {\n",
+       "      window._bokeh_onload_callbacks.push(callback);\n",
+       "      if (window._bokeh_is_loading > 0) {\n",
+       "        console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n",
+       "        return null;\n",
+       "      }\n",
+       "      if (js_urls == null || js_urls.length === 0) {\n",
+       "        run_callbacks();\n",
+       "        return null;\n",
+       "      }\n",
+       "      console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n",
+       "      window._bokeh_is_loading = js_urls.length;\n",
+       "      for (var i = 0; i < js_urls.length; i++) {\n",
+       "        var url = js_urls[i];\n",
+       "        var s = document.createElement('script');\n",
+       "        s.src = url;\n",
+       "        s.async = false;\n",
+       "        s.onreadystatechange = s.onload = function() {\n",
+       "          window._bokeh_is_loading--;\n",
+       "          if (window._bokeh_is_loading === 0) {\n",
+       "            console.log(\"Bokeh: all BokehJS libraries loaded\");\n",
+       "            run_callbacks()\n",
+       "          }\n",
+       "        };\n",
+       "        s.onerror = function() {\n",
+       "          console.warn(\"failed to load library \" + url);\n",
+       "        };\n",
+       "        console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n",
+       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
+       "      }\n",
+       "    };var element = document.getElementById(\"2b0d78b6-5d9b-40fe-8684-08c52484d994\");\n",
+       "    if (element == null) {\n",
+       "      console.log(\"Bokeh: ERROR: autoload.js configured with elementid '2b0d78b6-5d9b-40fe-8684-08c52484d994' but no matching script tag was found. \")\n",
+       "      return false;\n",
+       "    }\n",
+       "  \n",
+       "    var js_urls = [];\n",
+       "  \n",
+       "    var inline_js = [\n",
+       "      function(Bokeh) {\n",
+       "        Bokeh.$(function() {\n",
+       "            var docs_json = {\"cd90c40c-2777-4c3c-8c28-e5c2ba8ed0d2\":{\"roots\":{\"references\":[{\"attributes\":{\"plot\":{\"id\":\"80bcccee-1a4b-468e-9ad6-ffaf61916ed1\",\"subtype\":\"Figure\",\"type\":\"Plot\"}},\"id\":\"8a92b5fc-bbba-4120-b903-b7d498ab0f52\",\"type\":\"ResetTool\"},{\"attributes\":{\"callback\":null},\"id\":\"08c4b80e-d641-4bad-99f1-9c16f0bfd884\",\"type\":\"DataRange1d\"},{\"attributes\":{\"callback\":null,\"column_names\":[\"y\",\"x\"],\"data\":{\"x\":[[8. [...]
+       "            var render_items = [{\"docid\":\"cd90c40c-2777-4c3c-8c28-e5c2ba8ed0d2\",\"elementid\":\"2b0d78b6-5d9b-40fe-8684-08c52484d994\",\"modelid\":\"80bcccee-1a4b-468e-9ad6-ffaf61916ed1\"}];\n",
+       "            \n",
+       "            Bokeh.embed.embed_items(docs_json, render_items);\n",
+       "        });\n",
+       "      },\n",
+       "      function(Bokeh) {\n",
+       "      }\n",
+       "    ];\n",
+       "  \n",
+       "    function run_inline_js() {\n",
+       "      \n",
+       "      if ((window.Bokeh !== undefined) || (force === \"1\")) {\n",
+       "        for (var i = 0; i < inline_js.length; i++) {\n",
+       "          inline_js[i](window.Bokeh);\n",
+       "        }if (force === \"1\") {\n",
+       "          display_loaded();\n",
+       "        }} else if (Date.now() < window._bokeh_timeout) {\n",
+       "        setTimeout(run_inline_js, 100);\n",
+       "      } else if (!window._bokeh_failed_load) {\n",
+       "        console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n",
+       "        window._bokeh_failed_load = true;\n",
+       "      } else if (!force) {\n",
+       "        var cell = $(\"#2b0d78b6-5d9b-40fe-8684-08c52484d994\").parents('.cell').data().cell;\n",
+       "        cell.output_area.append_execute_result(NB_LOAD_WARNING)\n",
+       "      }\n",
+       "  \n",
+       "    }\n",
+       "  \n",
+       "    if (window._bokeh_is_loading === 0) {\n",
+       "      console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n",
+       "      run_inline_js();\n",
+       "    } else {\n",
+       "      load_libs(js_urls, function() {\n",
+       "        console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n",
+       "        run_inline_js();\n",
+       "      });\n",
+       "    }\n",
+       "  }(this));\n",
+       "</script>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "reload(maps)\n",
+    "\n",
+    "maps.plot_geocol_bk(db['geometry'], marker_size=10, hover=True)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "\n",
+       "    <div class=\"bk-root\">\n",
+       "        <div class=\"plotdiv\" id=\"9ba9c92a-404e-4557-923b-e577a39e6431\"></div>\n",
+       "    </div>\n",
+       "<script type=\"text/javascript\">\n",
+       "  \n",
+       "  (function(global) {\n",
+       "    function now() {\n",
+       "      return new Date();\n",
+       "    }\n",
+       "  \n",
+       "    var force = \"\";\n",
+       "  \n",
+       "    if (typeof (window._bokeh_onload_callbacks) === \"undefined\" || force !== \"\") {\n",
+       "      window._bokeh_onload_callbacks = [];\n",
+       "      window._bokeh_is_loading = undefined;\n",
+       "    }\n",
+       "  \n",
+       "  \n",
+       "    \n",
+       "    if (typeof (window._bokeh_timeout) === \"undefined\" || force !== \"\") {\n",
+       "      window._bokeh_timeout = Date.now() + 0;\n",
+       "      window._bokeh_failed_load = false;\n",
+       "    }\n",
+       "  \n",
+       "    var NB_LOAD_WARNING = {'data': {'text/html':\n",
+       "       \"<div style='background-color: #fdd'>\\n\"+\n",
+       "       \"<p>\\n\"+\n",
+       "       \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n",
+       "       \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n",
+       "       \"</p>\\n\"+\n",
+       "       \"<ul>\\n\"+\n",
+       "       \"<li>re-rerun `output_notebook()` to attempt to load from CDN again, or</li>\\n\"+\n",
+       "       \"<li>use INLINE resources instead, as so:</li>\\n\"+\n",
+       "       \"</ul>\\n\"+\n",
+       "       \"<code>\\n\"+\n",
+       "       \"from bokeh.resources import INLINE\\n\"+\n",
+       "       \"output_notebook(resources=INLINE)\\n\"+\n",
+       "       \"</code>\\n\"+\n",
+       "       \"</div>\"}};\n",
+       "  \n",
+       "    function display_loaded() {\n",
+       "      if (window.Bokeh !== undefined) {\n",
+       "        Bokeh.$(\"#9ba9c92a-404e-4557-923b-e577a39e6431\").text(\"BokehJS successfully loaded.\");\n",
+       "      } else if (Date.now() < window._bokeh_timeout) {\n",
+       "        setTimeout(display_loaded, 100)\n",
+       "      }\n",
+       "    }\n",
+       "  \n",
+       "    function run_callbacks() {\n",
+       "      window._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n",
+       "      delete window._bokeh_onload_callbacks\n",
+       "      console.info(\"Bokeh: all callbacks have finished\");\n",
+       "    }\n",
+       "  \n",
+       "    function load_libs(js_urls, callback) {\n",
+       "      window._bokeh_onload_callbacks.push(callback);\n",
+       "      if (window._bokeh_is_loading > 0) {\n",
+       "        console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n",
+       "        return null;\n",
+       "      }\n",
+       "      if (js_urls == null || js_urls.length === 0) {\n",
+       "        run_callbacks();\n",
+       "        return null;\n",
+       "      }\n",
+       "      console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n",
+       "      window._bokeh_is_loading = js_urls.length;\n",
+       "      for (var i = 0; i < js_urls.length; i++) {\n",
+       "        var url = js_urls[i];\n",
+       "        var s = document.createElement('script');\n",
+       "        s.src = url;\n",
+       "        s.async = false;\n",
+       "        s.onreadystatechange = s.onload = function() {\n",
+       "          window._bokeh_is_loading--;\n",
+       "          if (window._bokeh_is_loading === 0) {\n",
+       "            console.log(\"Bokeh: all BokehJS libraries loaded\");\n",
+       "            run_callbacks()\n",
+       "          }\n",
+       "        };\n",
+       "        s.onerror = function() {\n",
+       "          console.warn(\"failed to load library \" + url);\n",
+       "        };\n",
+       "        console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n",
+       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
+       "      }\n",
+       "    };var element = document.getElementById(\"9ba9c92a-404e-4557-923b-e577a39e6431\");\n",
+       "    if (element == null) {\n",
+       "      console.log(\"Bokeh: ERROR: autoload.js configured with elementid '9ba9c92a-404e-4557-923b-e577a39e6431' but no matching script tag was found. \")\n",
+       "      return false;\n",
+       "    }\n",
+       "  \n",
+       "    var js_urls = [];\n",
+       "  \n",
+       "    var inline_js = [\n",
+       "      function(Bokeh) {\n",
+       "        Bokeh.$(function() {\n",
+       "            var docs_json = {\"56a3a343-618b-49e9-a716-c343118ae56b\":{\"roots\":{\"references\":[{\"attributes\":{\"plot\":{\"id\":\"7fbf671f-a6a9-4b41-8642-09f13d8341b0\",\"subtype\":\"Figure\",\"type\":\"Plot\"}},\"id\":\"ff274918-776c-4d7b-8bc2-3ac23aa7d64b\",\"type\":\"PanTool\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"line_width\":{\"value\":0.2},\"xs\":{\" [...]
+       "            var render_items = [{\"docid\":\"56a3a343-618b-49e9-a716-c343118ae56b\",\"elementid\":\"9ba9c92a-404e-4557-923b-e577a39e6431\",\"modelid\":\"7fbf671f-a6a9-4b41-8642-09f13d8341b0\"}];\n",
+       "            \n",
+       "            Bokeh.embed.embed_items(docs_json, render_items);\n",
+       "        });\n",
+       "      },\n",
+       "      function(Bokeh) {\n",
+       "      }\n",
+       "    ];\n",
+       "  \n",
+       "    function run_inline_js() {\n",
+       "      \n",
+       "      if ((window.Bokeh !== undefined) || (force === \"1\")) {\n",
+       "        for (var i = 0; i < inline_js.length; i++) {\n",
+       "          inline_js[i](window.Bokeh);\n",
+       "        }if (force === \"1\") {\n",
+       "          display_loaded();\n",
+       "        }} else if (Date.now() < window._bokeh_timeout) {\n",
+       "        setTimeout(run_inline_js, 100);\n",
+       "      } else if (!window._bokeh_failed_load) {\n",
+       "        console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n",
+       "        window._bokeh_failed_load = true;\n",
+       "      } else if (!force) {\n",
+       "        var cell = $(\"#9ba9c92a-404e-4557-923b-e577a39e6431\").parents('.cell').data().cell;\n",
+       "        cell.output_area.append_execute_result(NB_LOAD_WARNING)\n",
+       "      }\n",
+       "  \n",
+       "    }\n",
+       "  \n",
+       "    if (window._bokeh_is_loading === 0) {\n",
+       "      console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n",
+       "      run_inline_js();\n",
+       "    } else {\n",
+       "      load_libs(js_urls, function() {\n",
+       "        console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n",
+       "        run_inline_js();\n",
+       "      });\n",
+       "    }\n",
+       "  }(this));\n",
+       "</script>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "reload(maps)\n",
+    "\n",
+    "maps.plot_geocol_bk(db['geometry'], marker_size=10, hover=True,\\\n",
+    "                   facecolor=colors)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 28,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "\n",
+       "    <div class=\"bk-root\">\n",
+       "        <div class=\"plotdiv\" id=\"d9a26d5e-9410-4ffc-96fa-f28688df6cfa\"></div>\n",
+       "    </div>\n",
+       "<script type=\"text/javascript\">\n",
+       "  \n",
+       "  (function(global) {\n",
+       "    function now() {\n",
+       "      return new Date();\n",
+       "    }\n",
+       "  \n",
+       "    var force = \"\";\n",
+       "  \n",
+       "    if (typeof (window._bokeh_onload_callbacks) === \"undefined\" || force !== \"\") {\n",
+       "      window._bokeh_onload_callbacks = [];\n",
+       "      window._bokeh_is_loading = undefined;\n",
+       "    }\n",
+       "  \n",
+       "  \n",
+       "    \n",
+       "    if (typeof (window._bokeh_timeout) === \"undefined\" || force !== \"\") {\n",
+       "      window._bokeh_timeout = Date.now() + 0;\n",
+       "      window._bokeh_failed_load = false;\n",
+       "    }\n",
+       "  \n",
+       "    var NB_LOAD_WARNING = {'data': {'text/html':\n",
+       "       \"<div style='background-color: #fdd'>\\n\"+\n",
+       "       \"<p>\\n\"+\n",
+       "       \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n",
+       "       \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n",
+       "       \"</p>\\n\"+\n",
+       "       \"<ul>\\n\"+\n",
+       "       \"<li>re-rerun `output_notebook()` to attempt to load from CDN again, or</li>\\n\"+\n",
+       "       \"<li>use INLINE resources instead, as so:</li>\\n\"+\n",
+       "       \"</ul>\\n\"+\n",
+       "       \"<code>\\n\"+\n",
+       "       \"from bokeh.resources import INLINE\\n\"+\n",
+       "       \"output_notebook(resources=INLINE)\\n\"+\n",
+       "       \"</code>\\n\"+\n",
+       "       \"</div>\"}};\n",
+       "  \n",
+       "    function display_loaded() {\n",
+       "      if (window.Bokeh !== undefined) {\n",
+       "        Bokeh.$(\"#d9a26d5e-9410-4ffc-96fa-f28688df6cfa\").text(\"BokehJS successfully loaded.\");\n",
+       "      } else if (Date.now() < window._bokeh_timeout) {\n",
+       "        setTimeout(display_loaded, 100)\n",
+       "      }\n",
+       "    }\n",
+       "  \n",
+       "    function run_callbacks() {\n",
+       "      window._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n",
+       "      delete window._bokeh_onload_callbacks\n",
+       "      console.info(\"Bokeh: all callbacks have finished\");\n",
+       "    }\n",
+       "  \n",
+       "    function load_libs(js_urls, callback) {\n",
+       "      window._bokeh_onload_callbacks.push(callback);\n",
+       "      if (window._bokeh_is_loading > 0) {\n",
+       "        console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n",
+       "        return null;\n",
+       "      }\n",
+       "      if (js_urls == null || js_urls.length === 0) {\n",
+       "        run_callbacks();\n",
+       "        return null;\n",
+       "      }\n",
+       "      console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n",
+       "      window._bokeh_is_loading = js_urls.length;\n",
+       "      for (var i = 0; i < js_urls.length; i++) {\n",
+       "        var url = js_urls[i];\n",
+       "        var s = document.createElement('script');\n",
+       "        s.src = url;\n",
+       "        s.async = false;\n",
+       "        s.onreadystatechange = s.onload = function() {\n",
+       "          window._bokeh_is_loading--;\n",
+       "          if (window._bokeh_is_loading === 0) {\n",
+       "            console.log(\"Bokeh: all BokehJS libraries loaded\");\n",
+       "            run_callbacks()\n",
+       "          }\n",
+       "        };\n",
+       "        s.onerror = function() {\n",
+       "          console.warn(\"failed to load library \" + url);\n",
+       "        };\n",
+       "        console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n",
+       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
+       "      }\n",
+       "    };var element = document.getElementById(\"d9a26d5e-9410-4ffc-96fa-f28688df6cfa\");\n",
+       "    if (element == null) {\n",
+       "      console.log(\"Bokeh: ERROR: autoload.js configured with elementid 'd9a26d5e-9410-4ffc-96fa-f28688df6cfa' but no matching script tag was found. \")\n",
+       "      return false;\n",
+       "    }\n",
+       "  \n",
+       "    var js_urls = [];\n",
+       "  \n",
+       "    var inline_js = [\n",
+       "      function(Bokeh) {\n",
+       "        Bokeh.$(function() {\n",
+       "            var docs_json = {\"8fa2b33d-7922-464b-8fa5-509d9519fcfb\":{\"roots\":{\"references\":[{\"attributes\":{\"active_drag\":\"auto\",\"active_scroll\":\"auto\",\"active_tap\":\"auto\",\"tools\":[{\"id\":\"3ca30532-2ad2-461f-8ca6-b077370d373b\",\"type\":\"PanTool\"},{\"id\":\"fcf840f6-d445-413e-8003-22827e76d53a\",\"type\":\"WheelZoomTool\"},{\"id\":\"7939c83e-a2c9-4873-953d-afa66b5f73a4\",\"type\":\"BoxZoomTool\"},{\"id\":\"a5eec090-06b3-4d12-9962-d14d2557ed11\",\"type\":\ [...]
+       "            var render_items = [{\"docid\":\"8fa2b33d-7922-464b-8fa5-509d9519fcfb\",\"elementid\":\"d9a26d5e-9410-4ffc-96fa-f28688df6cfa\",\"modelid\":\"e4b6f4a2-c162-41cd-bc79-50301f411bfa\"}];\n",
+       "            \n",
+       "            Bokeh.embed.embed_items(docs_json, render_items);\n",
+       "        });\n",
+       "      },\n",
+       "      function(Bokeh) {\n",
+       "      }\n",
+       "    ];\n",
+       "  \n",
+       "    function run_inline_js() {\n",
+       "      \n",
+       "      if ((window.Bokeh !== undefined) || (force === \"1\")) {\n",
+       "        for (var i = 0; i < inline_js.length; i++) {\n",
+       "          inline_js[i](window.Bokeh);\n",
+       "        }if (force === \"1\") {\n",
+       "          display_loaded();\n",
+       "        }} else if (Date.now() < window._bokeh_timeout) {\n",
+       "        setTimeout(run_inline_js, 100);\n",
+       "      } else if (!window._bokeh_failed_load) {\n",
+       "        console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n",
+       "        window._bokeh_failed_load = true;\n",
+       "      } else if (!force) {\n",
+       "        var cell = $(\"#d9a26d5e-9410-4ffc-96fa-f28688df6cfa\").parents('.cell').data().cell;\n",
+       "        cell.output_area.append_execute_result(NB_LOAD_WARNING)\n",
+       "      }\n",
+       "  \n",
+       "    }\n",
+       "  \n",
+       "    if (window._bokeh_is_loading === 0) {\n",
+       "      console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n",
+       "      run_inline_js();\n",
+       "    } else {\n",
+       "      load_libs(js_urls, function() {\n",
+       "        console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n",
+       "        run_inline_js();\n",
+       "      });\n",
+       "    }\n",
+       "  }(this));\n",
+       "</script>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "reload(maps)\n",
+    "\n",
+    "maps.geoplot(db, col='HOVAL' ,marker_size=10, hover=True,\\\n",
+    "             backend='bk')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "\n",
+       "    <div class=\"bk-root\">\n",
+       "        <div class=\"plotdiv\" id=\"654bb4e1-ad27-4945-8a12-560a03665d73\"></div>\n",
+       "    </div>\n",
+       "<script type=\"text/javascript\">\n",
+       "  \n",
+       "  (function(global) {\n",
+       "    function now() {\n",
+       "      return new Date();\n",
+       "    }\n",
+       "  \n",
+       "    var force = \"\";\n",
+       "  \n",
+       "    if (typeof (window._bokeh_onload_callbacks) === \"undefined\" || force !== \"\") {\n",
+       "      window._bokeh_onload_callbacks = [];\n",
+       "      window._bokeh_is_loading = undefined;\n",
+       "    }\n",
+       "  \n",
+       "  \n",
+       "    \n",
+       "    if (typeof (window._bokeh_timeout) === \"undefined\" || force !== \"\") {\n",
+       "      window._bokeh_timeout = Date.now() + 0;\n",
+       "      window._bokeh_failed_load = false;\n",
+       "    }\n",
+       "  \n",
+       "    var NB_LOAD_WARNING = {'data': {'text/html':\n",
+       "       \"<div style='background-color: #fdd'>\\n\"+\n",
+       "       \"<p>\\n\"+\n",
+       "       \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n",
+       "       \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n",
+       "       \"</p>\\n\"+\n",
+       "       \"<ul>\\n\"+\n",
+       "       \"<li>re-rerun `output_notebook()` to attempt to load from CDN again, or</li>\\n\"+\n",
+       "       \"<li>use INLINE resources instead, as so:</li>\\n\"+\n",
+       "       \"</ul>\\n\"+\n",
+       "       \"<code>\\n\"+\n",
+       "       \"from bokeh.resources import INLINE\\n\"+\n",
+       "       \"output_notebook(resources=INLINE)\\n\"+\n",
+       "       \"</code>\\n\"+\n",
+       "       \"</div>\"}};\n",
+       "  \n",
+       "    function display_loaded() {\n",
+       "      if (window.Bokeh !== undefined) {\n",
+       "        Bokeh.$(\"#654bb4e1-ad27-4945-8a12-560a03665d73\").text(\"BokehJS successfully loaded.\");\n",
+       "      } else if (Date.now() < window._bokeh_timeout) {\n",
+       "        setTimeout(display_loaded, 100)\n",
+       "      }\n",
+       "    }\n",
+       "  \n",
+       "    function run_callbacks() {\n",
+       "      window._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n",
+       "      delete window._bokeh_onload_callbacks\n",
+       "      console.info(\"Bokeh: all callbacks have finished\");\n",
+       "    }\n",
+       "  \n",
+       "    function load_libs(js_urls, callback) {\n",
+       "      window._bokeh_onload_callbacks.push(callback);\n",
+       "      if (window._bokeh_is_loading > 0) {\n",
+       "        console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n",
+       "        return null;\n",
+       "      }\n",
+       "      if (js_urls == null || js_urls.length === 0) {\n",
+       "        run_callbacks();\n",
+       "        return null;\n",
+       "      }\n",
+       "      console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n",
+       "      window._bokeh_is_loading = js_urls.length;\n",
+       "      for (var i = 0; i < js_urls.length; i++) {\n",
+       "        var url = js_urls[i];\n",
+       "        var s = document.createElement('script');\n",
+       "        s.src = url;\n",
+       "        s.async = false;\n",
+       "        s.onreadystatechange = s.onload = function() {\n",
+       "          window._bokeh_is_loading--;\n",
+       "          if (window._bokeh_is_loading === 0) {\n",
+       "            console.log(\"Bokeh: all BokehJS libraries loaded\");\n",
+       "            run_callbacks()\n",
+       "          }\n",
+       "        };\n",
+       "        s.onerror = function() {\n",
+       "          console.warn(\"failed to load library \" + url);\n",
+       "        };\n",
+       "        console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n",
+       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
+       "      }\n",
+       "    };var element = document.getElementById(\"654bb4e1-ad27-4945-8a12-560a03665d73\");\n",
+       "    if (element == null) {\n",
+       "      console.log(\"Bokeh: ERROR: autoload.js configured with elementid '654bb4e1-ad27-4945-8a12-560a03665d73' but no matching script tag was found. \")\n",
+       "      return false;\n",
+       "    }\n",
+       "  \n",
+       "    var js_urls = [];\n",
+       "  \n",
+       "    var inline_js = [\n",
+       "      function(Bokeh) {\n",
+       "        Bokeh.$(function() {\n",
+       "            var docs_json = {\"519cce4a-5a76-48ec-9ce6-3c0ae75358c1\":{\"roots\":{\"references\":[{\"attributes\":{\"active_drag\":\"auto\",\"active_scroll\":\"auto\",\"active_tap\":\"auto\",\"tools\":[{\"id\":\"9c24d024-0ecc-4ff6-b9df-9ac70077cf9e\",\"type\":\"PanTool\"},{\"id\":\"dd173062-cb24-4628-a596-858e987a1f65\",\"type\":\"WheelZoomTool\"},{\"id\":\"0e8b0118-3408-48e7-81eb-c755bfe303dc\",\"type\":\"BoxZoomTool\"},{\"id\":\"afcb65d1-aafd-4660-9a0c-9e0737bd8457\",\"type\":\ [...]
+       "            var render_items = [{\"docid\":\"519cce4a-5a76-48ec-9ce6-3c0ae75358c1\",\"elementid\":\"654bb4e1-ad27-4945-8a12-560a03665d73\",\"modelid\":\"cea8a5b9-e936-4e17-9d42-ab6e785a2408\"}];\n",
+       "            \n",
+       "            Bokeh.embed.embed_items(docs_json, render_items);\n",
+       "        });\n",
+       "      },\n",
+       "      function(Bokeh) {\n",
+       "      }\n",
+       "    ];\n",
+       "  \n",
+       "    function run_inline_js() {\n",
+       "      \n",
+       "      if ((window.Bokeh !== undefined) || (force === \"1\")) {\n",
+       "        for (var i = 0; i < inline_js.length; i++) {\n",
+       "          inline_js[i](window.Bokeh);\n",
+       "        }if (force === \"1\") {\n",
+       "          display_loaded();\n",
+       "        }} else if (Date.now() < window._bokeh_timeout) {\n",
+       "        setTimeout(run_inline_js, 100);\n",
+       "      } else if (!window._bokeh_failed_load) {\n",
+       "        console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n",
+       "        window._bokeh_failed_load = true;\n",
+       "      } else if (!force) {\n",
+       "        var cell = $(\"#654bb4e1-ad27-4945-8a12-560a03665d73\").parents('.cell').data().cell;\n",
+       "        cell.output_area.append_execute_result(NB_LOAD_WARNING)\n",
+       "      }\n",
+       "  \n",
+       "    }\n",
+       "  \n",
+       "    if (window._bokeh_is_loading === 0) {\n",
+       "      console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n",
+       "      run_inline_js();\n",
+       "    } else {\n",
+       "      load_libs(js_urls, function() {\n",
+       "        console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n",
+       "        run_inline_js();\n",
+       "      });\n",
+       "    }\n",
+       "  }(this));\n",
+       "</script>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "reload(maps)\n",
+    "\n",
+    "maps.geoplot(db, col='HOVAL' ,marker_size=10, hover=True,\\\n",
+    "             backend='bk', classi='fisher_jenks')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "\n",
+       "    <div class=\"bk-root\">\n",
+       "        <div class=\"plotdiv\" id=\"2f2b2887-6e3e-4076-864c-ce1142ab222e\"></div>\n",
+       "    </div>\n",
+       "<script type=\"text/javascript\">\n",
+       "  \n",
+       "  (function(global) {\n",
+       "    function now() {\n",
+       "      return new Date();\n",
+       "    }\n",
+       "  \n",
+       "    var force = \"\";\n",
+       "  \n",
+       "    if (typeof (window._bokeh_onload_callbacks) === \"undefined\" || force !== \"\") {\n",
+       "      window._bokeh_onload_callbacks = [];\n",
+       "      window._bokeh_is_loading = undefined;\n",
+       "    }\n",
+       "  \n",
+       "  \n",
+       "    \n",
+       "    if (typeof (window._bokeh_timeout) === \"undefined\" || force !== \"\") {\n",
+       "      window._bokeh_timeout = Date.now() + 0;\n",
+       "      window._bokeh_failed_load = false;\n",
+       "    }\n",
+       "  \n",
+       "    var NB_LOAD_WARNING = {'data': {'text/html':\n",
+       "       \"<div style='background-color: #fdd'>\\n\"+\n",
+       "       \"<p>\\n\"+\n",
+       "       \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n",
+       "       \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n",
+       "       \"</p>\\n\"+\n",
+       "       \"<ul>\\n\"+\n",
+       "       \"<li>re-rerun `output_notebook()` to attempt to load from CDN again, or</li>\\n\"+\n",
+       "       \"<li>use INLINE resources instead, as so:</li>\\n\"+\n",
+       "       \"</ul>\\n\"+\n",
+       "       \"<code>\\n\"+\n",
+       "       \"from bokeh.resources import INLINE\\n\"+\n",
+       "       \"output_notebook(resources=INLINE)\\n\"+\n",
+       "       \"</code>\\n\"+\n",
+       "       \"</div>\"}};\n",
+       "  \n",
+       "    function display_loaded() {\n",
+       "      if (window.Bokeh !== undefined) {\n",
+       "        Bokeh.$(\"#2f2b2887-6e3e-4076-864c-ce1142ab222e\").text(\"BokehJS successfully loaded.\");\n",
+       "      } else if (Date.now() < window._bokeh_timeout) {\n",
+       "        setTimeout(display_loaded, 100)\n",
+       "      }\n",
+       "    }\n",
+       "  \n",
+       "    function run_callbacks() {\n",
+       "      window._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n",
+       "      delete window._bokeh_onload_callbacks\n",
+       "      console.info(\"Bokeh: all callbacks have finished\");\n",
+       "    }\n",
+       "  \n",
+       "    function load_libs(js_urls, callback) {\n",
+       "      window._bokeh_onload_callbacks.push(callback);\n",
+       "      if (window._bokeh_is_loading > 0) {\n",
+       "        console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n",
+       "        return null;\n",
+       "      }\n",
+       "      if (js_urls == null || js_urls.length === 0) {\n",
+       "        run_callbacks();\n",
+       "        return null;\n",
+       "      }\n",
+       "      console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n",
+       "      window._bokeh_is_loading = js_urls.length;\n",
+       "      for (var i = 0; i < js_urls.length; i++) {\n",
+       "        var url = js_urls[i];\n",
+       "        var s = document.createElement('script');\n",
+       "        s.src = url;\n",
+       "        s.async = false;\n",
+       "        s.onreadystatechange = s.onload = function() {\n",
+       "          window._bokeh_is_loading--;\n",
+       "          if (window._bokeh_is_loading === 0) {\n",
+       "            console.log(\"Bokeh: all BokehJS libraries loaded\");\n",
+       "            run_callbacks()\n",
+       "          }\n",
+       "        };\n",
+       "        s.onerror = function() {\n",
+       "          console.warn(\"failed to load library \" + url);\n",
+       "        };\n",
+       "        console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n",
+       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
+       "      }\n",
+       "    };var element = document.getElementById(\"2f2b2887-6e3e-4076-864c-ce1142ab222e\");\n",
+       "    if (element == null) {\n",
+       "      console.log(\"Bokeh: ERROR: autoload.js configured with elementid '2f2b2887-6e3e-4076-864c-ce1142ab222e' but no matching script tag was found. \")\n",
+       "      return false;\n",
+       "    }\n",
+       "  \n",
+       "    var js_urls = [];\n",
+       "  \n",
+       "    var inline_js = [\n",
+       "      function(Bokeh) {\n",
+       "        Bokeh.$(function() {\n",
+       "            var docs_json = {\"51df25a9-daef-4995-b347-f619be066214\":{\"roots\":{\"references\":[{\"attributes\":{\"plot\":null,\"text\":null},\"id\":\"5caea954-28fb-43e9-83fe-8a16b399c90e\",\"type\":\"Title\"},{\"attributes\":{\"plot\":{\"id\":\"b8778257-e3c8-4431-bafc-8c7e3d7f2a40\",\"subtype\":\"Figure\",\"type\":\"Plot\"}},\"id\":\"b7490e71-117e-4b70-a850-cdfb0d905407\",\"type\":\"PanTool\"},{\"attributes\":{},\"id\":\"d4ace122-5d44-4f5c-b818-13022bc9e049\",\"type\":\"BasicT [...]
+       "            var render_items = [{\"docid\":\"51df25a9-daef-4995-b347-f619be066214\",\"elementid\":\"2f2b2887-6e3e-4076-864c-ce1142ab222e\",\"modelid\":\"b8778257-e3c8-4431-bafc-8c7e3d7f2a40\"}];\n",
+       "            \n",
+       "            Bokeh.embed.embed_items(docs_json, render_items);\n",
+       "        });\n",
+       "      },\n",
+       "      function(Bokeh) {\n",
+       "      }\n",
+       "    ];\n",
+       "  \n",
+       "    function run_inline_js() {\n",
+       "      \n",
+       "      if ((window.Bokeh !== undefined) || (force === \"1\")) {\n",
+       "        for (var i = 0; i < inline_js.length; i++) {\n",
+       "          inline_js[i](window.Bokeh);\n",
+       "        }if (force === \"1\") {\n",
+       "          display_loaded();\n",
+       "        }} else if (Date.now() < window._bokeh_timeout) {\n",
+       "        setTimeout(run_inline_js, 100);\n",
+       "      } else if (!window._bokeh_failed_load) {\n",
+       "        console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n",
+       "        window._bokeh_failed_load = true;\n",
+       "      } else if (!force) {\n",
+       "        var cell = $(\"#2f2b2887-6e3e-4076-864c-ce1142ab222e\").parents('.cell').data().cell;\n",
+       "        cell.output_area.append_execute_result(NB_LOAD_WARNING)\n",
+       "      }\n",
+       "  \n",
+       "    }\n",
+       "  \n",
+       "    if (window._bokeh_is_loading === 0) {\n",
+       "      console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n",
+       "      run_inline_js();\n",
+       "    } else {\n",
+       "      load_libs(js_urls, function() {\n",
+       "        console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n",
+       "        run_inline_js();\n",
+       "      });\n",
+       "    }\n",
+       "  }(this));\n",
+       "</script>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "reload(maps)\n",
+    "\n",
+    "maps.geoplot(db, col='HOVAL' ,marker_size=10, hover=True,\\\n",
+    "             backend='bk', classi='fisher_jenks', palette='OrRd')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 31,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "\n",
+       "    <div class=\"bk-root\">\n",
+       "        <div class=\"plotdiv\" id=\"fef73c4a-6b29-41cb-82a4-92a086d2028b\"></div>\n",
+       "    </div>\n",
+       "<script type=\"text/javascript\">\n",
+       "  \n",
+       "  (function(global) {\n",
+       "    function now() {\n",
+       "      return new Date();\n",
+       "    }\n",
+       "  \n",
+       "    var force = \"\";\n",
+       "  \n",
+       "    if (typeof (window._bokeh_onload_callbacks) === \"undefined\" || force !== \"\") {\n",
+       "      window._bokeh_onload_callbacks = [];\n",
+       "      window._bokeh_is_loading = undefined;\n",
+       "    }\n",
+       "  \n",
+       "  \n",
+       "    \n",
+       "    if (typeof (window._bokeh_timeout) === \"undefined\" || force !== \"\") {\n",
+       "      window._bokeh_timeout = Date.now() + 0;\n",
+       "      window._bokeh_failed_load = false;\n",
+       "    }\n",
+       "  \n",
+       "    var NB_LOAD_WARNING = {'data': {'text/html':\n",
+       "       \"<div style='background-color: #fdd'>\\n\"+\n",
+       "       \"<p>\\n\"+\n",
+       "       \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n",
+       "       \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n",
+       "       \"</p>\\n\"+\n",
+       "       \"<ul>\\n\"+\n",
+       "       \"<li>re-rerun `output_notebook()` to attempt to load from CDN again, or</li>\\n\"+\n",
+       "       \"<li>use INLINE resources instead, as so:</li>\\n\"+\n",
+       "       \"</ul>\\n\"+\n",
+       "       \"<code>\\n\"+\n",
+       "       \"from bokeh.resources import INLINE\\n\"+\n",
+       "       \"output_notebook(resources=INLINE)\\n\"+\n",
+       "       \"</code>\\n\"+\n",
+       "       \"</div>\"}};\n",
+       "  \n",
+       "    function display_loaded() {\n",
+       "      if (window.Bokeh !== undefined) {\n",
+       "        Bokeh.$(\"#fef73c4a-6b29-41cb-82a4-92a086d2028b\").text(\"BokehJS successfully loaded.\");\n",
+       "      } else if (Date.now() < window._bokeh_timeout) {\n",
+       "        setTimeout(display_loaded, 100)\n",
+       "      }\n",
+       "    }\n",
+       "  \n",
+       "    function run_callbacks() {\n",
+       "      window._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n",
+       "      delete window._bokeh_onload_callbacks\n",
+       "      console.info(\"Bokeh: all callbacks have finished\");\n",
+       "    }\n",
+       "  \n",
+       "    function load_libs(js_urls, callback) {\n",
+       "      window._bokeh_onload_callbacks.push(callback);\n",
+       "      if (window._bokeh_is_loading > 0) {\n",
+       "        console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n",
+       "        return null;\n",
+       "      }\n",
+       "      if (js_urls == null || js_urls.length === 0) {\n",
+       "        run_callbacks();\n",
+       "        return null;\n",
+       "      }\n",
+       "      console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n",
+       "      window._bokeh_is_loading = js_urls.length;\n",
+       "      for (var i = 0; i < js_urls.length; i++) {\n",
+       "        var url = js_urls[i];\n",
+       "        var s = document.createElement('script');\n",
+       "        s.src = url;\n",
+       "        s.async = false;\n",
+       "        s.onreadystatechange = s.onload = function() {\n",
+       "          window._bokeh_is_loading--;\n",
+       "          if (window._bokeh_is_loading === 0) {\n",
+       "            console.log(\"Bokeh: all BokehJS libraries loaded\");\n",
+       "            run_callbacks()\n",
+       "          }\n",
+       "        };\n",
+       "        s.onerror = function() {\n",
+       "          console.warn(\"failed to load library \" + url);\n",
+       "        };\n",
+       "        console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n",
+       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
+       "      }\n",
+       "    };var element = document.getElementById(\"fef73c4a-6b29-41cb-82a4-92a086d2028b\");\n",
+       "    if (element == null) {\n",
+       "      console.log(\"Bokeh: ERROR: autoload.js configured with elementid 'fef73c4a-6b29-41cb-82a4-92a086d2028b' but no matching script tag was found. \")\n",
+       "      return false;\n",
+       "    }\n",
+       "  \n",
+       "    var js_urls = [];\n",
+       "  \n",
+       "    var inline_js = [\n",
+       "      function(Bokeh) {\n",
+       "        Bokeh.$(function() {\n",
+       "            var docs_json = {\"a16e3327-728c-494c-abfb-26f07d36ab3e\":{\"roots\":{\"references\":[{\"attributes\":{\"callback\":null},\"id\":\"b102966b-f813-4f4c-bc15-0fe677ee8ab2\",\"type\":\"DataRange1d\"},{\"attributes\":{\"bottom_units\":\"screen\",\"fill_alpha\":{\"value\":0.5},\"fill_color\":{\"value\":\"lightgrey\"},\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":{\"value\":1.0},\"line_color\":{\"value\":\"black\"},\"line_dash\":[4,4],\"line_width\":{\"value [...]
+       "            var render_items = [{\"docid\":\"a16e3327-728c-494c-abfb-26f07d36ab3e\",\"elementid\":\"fef73c4a-6b29-41cb-82a4-92a086d2028b\",\"modelid\":\"8c0ef61c-12ef-4d09-aca4-76876cdc83af\"}];\n",
+       "            \n",
+       "            Bokeh.embed.embed_items(docs_json, render_items);\n",
+       "        });\n",
+       "      },\n",
+       "      function(Bokeh) {\n",
+       "      }\n",
+       "    ];\n",
+       "  \n",
+       "    function run_inline_js() {\n",
+       "      \n",
+       "      if ((window.Bokeh !== undefined) || (force === \"1\")) {\n",
+       "        for (var i = 0; i < inline_js.length; i++) {\n",
+       "          inline_js[i](window.Bokeh);\n",
+       "        }if (force === \"1\") {\n",
+       "          display_loaded();\n",
+       "        }} else if (Date.now() < window._bokeh_timeout) {\n",
+       "        setTimeout(run_inline_js, 100);\n",
+       "      } else if (!window._bokeh_failed_load) {\n",
+       "        console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n",
+       "        window._bokeh_failed_load = true;\n",
+       "      } else if (!force) {\n",
+       "        var cell = $(\"#fef73c4a-6b29-41cb-82a4-92a086d2028b\").parents('.cell').data().cell;\n",
+       "        cell.output_area.append_execute_result(NB_LOAD_WARNING)\n",
+       "      }\n",
+       "  \n",
+       "    }\n",
+       "  \n",
+       "    if (window._bokeh_is_loading === 0) {\n",
+       "      console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n",
+       "      run_inline_js();\n",
+       "    } else {\n",
+       "      load_libs(js_urls, function() {\n",
+       "        console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n",
+       "        run_inline_js();\n",
+       "      });\n",
+       "    }\n",
+       "  }(this));\n",
+       "</script>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "reload(maps)\n",
+    "\n",
+    "maps.geoplot(db, col='HOVAL' ,marker_size=10, hover=True,\\\n",
+    "             backend='bk', classi='fisher_jenks', palette='OrRd')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 32,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "\n",
+       "    <div class=\"bk-root\">\n",
+       "        <div class=\"plotdiv\" id=\"62a3a8c2-3d85-4519-ab05-1b2b578f0294\"></div>\n",
+       "    </div>\n",
+       "<script type=\"text/javascript\">\n",
+       "  \n",
+       "  (function(global) {\n",
+       "    function now() {\n",
+       "      return new Date();\n",
+       "    }\n",
+       "  \n",
+       "    var force = \"\";\n",
+       "  \n",
+       "    if (typeof (window._bokeh_onload_callbacks) === \"undefined\" || force !== \"\") {\n",
+       "      window._bokeh_onload_callbacks = [];\n",
+       "      window._bokeh_is_loading = undefined;\n",
+       "    }\n",
+       "  \n",
+       "  \n",
+       "    \n",
+       "    if (typeof (window._bokeh_timeout) === \"undefined\" || force !== \"\") {\n",
+       "      window._bokeh_timeout = Date.now() + 0;\n",
+       "      window._bokeh_failed_load = false;\n",
+       "    }\n",
+       "  \n",
+       "    var NB_LOAD_WARNING = {'data': {'text/html':\n",
+       "       \"<div style='background-color: #fdd'>\\n\"+\n",
+       "       \"<p>\\n\"+\n",
+       "       \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n",
+       "       \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n",
+       "       \"</p>\\n\"+\n",
+       "       \"<ul>\\n\"+\n",
+       "       \"<li>re-rerun `output_notebook()` to attempt to load from CDN again, or</li>\\n\"+\n",
+       "       \"<li>use INLINE resources instead, as so:</li>\\n\"+\n",
+       "       \"</ul>\\n\"+\n",
+       "       \"<code>\\n\"+\n",
+       "       \"from bokeh.resources import INLINE\\n\"+\n",
+       "       \"output_notebook(resources=INLINE)\\n\"+\n",
+       "       \"</code>\\n\"+\n",
+       "       \"</div>\"}};\n",
+       "  \n",
+       "    function display_loaded() {\n",
+       "      if (window.Bokeh !== undefined) {\n",
+       "        Bokeh.$(\"#62a3a8c2-3d85-4519-ab05-1b2b578f0294\").text(\"BokehJS successfully loaded.\");\n",
+       "      } else if (Date.now() < window._bokeh_timeout) {\n",
+       "        setTimeout(display_loaded, 100)\n",
+       "      }\n",
+       "    }\n",
+       "  \n",
+       "    function run_callbacks() {\n",
+       "      window._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n",
+       "      delete window._bokeh_onload_callbacks\n",
+       "      console.info(\"Bokeh: all callbacks have finished\");\n",
+       "    }\n",
+       "  \n",
+       "    function load_libs(js_urls, callback) {\n",
+       "      window._bokeh_onload_callbacks.push(callback);\n",
+       "      if (window._bokeh_is_loading > 0) {\n",
+       "        console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n",
+       "        return null;\n",
+       "      }\n",
+       "      if (js_urls == null || js_urls.length === 0) {\n",
+       "        run_callbacks();\n",
+       "        return null;\n",
+       "      }\n",
+       "      console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n",
+       "      window._bokeh_is_loading = js_urls.length;\n",
+       "      for (var i = 0; i < js_urls.length; i++) {\n",
+       "        var url = js_urls[i];\n",
+       "        var s = document.createElement('script');\n",
+       "        s.src = url;\n",
+       "        s.async = false;\n",
+       "        s.onreadystatechange = s.onload = function() {\n",
+       "          window._bokeh_is_loading--;\n",
+       "          if (window._bokeh_is_loading === 0) {\n",
+       "            console.log(\"Bokeh: all BokehJS libraries loaded\");\n",
+       "            run_callbacks()\n",
+       "          }\n",
+       "        };\n",
+       "        s.onerror = function() {\n",
+       "          console.warn(\"failed to load library \" + url);\n",
+       "        };\n",
+       "        console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n",
+       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
+       "      }\n",
+       "    };var element = document.getElementById(\"62a3a8c2-3d85-4519-ab05-1b2b578f0294\");\n",
+       "    if (element == null) {\n",
+       "      console.log(\"Bokeh: ERROR: autoload.js configured with elementid '62a3a8c2-3d85-4519-ab05-1b2b578f0294' but no matching script tag was found. \")\n",
+       "      return false;\n",
+       "    }\n",
+       "  \n",
+       "    var js_urls = [];\n",
+       "  \n",
+       "    var inline_js = [\n",
+       "      function(Bokeh) {\n",
+       "        Bokeh.$(function() {\n",
+       "            var docs_json = {\"a5d045cb-7cac-4e32-be90-7945abbd4e80\":{\"roots\":{\"references\":[{\"attributes\":{},\"id\":\"5723fa5b-2e4b-4d7d-a8f8-89c97452bd27\",\"type\":\"BasicTicker\"},{\"attributes\":{\"plot\":{\"id\":\"0b4ce831-1a2c-47f4-b3f7-2b1d2c0d3a76\",\"subtype\":\"Figure\",\"type\":\"Plot\"}},\"id\":\"15f6ced5-a29e-4945-9f31-f0f1352f90bd\",\"type\":\"PanTool\"},{\"attributes\":{\"renderers\":[{\"id\":\"dfee9f00-05ec-4774-9632-b829ff610477\",\"type\":\"Grid\"},{\"id [...]
+       "            var render_items = [{\"docid\":\"a5d045cb-7cac-4e32-be90-7945abbd4e80\",\"elementid\":\"62a3a8c2-3d85-4519-ab05-1b2b578f0294\",\"modelid\":\"0b4ce831-1a2c-47f4-b3f7-2b1d2c0d3a76\"}];\n",
+       "            \n",
+       "            Bokeh.embed.embed_items(docs_json, render_items);\n",
+       "        });\n",
+       "      },\n",
+       "      function(Bokeh) {\n",
+       "      }\n",
+       "    ];\n",
+       "  \n",
+       "    function run_inline_js() {\n",
+       "      \n",
+       "      if ((window.Bokeh !== undefined) || (force === \"1\")) {\n",
+       "        for (var i = 0; i < inline_js.length; i++) {\n",
+       "          inline_js[i](window.Bokeh);\n",
+       "        }if (force === \"1\") {\n",
+       "          display_loaded();\n",
+       "        }} else if (Date.now() < window._bokeh_timeout) {\n",
+       "        setTimeout(run_inline_js, 100);\n",
+       "      } else if (!window._bokeh_failed_load) {\n",
+       "        console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n",
+       "        window._bokeh_failed_load = true;\n",
+       "      } else if (!force) {\n",
+       "        var cell = $(\"#62a3a8c2-3d85-4519-ab05-1b2b578f0294\").parents('.cell').data().cell;\n",
+       "        cell.output_area.append_execute_result(NB_LOAD_WARNING)\n",
+       "      }\n",
+       "  \n",
+       "    }\n",
+       "  \n",
+       "    if (window._bokeh_is_loading === 0) {\n",
+       "      console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n",
+       "      run_inline_js();\n",
+       "    } else {\n",
+       "      load_libs(js_urls, function() {\n",
+       "        console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n",
+       "        run_inline_js();\n",
+       "      });\n",
+       "    }\n",
+       "  }(this));\n",
+       "</script>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "reload(maps)\n",
+    "\n",
+    "maps.geoplot(db, col='HOVAL' ,marker_size=10, hover=True,\\\n",
+    "             backend='bk', classi='fisher_jenks', palette='OrRd',\\\n",
+    "             tips = ['CRIME']\n",
+    "            )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "\n",
+       "    <div class=\"bk-root\">\n",
+       "        <div class=\"plotdiv\" id=\"65df6188-9607-4c6a-9183-3b735acea306\"></div>\n",
+       "    </div>\n",
+       "<script type=\"text/javascript\">\n",
+       "  \n",
+       "  (function(global) {\n",
+       "    function now() {\n",
+       "      return new Date();\n",
+       "    }\n",
+       "  \n",
+       "    var force = \"\";\n",
+       "  \n",
+       "    if (typeof (window._bokeh_onload_callbacks) === \"undefined\" || force !== \"\") {\n",
+       "      window._bokeh_onload_callbacks = [];\n",
+       "      window._bokeh_is_loading = undefined;\n",
+       "    }\n",
+       "  \n",
+       "  \n",
+       "    \n",
+       "    if (typeof (window._bokeh_timeout) === \"undefined\" || force !== \"\") {\n",
+       "      window._bokeh_timeout = Date.now() + 0;\n",
+       "      window._bokeh_failed_load = false;\n",
+       "    }\n",
+       "  \n",
+       "    var NB_LOAD_WARNING = {'data': {'text/html':\n",
+       "       \"<div style='background-color: #fdd'>\\n\"+\n",
+       "       \"<p>\\n\"+\n",
+       "       \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n",
+       "       \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n",
+       "       \"</p>\\n\"+\n",
+       "       \"<ul>\\n\"+\n",
+       "       \"<li>re-rerun `output_notebook()` to attempt to load from CDN again, or</li>\\n\"+\n",
+       "       \"<li>use INLINE resources instead, as so:</li>\\n\"+\n",
+       "       \"</ul>\\n\"+\n",
+       "       \"<code>\\n\"+\n",
+       "       \"from bokeh.resources import INLINE\\n\"+\n",
+       "       \"output_notebook(resources=INLINE)\\n\"+\n",
+       "       \"</code>\\n\"+\n",
+       "       \"</div>\"}};\n",
+       "  \n",
+       "    function display_loaded() {\n",
+       "      if (window.Bokeh !== undefined) {\n",
+       "        Bokeh.$(\"#65df6188-9607-4c6a-9183-3b735acea306\").text(\"BokehJS successfully loaded.\");\n",
+       "      } else if (Date.now() < window._bokeh_timeout) {\n",
+       "        setTimeout(display_loaded, 100)\n",
+       "      }\n",
+       "    }\n",
+       "  \n",
+       "    function run_callbacks() {\n",
+       "      window._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n",
+       "      delete window._bokeh_onload_callbacks\n",
+       "      console.info(\"Bokeh: all callbacks have finished\");\n",
+       "    }\n",
+       "  \n",
+       "    function load_libs(js_urls, callback) {\n",
+       "      window._bokeh_onload_callbacks.push(callback);\n",
+       "      if (window._bokeh_is_loading > 0) {\n",
+       "        console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n",
+       "        return null;\n",
+       "      }\n",
+       "      if (js_urls == null || js_urls.length === 0) {\n",
+       "        run_callbacks();\n",
+       "        return null;\n",
+       "      }\n",
+       "      console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n",
+       "      window._bokeh_is_loading = js_urls.length;\n",
+       "      for (var i = 0; i < js_urls.length; i++) {\n",
+       "        var url = js_urls[i];\n",
+       "        var s = document.createElement('script');\n",
+       "        s.src = url;\n",
+       "        s.async = false;\n",
+       "        s.onreadystatechange = s.onload = function() {\n",
+       "          window._bokeh_is_loading--;\n",
+       "          if (window._bokeh_is_loading === 0) {\n",
+       "            console.log(\"Bokeh: all BokehJS libraries loaded\");\n",
+       "            run_callbacks()\n",
+       "          }\n",
+       "        };\n",
+       "        s.onerror = function() {\n",
+       "          console.warn(\"failed to load library \" + url);\n",
+       "        };\n",
+       "        console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n",
+       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
+       "      }\n",
+       "    };var element = document.getElementById(\"65df6188-9607-4c6a-9183-3b735acea306\");\n",
+       "    if (element == null) {\n",
+       "      console.log(\"Bokeh: ERROR: autoload.js configured with elementid '65df6188-9607-4c6a-9183-3b735acea306' but no matching script tag was found. \")\n",
+       "      return false;\n",
+       "    }\n",
+       "  \n",
+       "    var js_urls = [];\n",
+       "  \n",
+       "    var inline_js = [\n",
+       "      function(Bokeh) {\n",
+       "        Bokeh.$(function() {\n",
+       "            var docs_json = {\"63d4556a-22f0-456d-9894-50f976ee0763\":{\"roots\":{\"references\":[{\"attributes\":{\"data_source\":{\"id\":\"8b737a33-1069-4b88-9e85-eccad4f19fa8\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"d8804f69-de09-40c6-9d7a-f88cc5ccf599\",\"type\":\"Patches\"},\"hover_glyph\":null,\"nonselection_glyph\":{\"id\":\"72303ffb-35f8-425e-9ba2-8e5e6cd27d8d\",\"type\":\"Patches\"},\"selection_glyph\":null},\"id\":\"af1dba98-35e9-4d12-9f9b-d80391ace4b5\",\"t [...]
+       "            var render_items = [{\"docid\":\"63d4556a-22f0-456d-9894-50f976ee0763\",\"elementid\":\"65df6188-9607-4c6a-9183-3b735acea306\",\"modelid\":\"c09d27c4-d2eb-449d-b6e4-ff8e9aa5fab6\"}];\n",
+       "            \n",
+       "            Bokeh.embed.embed_items(docs_json, render_items);\n",
+       "        });\n",
+       "      },\n",
+       "      function(Bokeh) {\n",
+       "      }\n",
+       "    ];\n",
+       "  \n",
+       "    function run_inline_js() {\n",
+       "      \n",
+       "      if ((window.Bokeh !== undefined) || (force === \"1\")) {\n",
+       "        for (var i = 0; i < inline_js.length; i++) {\n",
+       "          inline_js[i](window.Bokeh);\n",
+       "        }if (force === \"1\") {\n",
+       "          display_loaded();\n",
+       "        }} else if (Date.now() < window._bokeh_timeout) {\n",
+       "        setTimeout(run_inline_js, 100);\n",
+       "      } else if (!window._bokeh_failed_load) {\n",
+       "        console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n",
+       "        window._bokeh_failed_load = true;\n",
+       "      } else if (!force) {\n",
+       "        var cell = $(\"#65df6188-9607-4c6a-9183-3b735acea306\").parents('.cell').data().cell;\n",
+       "        cell.output_area.append_execute_result(NB_LOAD_WARNING)\n",
+       "      }\n",
+       "  \n",
+       "    }\n",
+       "  \n",
+       "    if (window._bokeh_is_loading === 0) {\n",
+       "      console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n",
+       "      run_inline_js();\n",
+       "    } else {\n",
+       "      load_libs(js_urls, function() {\n",
+       "        console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n",
+       "        run_inline_js();\n",
+       "      });\n",
+       "    }\n",
+       "  }(this));\n",
+       "</script>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "reload(maps)\n",
+    "\n",
+    "maps.geoplot(db, col='CRIME' ,marker_size=10, hover=True,\\\n",
+    "             backend='bk', classi='fisher_jenks', palette='OrRd',\\\n",
+    "             tips = ['HOVAL']\n",
+    "            )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [],
+   "source": [
+    "gc = db['geometry']\n",
+    "patch_xs = []\n",
+    "patch_ys = []\n",
+    "ids = []\n",
+    "for idx, shape in gc.iteritems():\n",
+    "    for ring in shape.parts:\n",
+    "        xs, ys = zip(*ring)\n",
+    "        patch_xs.append(xs)\n",
+    "        patch_ys.append(ys)\n",
+    "        ids.append(idx)\n",
+    "cds = ColumnDataSource(data=dict(\n",
+    "            x=patch_xs,\n",
+    "            y=patch_ys\n",
+    "            ))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 35,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "\n",
+       "    <div class=\"bk-root\">\n",
+       "        <div class=\"plotdiv\" id=\"09793e44-6af8-4e3e-99ea-ac4d131a598e\"></div>\n",
+       "    </div>\n",
+       "<script type=\"text/javascript\">\n",
+       "  \n",
+       "  (function(global) {\n",
+       "    function now() {\n",
+       "      return new Date();\n",
+       "    }\n",
+       "  \n",
+       "    var force = \"\";\n",
+       "  \n",
+       "    if (typeof (window._bokeh_onload_callbacks) === \"undefined\" || force !== \"\") {\n",
+       "      window._bokeh_onload_callbacks = [];\n",
+       "      window._bokeh_is_loading = undefined;\n",
+       "    }\n",
+       "  \n",
+       "  \n",
+       "    \n",
+       "    if (typeof (window._bokeh_timeout) === \"undefined\" || force !== \"\") {\n",
+       "      window._bokeh_timeout = Date.now() + 0;\n",
+       "      window._bokeh_failed_load = false;\n",
+       "    }\n",
+       "  \n",
+       "    var NB_LOAD_WARNING = {'data': {'text/html':\n",
+       "       \"<div style='background-color: #fdd'>\\n\"+\n",
+       "       \"<p>\\n\"+\n",
+       "       \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n",
+       "       \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n",
+       "       \"</p>\\n\"+\n",
+       "       \"<ul>\\n\"+\n",
+       "       \"<li>re-rerun `output_notebook()` to attempt to load from CDN again, or</li>\\n\"+\n",
+       "       \"<li>use INLINE resources instead, as so:</li>\\n\"+\n",
+       "       \"</ul>\\n\"+\n",
+       "       \"<code>\\n\"+\n",
+       "       \"from bokeh.resources import INLINE\\n\"+\n",
+       "       \"output_notebook(resources=INLINE)\\n\"+\n",
+       "       \"</code>\\n\"+\n",
+       "       \"</div>\"}};\n",
+       "  \n",
+       "    function display_loaded() {\n",
+       "      if (window.Bokeh !== undefined) {\n",
+       "        Bokeh.$(\"#09793e44-6af8-4e3e-99ea-ac4d131a598e\").text(\"BokehJS successfully loaded.\");\n",
+       "      } else if (Date.now() < window._bokeh_timeout) {\n",
+       "        setTimeout(display_loaded, 100)\n",
+       "      }\n",
+       "    }\n",
+       "  \n",
+       "    function run_callbacks() {\n",
+       "      window._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n",
+       "      delete window._bokeh_onload_callbacks\n",
+       "      console.info(\"Bokeh: all callbacks have finished\");\n",
+       "    }\n",
+       "  \n",
+       "    function load_libs(js_urls, callback) {\n",
+       "      window._bokeh_onload_callbacks.push(callback);\n",
+       "      if (window._bokeh_is_loading > 0) {\n",
+       "        console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n",
+       "        return null;\n",
+       "      }\n",
+       "      if (js_urls == null || js_urls.length === 0) {\n",
+       "        run_callbacks();\n",
+       "        return null;\n",
+       "      }\n",
+       "      console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n",
+       "      window._bokeh_is_loading = js_urls.length;\n",
+       "      for (var i = 0; i < js_urls.length; i++) {\n",
+       "        var url = js_urls[i];\n",
+       "        var s = document.createElement('script');\n",
+       "        s.src = url;\n",
+       "        s.async = false;\n",
+       "        s.onreadystatechange = s.onload = function() {\n",
+       "          window._bokeh_is_loading--;\n",
+       "          if (window._bokeh_is_loading === 0) {\n",
+       "            console.log(\"Bokeh: all BokehJS libraries loaded\");\n",
+       "            run_callbacks()\n",
+       "          }\n",
+       "        };\n",
+       "        s.onerror = function() {\n",
+       "          console.warn(\"failed to load library \" + url);\n",
+       "        };\n",
+       "        console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n",
+       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
+       "      }\n",
+       "    };var element = document.getElementById(\"09793e44-6af8-4e3e-99ea-ac4d131a598e\");\n",
+       "    if (element == null) {\n",
+       "      console.log(\"Bokeh: ERROR: autoload.js configured with elementid '09793e44-6af8-4e3e-99ea-ac4d131a598e' but no matching script tag was found. \")\n",
+       "      return false;\n",
+       "    }\n",
+       "  \n",
+       "    var js_urls = [];\n",
+       "  \n",
+       "    var inline_js = [\n",
+       "      function(Bokeh) {\n",
+       "        Bokeh.$(function() {\n",
+       "            var docs_json = {\"6c33bb76-76dc-489f-bd9b-f42668602537\":{\"roots\":{\"references\":[{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"line_width\":{\"value\":0.5},\"xs\":{\"field\":\"x\"},\"ys\":{\"field\":\"y\"}},\"id\":\"01ee439a-23e1-4062-904d-931a2322ab97\",\"type\":\"Patches\"},{\"attributes\":{\"active_drag\":\"auto\",\"active_scroll\":\"auto\",\"active [...]
+       "            var render_items = [{\"docid\":\"6c33bb76-76dc-489f-bd9b-f42668602537\",\"elementid\":\"09793e44-6af8-4e3e-99ea-ac4d131a598e\",\"modelid\":\"2ed7bee7-40f9-435a-8ea9-6a05a1bc4734\"}];\n",
+       "            \n",
+       "            Bokeh.embed.embed_items(docs_json, render_items);\n",
+       "        });\n",
+       "      },\n",
+       "      function(Bokeh) {\n",
+       "      }\n",
+       "    ];\n",
+       "  \n",
+       "    function run_inline_js() {\n",
+       "      \n",
+       "      if ((window.Bokeh !== undefined) || (force === \"1\")) {\n",
+       "        for (var i = 0; i < inline_js.length; i++) {\n",
+       "          inline_js[i](window.Bokeh);\n",
+       "        }if (force === \"1\") {\n",
+       "          display_loaded();\n",
+       "        }} else if (Date.now() < window._bokeh_timeout) {\n",
+       "        setTimeout(run_inline_js, 100);\n",
+       "      } else if (!window._bokeh_failed_load) {\n",
+       "        console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n",
+       "        window._bokeh_failed_load = true;\n",
+       "      } else if (!force) {\n",
+       "        var cell = $(\"#09793e44-6af8-4e3e-99ea-ac4d131a598e\").parents('.cell').data().cell;\n",
+       "        cell.output_area.append_execute_result(NB_LOAD_WARNING)\n",
+       "      }\n",
+       "  \n",
+       "    }\n",
+       "  \n",
+       "    if (window._bokeh_is_loading === 0) {\n",
+       "      console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n",
+       "      run_inline_js();\n",
+       "    } else {\n",
+       "      load_libs(js_urls, function() {\n",
+       "        console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n",
+       "        run_inline_js();\n",
+       "      });\n",
+       "    }\n",
+       "  }(this));\n",
+       "</script>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "TOOLS=\"pan,wheel_zoom,box_zoom,reset,hover\"\n",
+    "p = figure(tools=TOOLS, x_axis_location=None, y_axis_location=None)\n",
+    "p.grid.grid_line_color = None\n",
+    "\n",
+    "p.patches('x', 'y', source=cds,\n",
+    "  fill_alpha=1.,\n",
+    "  line_color='black', \n",
+    "  line_width=0.5\n",
+    "  )\n",
+    "\n",
+    "show(p)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 36,
+   "metadata": {
+    "collapsed": false,
+    "scrolled": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "\n",
+       "    <div class=\"bk-root\">\n",
+       "        <div class=\"plotdiv\" id=\"08cd2e3a-f387-466d-b13f-960fbcc5194c\"></div>\n",
+       "    </div>\n",
+       "<script type=\"text/javascript\">\n",
+       "  \n",
+       "  (function(global) {\n",
+       "    function now() {\n",
+       "      return new Date();\n",
+       "    }\n",
+       "  \n",
+       "    var force = \"\";\n",
+       "  \n",
+       "    if (typeof (window._bokeh_onload_callbacks) === \"undefined\" || force !== \"\") {\n",
+       "      window._bokeh_onload_callbacks = [];\n",
+       "      window._bokeh_is_loading = undefined;\n",
+       "    }\n",
+       "  \n",
+       "  \n",
+       "    \n",
+       "    if (typeof (window._bokeh_timeout) === \"undefined\" || force !== \"\") {\n",
+       "      window._bokeh_timeout = Date.now() + 0;\n",
+       "      window._bokeh_failed_load = false;\n",
+       "    }\n",
+       "  \n",
+       "    var NB_LOAD_WARNING = {'data': {'text/html':\n",
+       "       \"<div style='background-color: #fdd'>\\n\"+\n",
+       "       \"<p>\\n\"+\n",
+       "       \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n",
+       "       \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n",
+       "       \"</p>\\n\"+\n",
+       "       \"<ul>\\n\"+\n",
+       "       \"<li>re-rerun `output_notebook()` to attempt to load from CDN again, or</li>\\n\"+\n",
+       "       \"<li>use INLINE resources instead, as so:</li>\\n\"+\n",
+       "       \"</ul>\\n\"+\n",
+       "       \"<code>\\n\"+\n",
+       "       \"from bokeh.resources import INLINE\\n\"+\n",
+       "       \"output_notebook(resources=INLINE)\\n\"+\n",
+       "       \"</code>\\n\"+\n",
+       "       \"</div>\"}};\n",
+       "  \n",
+       "    function display_loaded() {\n",
+       "      if (window.Bokeh !== undefined) {\n",
+       "        Bokeh.$(\"#08cd2e3a-f387-466d-b13f-960fbcc5194c\").text(\"BokehJS successfully loaded.\");\n",
+       "      } else if (Date.now() < window._bokeh_timeout) {\n",
+       "        setTimeout(display_loaded, 100)\n",
+       "      }\n",
+       "    }\n",
+       "  \n",
+       "    function run_callbacks() {\n",
+       "      window._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n",
+       "      delete window._bokeh_onload_callbacks\n",
+       "      console.info(\"Bokeh: all callbacks have finished\");\n",
+       "    }\n",
+       "  \n",
+       "    function load_libs(js_urls, callback) {\n",
+       "      window._bokeh_onload_callbacks.push(callback);\n",
+       "      if (window._bokeh_is_loading > 0) {\n",
+       "        console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n",
+       "        return null;\n",
+       "      }\n",
+       "      if (js_urls == null || js_urls.length === 0) {\n",
+       "        run_callbacks();\n",
+       "        return null;\n",
+       "      }\n",
+       "      console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n",
+       "      window._bokeh_is_loading = js_urls.length;\n",
+       "      for (var i = 0; i < js_urls.length; i++) {\n",
+       "        var url = js_urls[i];\n",
+       "        var s = document.createElement('script');\n",
+       "        s.src = url;\n",
+       "        s.async = false;\n",
+       "        s.onreadystatechange = s.onload = function() {\n",
+       "          window._bokeh_is_loading--;\n",
+       "          if (window._bokeh_is_loading === 0) {\n",
+       "            console.log(\"Bokeh: all BokehJS libraries loaded\");\n",
+       "            run_callbacks()\n",
+       "          }\n",
+       "        };\n",
+       "        s.onerror = function() {\n",
+       "          console.warn(\"failed to load library \" + url);\n",
+       "        };\n",
+       "        console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n",
+       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
+       "      }\n",
+       "    };var element = document.getElementById(\"08cd2e3a-f387-466d-b13f-960fbcc5194c\");\n",
+       "    if (element == null) {\n",
+       "      console.log(\"Bokeh: ERROR: autoload.js configured with elementid '08cd2e3a-f387-466d-b13f-960fbcc5194c' but no matching script tag was found. \")\n",
+       "      return false;\n",
+       "    }\n",
+       "  \n",
+       "    var js_urls = [];\n",
+       "  \n",
+       "    var inline_js = [\n",
+       "      function(Bokeh) {\n",
+       "        Bokeh.$(function() {\n",
+       "            var docs_json = {\"953579a2-0a4b-445c-b739-358c4a4635e9\":{\"roots\":{\"references\":[{\"attributes\":{\"renderers\":[{\"id\":\"ebc2ed1b-3e2a-4b11-82e8-4d64b97e77ee\",\"type\":\"Grid\"},{\"id\":\"f9c1b768-8e68-41e7-960d-f0748948f36a\",\"type\":\"Grid\"},{\"id\":\"a0578d07-1c38-4cf4-8f52-2588761f5a5d\",\"type\":\"BoxAnnotation\"},{\"id\":\"9c796007-2445-450e-80e6-f032643ff4b5\",\"type\":\"GlyphRenderer\"}],\"title\":{\"id\":\"c6c58abf-6bf3-4a7d-a73d-a0dd4ea7234a\",\"ty [...]
+       "            var render_items = [{\"docid\":\"953579a2-0a4b-445c-b739-358c4a4635e9\",\"elementid\":\"08cd2e3a-f387-466d-b13f-960fbcc5194c\",\"modelid\":\"d4b542f9-2095-43b7-8366-074f86a3d727\"}];\n",
+       "            \n",
+       "            Bokeh.embed.embed_items(docs_json, render_items);\n",
+       "        });\n",
+       "      },\n",
+       "      function(Bokeh) {\n",
+       "      }\n",
+       "    ];\n",
+       "  \n",
+       "    function run_inline_js() {\n",
+       "      \n",
+       "      if ((window.Bokeh !== undefined) || (force === \"1\")) {\n",
+       "        for (var i = 0; i < inline_js.length; i++) {\n",
+       "          inline_js[i](window.Bokeh);\n",
+       "        }if (force === \"1\") {\n",
+       "          display_loaded();\n",
+       "        }} else if (Date.now() < window._bokeh_timeout) {\n",
+       "        setTimeout(run_inline_js, 100);\n",
+       "      } else if (!window._bokeh_failed_load) {\n",
+       "        console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n",
+       "        window._bokeh_failed_load = true;\n",
+       "      } else if (!force) {\n",
+       "        var cell = $(\"#08cd2e3a-f387-466d-b13f-960fbcc5194c\").parents('.cell').data().cell;\n",
+       "        cell.output_area.append_execute_result(NB_LOAD_WARNING)\n",
+       "      }\n",
+       "  \n",
+       "    }\n",
+       "  \n",
+       "    if (window._bokeh_is_loading === 0) {\n",
+       "      console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n",
+       "      run_inline_js();\n",
+       "    } else {\n",
+       "      load_libs(js_urls, function() {\n",
+       "        console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n",
+       "        run_inline_js();\n",
+       "      });\n",
+       "    }\n",
+       "  }(this));\n",
+       "</script>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "\n",
+    "maps.plot_geocol_bk(db.loc[:, 'geometry'], linewidth=10, facecolor=colors)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 37,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "\n",
+       "    <div class=\"bk-root\">\n",
+       "        <div class=\"plotdiv\" id=\"2538d759-4c7f-4e33-aa39-f76d4fa19732\"></div>\n",
+       "    </div>\n",
+       "<script type=\"text/javascript\">\n",
+       "  \n",
+       "  (function(global) {\n",
+       "    function now() {\n",
+       "      return new Date();\n",
+       "    }\n",
+       "  \n",
+       "    var force = \"\";\n",
+       "  \n",
+       "    if (typeof (window._bokeh_onload_callbacks) === \"undefined\" || force !== \"\") {\n",
+       "      window._bokeh_onload_callbacks = [];\n",
+       "      window._bokeh_is_loading = undefined;\n",
+       "    }\n",
+       "  \n",
+       "  \n",
+       "    \n",
+       "    if (typeof (window._bokeh_timeout) === \"undefined\" || force !== \"\") {\n",
+       "      window._bokeh_timeout = Date.now() + 0;\n",
+       "      window._bokeh_failed_load = false;\n",
+       "    }\n",
+       "  \n",
+       "    var NB_LOAD_WARNING = {'data': {'text/html':\n",
+       "       \"<div style='background-color: #fdd'>\\n\"+\n",
+       "       \"<p>\\n\"+\n",
+       "       \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n",
+       "       \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n",
+       "       \"</p>\\n\"+\n",
+       "       \"<ul>\\n\"+\n",
+       "       \"<li>re-rerun `output_notebook()` to attempt to load from CDN again, or</li>\\n\"+\n",
+       "       \"<li>use INLINE resources instead, as so:</li>\\n\"+\n",
+       "       \"</ul>\\n\"+\n",
+       "       \"<code>\\n\"+\n",
+       "       \"from bokeh.resources import INLINE\\n\"+\n",
+       "       \"output_notebook(resources=INLINE)\\n\"+\n",
+       "       \"</code>\\n\"+\n",
+       "       \"</div>\"}};\n",
+       "  \n",
+       "    function display_loaded() {\n",
+       "      if (window.Bokeh !== undefined) {\n",
+       "        Bokeh.$(\"#2538d759-4c7f-4e33-aa39-f76d4fa19732\").text(\"BokehJS successfully loaded.\");\n",
+       "      } else if (Date.now() < window._bokeh_timeout) {\n",
+       "        setTimeout(display_loaded, 100)\n",
+       "      }\n",
+       "    }\n",
+       "  \n",
+       "    function run_callbacks() {\n",
+       "      window._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n",
+       "      delete window._bokeh_onload_callbacks\n",
+       "      console.info(\"Bokeh: all callbacks have finished\");\n",
+       "    }\n",
+       "  \n",
+       "    function load_libs(js_urls, callback) {\n",
+       "      window._bokeh_onload_callbacks.push(callback);\n",
+       "      if (window._bokeh_is_loading > 0) {\n",
+       "        console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n",
+       "        return null;\n",
+       "      }\n",
+       "      if (js_urls == null || js_urls.length === 0) {\n",
+       "        run_callbacks();\n",
+       "        return null;\n",
+       "      }\n",
+       "      console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n",
+       "      window._bokeh_is_loading = js_urls.length;\n",
+       "      for (var i = 0; i < js_urls.length; i++) {\n",
+       "        var url = js_urls[i];\n",
+       "        var s = document.createElement('script');\n",
+       "        s.src = url;\n",
+       "        s.async = false;\n",
+       "        s.onreadystatechange = s.onload = function() {\n",
+       "          window._bokeh_is_loading--;\n",
+       "          if (window._bokeh_is_loading === 0) {\n",
+       "            console.log(\"Bokeh: all BokehJS libraries loaded\");\n",
+       "            run_callbacks()\n",
+       "          }\n",
+       "        };\n",
+       "        s.onerror = function() {\n",
+       "          console.warn(\"failed to load library \" + url);\n",
+       "        };\n",
+       "        console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n",
+       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
+       "      }\n",
+       "    };var element = document.getElementById(\"2538d759-4c7f-4e33-aa39-f76d4fa19732\");\n",
+       "    if (element == null) {\n",
+       "      console.log(\"Bokeh: ERROR: autoload.js configured with elementid '2538d759-4c7f-4e33-aa39-f76d4fa19732' but no matching script tag was found. \")\n",
+       "      return false;\n",
+       "    }\n",
+       "  \n",
+       "    var js_urls = [];\n",
+       "  \n",
+       "    var inline_js = [\n",
+       "      function(Bokeh) {\n",
+       "        Bokeh.$(function() {\n",
+       "            var docs_json = {\"72f4d345-3816-4bdb-a088-daee5bfd4aff\":{\"roots\":{\"references\":[{\"attributes\":{\"renderers\":[{\"id\":\"2e24d76b-af0d-4b1d-9678-f1cfd1cb0109\",\"type\":\"Grid\"},{\"id\":\"212148ba-ab29-488b-9783-ca663ed8936b\",\"type\":\"Grid\"},{\"id\":\"a52b8b06-c01c-4ddf-a44c-14b563b19432\",\"type\":\"BoxAnnotation\"},{\"id\":\"13b77016-97cb-43e4-bafe-d5bf956cdbaf\",\"type\":\"GlyphRenderer\"}],\"title\":{\"id\":\"0bbff6b9-7432-4575-a42d-c5ecc54d6c97\",\"ty [...]
+       "            var render_items = [{\"docid\":\"72f4d345-3816-4bdb-a088-daee5bfd4aff\",\"elementid\":\"2538d759-4c7f-4e33-aa39-f76d4fa19732\",\"modelid\":\"08bb6e82-932e-452a-a75d-fb495de35b0d\"}];\n",
+       "            \n",
+       "            Bokeh.embed.embed_items(docs_json, render_items);\n",
+       "        });\n",
+       "      },\n",
+       "      function(Bokeh) {\n",
+       "      }\n",
+       "    ];\n",
+       "  \n",
+       "    function run_inline_js() {\n",
+       "      \n",
+       "      if ((window.Bokeh !== undefined) || (force === \"1\")) {\n",
+       "        for (var i = 0; i < inline_js.length; i++) {\n",
+       "          inline_js[i](window.Bokeh);\n",
+       "        }if (force === \"1\") {\n",
+       "          display_loaded();\n",
+       "        }} else if (Date.now() < window._bokeh_timeout) {\n",
+       "        setTimeout(run_inline_js, 100);\n",
+       "      } else if (!window._bokeh_failed_load) {\n",
+       "        console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n",
+       "        window._bokeh_failed_load = true;\n",
+       "      } else if (!force) {\n",
+       "        var cell = $(\"#2538d759-4c7f-4e33-aa39-f76d4fa19732\").parents('.cell').data().cell;\n",
+       "        cell.output_area.append_execute_result(NB_LOAD_WARNING)\n",
+       "      }\n",
+       "  \n",
+       "    }\n",
+       "  \n",
+       "    if (window._bokeh_is_loading === 0) {\n",
+       "      console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n",
+       "      run_inline_js();\n",
+       "    } else {\n",
+       "      load_libs(js_urls, function() {\n",
+       "        console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n",
+       "        run_inline_js();\n",
+       "      });\n",
+       "    }\n",
+       "  }(this));\n",
+       "</script>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "TOOLS=\"pan,wheel_zoom,box_zoom,reset,hover\"\n",
+    "p = figure(tools=TOOLS, x_axis_location=None, y_axis_location=None)\n",
+    "p.grid.grid_line_color = None\n",
+    "\n",
+    "p.patches('x', 'y', source=cds,\n",
+    "  fill_alpha=1.,\n",
+    "  line_color='black', \n",
+    "  line_width=0.5\n",
+    "  )\n",
+    "\n",
+    "show(p)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 38,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "\n",
+       "    <div class=\"bk-root\">\n",
+       "        <div class=\"plotdiv\" id=\"0c5ea6a9-e3a5-4e96-b637-192bd20b9f1d\"></div>\n",
+       "    </div>\n",
+       "<script type=\"text/javascript\">\n",
+       "  \n",
+       "  (function(global) {\n",
+       "    function now() {\n",
+       "      return new Date();\n",
+       "    }\n",
+       "  \n",
+       "    var force = \"\";\n",
+       "  \n",
+       "    if (typeof (window._bokeh_onload_callbacks) === \"undefined\" || force !== \"\") {\n",
+       "      window._bokeh_onload_callbacks = [];\n",
+       "      window._bokeh_is_loading = undefined;\n",
+       "    }\n",
+       "  \n",
+       "  \n",
+       "    \n",
+       "    if (typeof (window._bokeh_timeout) === \"undefined\" || force !== \"\") {\n",
+       "      window._bokeh_timeout = Date.now() + 0;\n",
+       "      window._bokeh_failed_load = false;\n",
+       "    }\n",
+       "  \n",
+       "    var NB_LOAD_WARNING = {'data': {'text/html':\n",
+       "       \"<div style='background-color: #fdd'>\\n\"+\n",
+       "       \"<p>\\n\"+\n",
+       "       \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n",
+       "       \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n",
+       "       \"</p>\\n\"+\n",
+       "       \"<ul>\\n\"+\n",
+       "       \"<li>re-rerun `output_notebook()` to attempt to load from CDN again, or</li>\\n\"+\n",
+       "       \"<li>use INLINE resources instead, as so:</li>\\n\"+\n",
+       "       \"</ul>\\n\"+\n",
+       "       \"<code>\\n\"+\n",
+       "       \"from bokeh.resources import INLINE\\n\"+\n",
+       "       \"output_notebook(resources=INLINE)\\n\"+\n",
+       "       \"</code>\\n\"+\n",
+       "       \"</div>\"}};\n",
+       "  \n",
+       "    function display_loaded() {\n",
+       "      if (window.Bokeh !== undefined) {\n",
+       "        Bokeh.$(\"#0c5ea6a9-e3a5-4e96-b637-192bd20b9f1d\").text(\"BokehJS successfully loaded.\");\n",
+       "      } else if (Date.now() < window._bokeh_timeout) {\n",
+       "        setTimeout(display_loaded, 100)\n",
+       "      }\n",
+       "    }\n",
+       "  \n",
+       "    function run_callbacks() {\n",
+       "      window._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n",
+       "      delete window._bokeh_onload_callbacks\n",
+       "      console.info(\"Bokeh: all callbacks have finished\");\n",
+       "    }\n",
+       "  \n",
+       "    function load_libs(js_urls, callback) {\n",
+       "      window._bokeh_onload_callbacks.push(callback);\n",
+       "      if (window._bokeh_is_loading > 0) {\n",
+       "        console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n",
+       "        return null;\n",
+       "      }\n",
+       "      if (js_urls == null || js_urls.length === 0) {\n",
+       "        run_callbacks();\n",
+       "        return null;\n",
+       "      }\n",
+       "      console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n",
+       "      window._bokeh_is_loading = js_urls.length;\n",
+       "      for (var i = 0; i < js_urls.length; i++) {\n",
+       "        var url = js_urls[i];\n",
+       "        var s = document.createElement('script');\n",
+       "        s.src = url;\n",
+       "        s.async = false;\n",
+       "        s.onreadystatechange = s.onload = function() {\n",
+       "          window._bokeh_is_loading--;\n",
+       "          if (window._bokeh_is_loading === 0) {\n",
+       "            console.log(\"Bokeh: all BokehJS libraries loaded\");\n",
+       "            run_callbacks()\n",
+       "          }\n",
+       "        };\n",
+       "        s.onerror = function() {\n",
+       "          console.warn(\"failed to load library \" + url);\n",
+       "        };\n",
+       "        console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n",
+       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
+       "      }\n",
+       "    };var element = document.getElementById(\"0c5ea6a9-e3a5-4e96-b637-192bd20b9f1d\");\n",
+       "    if (element == null) {\n",
+       "      console.log(\"Bokeh: ERROR: autoload.js configured with elementid '0c5ea6a9-e3a5-4e96-b637-192bd20b9f1d' but no matching script tag was found. \")\n",
+       "      return false;\n",
+       "    }\n",
+       "  \n",
+       "    var js_urls = [];\n",
+       "  \n",
+       "    var inline_js = [\n",
+       "      function(Bokeh) {\n",
+       "        Bokeh.$(function() {\n",
+       "            var docs_json = {\"e2a303da-a6a4-4f72-93aa-fd4d058e86e1\":{\"roots\":{\"references\":[{\"attributes\":{\"bottom_units\":\"screen\",\"fill_alpha\":{\"value\":0.5},\"fill_color\":{\"value\":\"lightgrey\"},\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":{\"value\":1.0},\"line_color\":{\"value\":\"black\"},\"line_dash\":[4,4],\"line_width\":{\"value\":2},\"plot\":null,\"render_mode\":\"css\",\"right_units\":\"screen\",\"top_units\":\"screen\"},\"id\":\"c716 [...]
+       "            var render_items = [{\"docid\":\"e2a303da-a6a4-4f72-93aa-fd4d058e86e1\",\"elementid\":\"0c5ea6a9-e3a5-4e96-b637-192bd20b9f1d\",\"modelid\":\"ff6e3385-d72e-4641-a5fb-aa04fd3eab28\"}];\n",
+       "            \n",
+       "            Bokeh.embed.embed_items(docs_json, render_items);\n",
+       "        });\n",
+       "      },\n",
+       "      function(Bokeh) {\n",
+       "      }\n",
+       "    ];\n",
+       "  \n",
+       "    function run_inline_js() {\n",
+       "      \n",
+       "      if ((window.Bokeh !== undefined) || (force === \"1\")) {\n",
+       "        for (var i = 0; i < inline_js.length; i++) {\n",
+       "          inline_js[i](window.Bokeh);\n",
+       "        }if (force === \"1\") {\n",
+       "          display_loaded();\n",
+       "        }} else if (Date.now() < window._bokeh_timeout) {\n",
+       "        setTimeout(run_inline_js, 100);\n",
+       "      } else if (!window._bokeh_failed_load) {\n",
+       "        console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n",
+       "        window._bokeh_failed_load = true;\n",
+       "      } else if (!force) {\n",
+       "        var cell = $(\"#0c5ea6a9-e3a5-4e96-b637-192bd20b9f1d\").parents('.cell').data().cell;\n",
+       "        cell.output_area.append_execute_result(NB_LOAD_WARNING)\n",
+       "      }\n",
+       "  \n",
+       "    }\n",
+       "  \n",
+       "    if (window._bokeh_is_loading === 0) {\n",
+       "      console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n",
+       "      run_inline_js();\n",
+       "    } else {\n",
+       "      load_libs(js_urls, function() {\n",
+       "        console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n",
+       "        run_inline_js();\n",
+       "      });\n",
+       "    }\n",
+       "  }(this));\n",
+       "</script>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "TOOLS=\"pan,wheel_zoom,box_zoom,reset,hover\"\n",
+    "p = figure(tools=TOOLS, x_axis_location=None, y_axis_location=None)\n",
+    "p.grid.grid_line_color = None\n",
+    "\n",
+    "p.patches('x', 'y', source=cds,\n",
+    "  fill_alpha=1.,\n",
+    "  line_color='black', \n",
+    "  line_width=0.5\n",
+    "  )\n",
+    "\n",
+    "show(p)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 39,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "x = range(10)\n",
+    "y = range(100)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 40,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "d = dict(f=x,l=y)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 41,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'f': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],\n",
+       " 'l': [0,\n",
+       "  1,\n",
+       "  2,\n",
+       "  3,\n",
+       "  4,\n",
+       "  5,\n",
+       "  6,\n",
+       "  7,\n",
+       "  8,\n",
+       "  9,\n",
+       "  10,\n",
+       "  11,\n",
+       "  12,\n",
+       "  13,\n",
+       "  14,\n",
+       "  15,\n",
+       "  16,\n",
+       "  17,\n",
+       "  18,\n",
+       "  19,\n",
+       "  20,\n",
+       "  21,\n",
+       "  22,\n",
+       "  23,\n",
+       "  24,\n",
+       "  25,\n",
+       "  26,\n",
+       "  27,\n",
+       "  28,\n",
+       "  29,\n",
+       "  30,\n",
+       "  31,\n",
+       "  32,\n",
+       "  33,\n",
+       "  34,\n",
+       "  35,\n",
+       "  36,\n",
+       "  37,\n",
+       "  38,\n",
+       "  39,\n",
+       "  40,\n",
+       "  41,\n",
+       "  42,\n",
+       "  43,\n",
+       "  44,\n",
+       "  45,\n",
+       "  46,\n",
+       "  47,\n",
+       "  48,\n",
+       "  49,\n",
+       "  50,\n",
+       "  51,\n",
+       "  52,\n",
+       "  53,\n",
+       "  54,\n",
+       "  55,\n",
+       "  56,\n",
+       "  57,\n",
+       "  58,\n",
+       "  59,\n",
+       "  60,\n",
+       "  61,\n",
+       "  62,\n",
+       "  63,\n",
+       "  64,\n",
+       "  65,\n",
+       "  66,\n",
+       "  67,\n",
+       "  68,\n",
+       "  69,\n",
+       "  70,\n",
+       "  71,\n",
+       "  72,\n",
+       "  73,\n",
+       "  74,\n",
+       "  75,\n",
+       "  76,\n",
+       "  77,\n",
+       "  78,\n",
+       "  79,\n",
+       "  80,\n",
+       "  81,\n",
+       "  82,\n",
+       "  83,\n",
+       "  84,\n",
+       "  85,\n",
+       "  86,\n",
+       "  87,\n",
+       "  88,\n",
+       "  89,\n",
+       "  90,\n",
+       "  91,\n",
+       "  92,\n",
+       "  93,\n",
+       "  94,\n",
+       "  95,\n",
+       "  96,\n",
+       "  97,\n",
+       "  98,\n",
+       "  99]}"
+      ]
+     },
+     "execution_count": 41,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "d"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 42,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,\n",
+       "       17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,\n",
+       "       34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48])"
+      ]
+     },
+     "execution_count": 42,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "db.index.values\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 43,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "0     80.467003\n",
+       "1     44.567001\n",
+       "2     26.350000\n",
+       "3     33.200001\n",
+       "4     23.225000\n",
+       "5     28.750000\n",
+       "6     75.000000\n",
+       "7     37.125000\n",
+       "8     52.599998\n",
+       "9     96.400002\n",
+       "10    19.700001\n",
+       "11    19.900000\n",
+       "12    41.700001\n",
+       "13    42.900002\n",
+       "14    18.000000\n",
+       "15    18.799999\n",
+       "16    41.750000\n",
+       "17    60.000000\n",
+       "18    30.600000\n",
+       "19    81.266998\n",
+       "20    19.975000\n",
+       "21    30.450001\n",
+       "22    47.733002\n",
+       "23    53.200001\n",
+       "24    17.900000\n",
+       "25    20.299999\n",
+       "26    34.099998\n",
+       "27    22.850000\n",
+       "28    32.500000\n",
+       "29    22.500000\n",
+       "30    31.799999\n",
+       "31    40.299999\n",
+       "32    23.600000\n",
+       "33    28.450001\n",
+       "34    27.000000\n",
+       "35    36.299999\n",
+       "36    43.299999\n",
+       "37    22.700001\n",
+       "38    39.599998\n",
+       "39    61.950001\n",
+       "40    42.099998\n",
+       "41    44.333000\n",
+       "42    25.700001\n",
+       "43    33.500000\n",
+       "44    27.733000\n",
+       "45    76.099998\n",
+       "46    42.500000\n",
+       "47    26.799999\n",
+       "48    35.799999\n",
+       "Name: HOVAL, dtype: float64"
+      ]
+     },
+     "execution_count": 43,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "db['HOVAL']"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python [default]",
+   "language": "python",
+   "name": "python2"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 2
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython2",
+   "version": "2.7.12"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 0
+}
diff --git a/pysal/contrib/viz/mapping.py b/pysal/contrib/viz/mapping.py
index cfb38f6..b030685 100644
--- a/pysal/contrib/viz/mapping.py
+++ b/pysal/contrib/viz/mapping.py
@@ -1,5 +1,5 @@
 """
-Choropleth mapping using PySAL and Matplotlib
+Choropleth mapping using PySAL
 
 ToDo:
     * map_line_shp, map_point_shp should take a shp object not a shp_link
@@ -10,6 +10,7 @@ ToDo:
 __author__ = "Sergio Rey <sjsrey at gmail.com>", "Dani Arribas-Bel <daniel.arribas.bel at gmail.com"
 
 
+from warnings import warn
 import pandas as pd
 import pysal as ps
 import numpy as np
@@ -19,8 +20,47 @@ import matplotlib as mpl
 from matplotlib.pyplot import fill, text
 from matplotlib import cm
 from matplotlib.patches import Polygon
+import collections
 from matplotlib.path import Path
-from matplotlib.collections import LineCollection, PathCollection, PolyCollection, PathCollection, PatchCollection
+from matplotlib.collections import LineCollection, PathCollection, PolyCollection, PathCollection, PatchCollection, CircleCollection
+
+from color import get_color_map
+
+try:
+    import bokeh.plotting as bk
+    from bokeh.models import HoverTool
+except:
+    warn('Bokeh not installed. Functionality ' \
+            'related to it will not work')
+# Classifier helper
+classifiers = ps.esda.mapclassify.CLASSIFIERS
+classifier = {c.lower():getattr(ps.esda.mapclassify,c) for c in classifiers}
+
+def value_classifier(y, scheme='Quantiles', **kwargs):
+    """
+    Return classification for an indexed Series of values
+    ...
+
+    Arguments
+    ---------
+    y           : Series
+                  Indexed series containing values to be classified
+    scheme      : str
+                  [Optional. Default='Quantiles'] Name of the PySAL classifier
+                  to be used
+    **kwargs    : dict
+                  Additional arguments specific to the classifier of choice
+                  (see the classifier's documentation for details)
+
+    Returns
+    -------
+    labels           : Series
+                       Indexed series containing classes for each observation
+    classification   : Map_Classifier instance
+    """
+    c = classifier[scheme.lower()](y, **kwargs)
+    return (pd.Series(c.yb, index=y.index), c)
+
 
 # Low-level pieces
 
@@ -505,6 +545,358 @@ def _expand_values(values, shp2dbf_row):
 
 # High-level pieces
 
+def geoplot(db, col=None, palette='BuGn', classi='Quantiles',
+        backend='mpl', color=None, facecolor='#4D4D4D', edgecolor='#B3B3B3',
+        alpha=1., linewidth=0.2, marker='o', marker_size=20,
+        ax=None, hover=True, p=None, tips=None, figsize=(9,9), **kwargs):
+    '''
+    Higher level plotter for geotables
+    ...
+
+    Arguments
+    ---------
+    db          : DataFrame
+                  GeoTable with 'geometry' column and values to be plotted.
+    col         : None/str
+                  [Optional. Default=None] Column holding the values to encode
+                  into the choropleth.
+    palette     : str/palettable palette
+                  String of the `palettable.colorbrewer` portfolio, or a
+                  `palettable` palette to use
+    classi      : str
+                  [Optional. Default='mpl'] Backend to plot the
+    backend     : str
+                  [Optional. Default='mpl'] Backend to plot the
+                  geometries. Available options include Matplotlib ('mpl') or
+                  Bokeh ('bk').
+    color       : str/tuple/Series
+                  [Optional. Default=None] Wrapper that sets both `facecolor`
+                  and `edgecolor` at the same time. If set, `facecolor` and
+                  `edgecolor` are ignored. It allows for either a single color
+                  or a Series of the same length as `gc` with colors, indexed
+                  on `gc.index`.
+    facecolor   : str/tuple/Series
+                  [Optional. Default='#4D4D4D'] Color for polygons and points. It
+                  allows for either a single color or a Series of the same
+                  length as `gc` with colors, indexed on `gc.index`.
+    edgecolor   : str/tuple/Series
+                  [Optional. Default='#B3B3B3'] Color for the polygon and point
+                  edges. It allows for either a single color or a Series of
+                  the same length as `gc` with colors, indexed on `gc.index`.
+    alpha       : float/Series
+                  [Optional. Default=1.] Transparency. It allows for either a
+                  single value or a Series of the same length as `gc` with
+                  colors, indexed on `gc.index`.
+    linewidth   : float/Series
+                  [Optional. Default=0.2] Width(s) of the lines in polygon and
+                  line plotting (not applicable to points). It allows for
+                  either a single value or a Series of the same length as `gc`
+                  with colors, indexed on `gc.index`.
+    marker      : str
+                  [Optional. `mpl` backend only. Default='o'] Marker for point
+                  plotting.
+    marker_size : int/Series
+                  [Optional. Default=0.15] Width(s) of the lines in polygon and
+    ax          : AxesSubplot
+                  [Optional. `mpl` backend only. Default=None] Pre-existing
+                  axes to which append the geometries.
+    hover       : Boolean
+                  [Optional. `bk` backend only. Default=True] Include hover tool.
+    p           : bokeh.plotting.figure
+                  [Optional. `bk` backend only. Default=None] Pre-existing
+                  bokeh figure to which append the collections and setup.
+    tips        : list of strings
+                  series names to add to hover tool
+    kwargs      : Dict
+                  Additional named vaues to be passed to the classifier of choice.
+    '''
+    if col:
+        if hasattr(palette, 'number') and 'k' in kwargs:
+            if kwargs['k'] > palette.number:
+                raise ValueError('The number of classes requested is greater than '
+                                 'the number of colors available in the palette.')
+        lbl,c = value_classifier(db[col], scheme=classi, **kwargs)
+        if type(palette) is not str:
+            palette = get_color_map(palette=palette, k=c.k)
+        else:
+            palette = get_color_map(name=palette, k=c.k)
+        facecolor = lbl.map({i:j for i,j in enumerate(palette)})
+        try:
+            kwargs.pop('k')
+        except KeyError:
+            pass
+        col = [(col, db[col])]
+        if tips:
+            for tip in tips:
+                col.append((tip, db[tip]))
+        col.append(('index', db.index.values))
+        col = collections.OrderedDict(col) # put mapped variable at the top
+
+    if backend is 'mpl':
+        plot_geocol_mpl(db['geometry'], facecolor=facecolor, ax=ax,
+                color=color, edgecolor=edgecolor, alpha=alpha,
+                linewidth=linewidth, marker=marker, marker_size=marker_size,
+                        figsize=figsize,
+                **kwargs)
+    elif backend is 'bk':
+        plot_geocol_bk(db['geometry'], facecolor=facecolor,
+                color=color, edgecolor=edgecolor, alpha=alpha,
+                linewidth=linewidth, marker_size=marker_size,
+                hover=hover, p=p, col=col, **kwargs)
+    else:
+        warn("Please choose an available backend")
+    return None
+
+def plot_geocol_mpl(gc, color=None, facecolor='0.3', edgecolor='0.7',
+        alpha=1., linewidth=0.2, marker='o', marker_size=20,
+        ax=None, figsize=(9,9)):
+    '''
+    Plot geographical data from the `geometry` column of a PySAL geotable to a
+    matplotlib backend.
+
+    ...
+
+    Arguments
+    ---------
+    gc          : DataFrame
+                  GeoCol with data to be plotted.
+    color       : str/tuple/Series
+                  [Optional. Default=None] Wrapper that sets both `facecolor`
+                  and `edgecolor` at the same time. If set, `facecolor` and
+                  `edgecolor` are ignored. It allows for either a single color
+                  or a Series of the same length as `gc` with colors, indexed
+                  on `gc.index`.
+    facecolor   : str/tuple/Series
+                  [Optional. Default='0.3'] Color for polygons and points. It
+                  allows for either a single color or a Series of the same
+                  length as `gc` with colors, indexed on `gc.index`.
+    edgecolor   : str/tuple/Series
+                  [Optional. Default='0.7'] Color for the polygon and point
+                  edges. It allows for either a single color or a Series of
+                  the same length as `gc` with colors, indexed on `gc.index`.
+    alpha       : float/Series
+                  [Optional. Default=1.] Transparency. It allows for either a
+                  single value or a Series of the same length as `gc` with
+                  colors, indexed on `gc.index`.
+    linewidth   : float/Series
+                  [Optional. Default=0.2] Width(s) of the lines in polygon and
+                  line plotting (not applicable to points). It allows for
+                  either a single value or a Series of the same length as `gc`
+                  with colors, indexed on `gc.index`.
+    marker      : 'o'
+    marker_size : int
+    ax          : AxesSubplot
+                  [Optional. Default=None] Pre-existing axes to which append the
+                  collections and setup
+    figsize     : tuple
+                  w,h of figure
+    '''
+    geom = type(gc.iloc[0])
+    if color is not None:
+        facecolor = edgecolor = color
+    draw = False
+    if not ax:
+        f, ax = plt.subplots(1, figsize=figsize)
+        draw = True
+    # Geometry plotting
+    patches = []
+    ids = []
+    ## Polygons
+    if geom == ps.cg.shapes.Polygon:
+        for id, shape in gc.iteritems():
+            for ring in shape.parts:
+                xy = np.array(ring)
+                patches.append(xy)
+                ids.append(id)
+        mpl_col = PolyCollection(patches)
+    ## Lines
+    elif geom == ps.cg.shapes.Chain:
+        for id, shape in gc.iteritems():
+            for xy in shape.parts:
+                patches.append(xy)
+                ids.append(id)
+        mpl_col = LineCollection(patches)
+        facecolor = 'None'
+    ## Points
+    elif geom == ps.cg.shapes.Point:
+        edgecolor = facecolor
+        xys = np.array(zip(*gc)).T
+        ax.scatter(xys[:, 0], xys[:, 1], marker=marker,
+                s=marker_size, c=facecolor, edgecolors=edgecolor,
+                linewidths=linewidth)
+        mpl_col = None
+    # Styling mpl collection (polygons & lines)
+    if mpl_col:
+        if type(facecolor) is pd.Series:
+            facecolor = facecolor.reindex(ids)
+        mpl_col.set_facecolor(facecolor)
+        if type(edgecolor) is pd.Series:
+            edgecolor = edgecolor.reindex(ids)
+        mpl_col.set_edgecolor(edgecolor)
+        if type(linewidth) is pd.Series:
+            linewidth = linewidth.reindex(ids)
+        mpl_col.set_linewidth(linewidth)
+        if type(alpha) is pd.Series:
+            alpha = alpha.reindex(ids)
+        mpl_col.set_alpha(alpha)
+
+        ax.add_collection(mpl_col, autolim=True)
+        ax.autoscale_view()
+    ax.set_axis_off()
+    if draw:
+        plt.axis('equal')
+        plt.show()
+    return None
+
+def plot_geocol_bk(gc, color=None, facecolor='#4D4D4D', edgecolor='#B3B3B3',
+        alpha=1., linewidth=0.2, marker_size=10, hover=True, p=None, col=None):
+    '''
+    Plot geographical data from the `geometry` column of a PySAL geotable to a
+    bokeh backend.
+
+    ...
+
+    Arguments
+    ---------
+    gc          : DataFrame
+                  GeoCol with data to be plotted.
+    col         : None/dict
+                  [Optional. Default=None] Dictionary  with key, values for entries in hover tool
+    color       : str/tuple/Series
+                  [Optional. Default=None] Wrapper that sets both `facecolor`
+                  and `edgecolor` at the same time. If set, `facecolor` and
+                  `edgecolor` are ignored. It allows for either a single color
+                  or a Series of the same length as `gc` with colors, indexed
+                  on `gc.index`.
+    facecolor   : str/tuple/Series
+                  [Optional. Default='0.3'] Color for polygons and points. It
+                  allows for either a single color or a Series of the same
+                  length as `gc` with colors, indexed on `gc.index`.
+    edgecolor   : str/tuple/Series
+                  [Optional. Default='0.7'] Color for the polygon and point
+                  edges. It allows for either a single color or a Series of
+                  the same length as `gc` with colors, indexed on `gc.index`.
+    alpha       : float/Series
+                  [Optional. Default=1.] Transparency. It allows for either a
+                  single value or a Series of the same length as `gc` with
+                  colors, indexed on `gc.index`.
+    linewidth   : float/Series
+                  [Optional. Default=0.2] Width(s) of the lines in polygon and
+                  line plotting (not applicable to points). It allows for
+                  either a single value or a Series of the same length as `gc`
+                  with colors, indexed on `gc.index`.
+    marker_size : int
+    hover       : Boolean
+                  Include hover tool
+    p           : bokeh.plotting.figure
+                  [Optional. Default=None] Pre-existing bokeh figure to which
+                  append the collections and setup.
+    '''
+    geom = type(gc.iloc[0])
+    if color is not None:
+        facecolor = edgecolor = color
+    draw = False
+    if not p:
+        TOOLS="pan,wheel_zoom,box_zoom,reset,save"
+        if hover:
+            TOOLS += ',hover'
+        p = bk.figure(tools=TOOLS,
+           x_axis_location=None, y_axis_location=None)
+        p.grid.grid_line_color = None
+        draw = True
+    # Geometry plotting
+    patch_xs = []
+    patch_ys = []
+    ids = []
+    pars = {'fc': facecolor, \
+            'ec': edgecolor, \
+            'alpha': alpha, \
+            'lw': linewidth, \
+            'ms': marker_size}
+    ## Polygons + Lines
+    if (geom == ps.cg.shapes.Polygon) or \
+            (geom == ps.cg.shapes.Chain):
+        for idx, shape in gc.iteritems():
+            for ring in shape.parts:
+                xs, ys = zip(*ring)
+                patch_xs.append(xs)
+                patch_ys.append(ys)
+                ids.append(idx)
+        if hover and col:
+            tips = []
+            ds = dict(x=patch_xs, y=patch_ys)
+            for k,v in col.iteritems():
+                ds[k] = v
+                tips.append((k, "@"+k))
+            cds = bk.ColumnDataSource(data=ds)
+            h = p.select_one(HoverTool)
+            h.point_policy = 'follow_mouse'
+            h.tooltips = tips
+        else:
+            cds = bk.ColumnDataSource(data=dict(
+                        x=patch_xs,
+                        y=patch_ys
+                        ))
+        if type(facecolor) is pd.Series:
+            cds.add(facecolor.reindex(ids), 'facecolor')
+            pars['fc'] = 'facecolor'
+        if type(edgecolor) is pd.Series:
+            cds.add(edgecolor.reindex(ids), 'edgecolor')
+            pars['ec'] = 'edgecolor'
+        if type(alpha) is pd.Series:
+            cds.add(alpha.reindex(ids), 'alpha')
+            pars['alpha'] = 'alpha'
+        if type(linewidth) is pd.Series:
+            cds.add(linewidth.reindex(ids), 'linewidth')
+            pars['lw'] = 'linewidth'
+        if geom == ps.cg.shapes.Polygon:
+            p.patches('x', 'y', source=cds,
+              fill_color=pars['fc'],
+              line_color=pars['ec'],
+              fill_alpha=pars['alpha'],
+              line_width=pars['lw']
+              )
+        elif geom == ps.cg.shapes.Chain:
+            p.multi_line('x', 'y', source=cds,
+              line_color=pars['ec'],
+              line_alpha=pars['alpha'],
+              line_width=pars['lw']
+              )
+            facecolor = 'None'
+    ## Points
+    elif geom == ps.cg.shapes.Point:
+        edgecolor = facecolor
+        xys = np.array(zip(*gc)).T
+        cds = bk.ColumnDataSource(data=dict(
+                    x=xys[:, 0],
+                    y=xys[:, 1]
+                    ))
+        if type(facecolor) is pd.Series:
+            cds.add(facecolor.reindex(ids), 'facecolor')
+            pars['fc'] = 'facecolor'
+        if type(edgecolor) is pd.Series:
+            cds.add(edgecolor.reindex(ids), 'edgecolor')
+            pars['ec'] = 'edgecolor'
+        if type(alpha) is pd.Series:
+            cds.add(alpha.reindex(ids), 'alpha')
+            pars['alpha'] = 'alpha'
+        if type(linewidth) is pd.Series:
+            cds.add(linewidth.reindex(ids), 'linewidth')
+            pars['lw'] = 'linewidth'
+        if type(marker_size) is pd.Series:
+            cds.add(marker_size.reindex(ids), 'marker_size')
+            pars['ms'] = 'marker_size'
+        p.circle('x', 'y',
+                 source=cds,
+                 fill_color=pars['fc'],
+                 line_color=pars['ec'],
+                 line_width=pars['lw'],
+                 fill_alpha=pars['alpha'],
+                 line_alpha=pars['alpha'],
+                 size=pars['ms'])
+    if draw:
+        bk.show(p)
+    return None
 
 def plot_poly_lines(shp_link,  savein=None, poly_col='none'):
     '''
@@ -532,7 +924,7 @@ def plot_poly_lines(shp_link,  savein=None, poly_col='none'):
     if savein:
         plt.savefig(savein)
     else:
-        print('callng plt.show()')
+        print('calling plt.show()')
         plt.show()
     return None
 
diff --git a/pysal/contrib/viz/mapping_guide.ipynb b/pysal/contrib/viz/mapping_guide.ipynb
index e057820..444bc61 100644
--- a/pysal/contrib/viz/mapping_guide.ipynb
+++ b/pysal/contrib/viz/mapping_guide.ipynb
@@ -363,7 +363,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython2",
-   "version": "2.7.10"
+   "version": "2.7.11"
   }
  },
  "nbformat": 4,
diff --git a/pysal/esda/mapclassify.py b/pysal/esda/mapclassify.py
index 3690948..aac2bcc 100644
--- a/pysal/esda/mapclassify.py
+++ b/pysal/esda/mapclassify.py
@@ -10,7 +10,15 @@ __all__ = ['Map_Classifier', 'quantile', 'Box_Plot', 'Equal_Interval',
            'Jenks_Caspall_Forced', 'Jenks_Caspall_Sampled',
            'Max_P_Classifier', 'Maximum_Breaks', 'Natural_Breaks',
            'Quantiles', 'Percentiles', 'Std_Mean', 'User_Defined',
-           'gadf', 'K_classifiers', 'HeadTail_Breaks']
+           'gadf', 'K_classifiers', 'HeadTail_Breaks', 'CLASSIFIERS']
+
+
+CLASSIFIERS = ('Box_Plot', 'Equal_Interval', 'Fisher_Jenks',
+               'Fisher_Jenks_Sampled', 'HeadTail_Breaks', 'Jenks_Caspall',
+               'Jenks_Caspall_Forced', 'Jenks_Caspall_Sampled',
+               'Max_P_Classifier', 'Maximum_Breaks', 'Natural_Breaks',
+               'Quantiles', 'Percentiles', 'Std_Mean', 'User_Defined')
+
 
 
 K = 5  # default number of classes in any map scheme with this as an argument
@@ -1072,7 +1080,7 @@ class Box_Plot(Map_Classifier):
             bins[-1] = right_fence
         bins.insert(0, left_fence)
         self.bins = np.array(bins)
-        self.k = len(pct)
+        self.k = len(bins)
 
     def _classify(self):
         Map_Classifier._classify(self)
diff --git a/pysal/version.py b/pysal/version.py
index e739bc2..f08e764 100644
--- a/pysal/version.py
+++ b/pysal/version.py
@@ -1,3 +1,3 @@
 import datetime
-version = "1.12.0"
-stable_release_date = datetime.date(2016, 9, 21)
+version = "1.13.0"
+stable_release_date = datetime.date(2016, 12, 9)
diff --git a/pysal/weights/weights.py b/pysal/weights/weights.py
index 975e08e..5c56272 100644
--- a/pysal/weights/weights.py
+++ b/pysal/weights/weights.py
@@ -4,6 +4,7 @@ Weights.
 __author__ = "Sergio J. Rey <srey at asu.edu> "
 
 import math
+import warnings
 import numpy as np
 import scipy.sparse
 from os.path import basename as BASENAME
@@ -182,11 +183,11 @@ class W(object):
         if self.islands and not self.silent_island_warning:
             ni = len(self.islands)
             if ni == 1:
-                print("WARNING: there is one disconnected observation (no neighbors)")
-                print("Island id: ", self.islands)
+                warnings.warn("There is one disconnected observation (no neighbors)")
+                warnings.warn("Island id: %s" % str(self.islands[0]))
             else:
-                print("WARNING: there are %d disconnected observations" % ni)
-                print("Island ids: ", self.islands)
+                warnings.warn("There are %d disconnected observations" % ni)
+                warnings.warn("Island ids: %s" % ', '.join(str(island) for island in self.islands))
 
     def _reset(self):
         """Reset properties.
@@ -787,15 +788,17 @@ class W(object):
 
         .. table::
 
-            ================   ======================================================
-            transform string   value
-            ================   ======================================================
-            B                  Binary
-            R                  Row-standardization (global sum=n)
-            D                  Double-standardization (global sum=1)
-            V                  Variance stabilizing
-            O                  Restore original transformation (from instantiation)
-            ================   ======================================================
+           :widths: auto
+
+           ================   ======================================================
+           transform string   value
+           ================   ======================================================
+           B                  Binary
+           R                  Row-standardization (global sum=n)
+           D                  Double-standardization (global sum=1)
+           V                  Variance stabilizing
+           O                  Restore original transformation (from instantiation)
+           ================   ======================================================
 
         Examples
         --------
diff --git a/requirements.txt b/requirements.txt
index f3aca17..88cd714 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1 +1,2 @@
 scipy>=0.11
+numpy>=1.3
diff --git a/travis.txt b/requirements_dev.txt
similarity index 94%
rename from travis.txt
rename to requirements_dev.txt
index 8b30813..71110ce 100644
--- a/travis.txt
+++ b/requirements_dev.txt
@@ -1,5 +1,6 @@
-nose-exclude
+nose
 nose-progressive
+nose-exclude
 coverage
 sphinx
 sphinxcontrib-napoleon
diff --git a/requirements_plus.txt b/requirements_plus.txt
index 9dcf92d..2a57755 100644
--- a/requirements_plus.txt
+++ b/requirements_plus.txt
@@ -1,4 +1,3 @@
-scipy>=0.11
 matplotlib>=1.5.1
 seaborn>=0.7.0
 geopandas>=0.2
diff --git a/setup.py b/setup.py
index 7bdebf6..12f8136 100644
--- a/setup.py
+++ b/setup.py
@@ -13,7 +13,7 @@ with open('README.rst') as file:
     long_description = file.read()
 
 MAJOR = 1
-MINOR = 12
+MINOR = 13
 MICRO = 0
 ISRELEASED = False
 VERSION = '%d.%d.%d' % (MAJOR, MINOR, MICRO)
@@ -24,9 +24,17 @@ VERSION = '%d.%d.%d' % (MAJOR, MINOR, MICRO)
 if os.path.exists('MANIFEST'):
     os.remove('MANIFEST')
 
+def _get_requirements_from_files(groups_files):
+    groups_reqlist = {}
 
-def setup_package():
+    for k,v in groups_files.items():
+        with open(v, 'r') as f:
+            pkg_list = f.read().splitlines()
+        groups_reqlist[k] = pkg_list
+
+    return groups_reqlist
 
+def setup_package():
     # get all file endings and copy whole file names without a file suffix
     # assumes nested directories are only down one level
     example_data_files = set()
@@ -43,6 +51,16 @@ def setup_package():
 
         example_data_files.add(glob_name)
 
+    _groups_files = {
+        'base': 'requirements.txt',
+        'plus': 'requirements_plus.txt',
+        'dev': 'requirements_dev.txt'
+    }
+
+    reqs = _get_requirements_from_files(_groups_files)
+    install_reqs = reqs.pop('base')
+    extras_reqs = reqs
+
     setup(
         name='PySAL',
         version=VERSION,
@@ -74,8 +92,9 @@ def setup_package():
         packages=find_packages(exclude=[".meta", "*.meta.*", "meta.*",
                                         "meta"]),
         package_data={'pysal': list(example_data_files)},
-        requires=['scipy'],
-        cmdclass= {'build_py': build_py}
+        install_requires=install_reqs,
+        extras_require=extras_reqs,
+        cmdclass={'build_py': build_py}
     )
 
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/pysal.git



More information about the Pkg-grass-devel mailing list