{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys\n",
    "import os"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "sys.path.append(os.path.abspath('..'))\n",
    "import libpysal"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['georgia',\n",
       " '__pycache__',\n",
       " 'tests',\n",
       " 'newHaven',\n",
       " 'Polygon_Holes',\n",
       " 'nat',\n",
       " 'Polygon',\n",
       " '10740',\n",
       " 'berlin',\n",
       " 'rio_grande_do_sul',\n",
       " 'sids2',\n",
       " 'sacramento2',\n",
       " 'burkitt',\n",
       " 'arcgis',\n",
       " 'calemp',\n",
       " 'stl',\n",
       " 'virginia',\n",
       " 'geodanet',\n",
       " 'desmith',\n",
       " 'book',\n",
       " 'nyc_bikes',\n",
       " 'Line',\n",
       " 'south',\n",
       " 'snow_maps',\n",
       " 'Point',\n",
       " 'street_net_pts',\n",
       " 'guerry',\n",
       " '__pycache__',\n",
       " 'baltim',\n",
       " 'networks',\n",
       " 'us_income',\n",
       " 'taz',\n",
       " 'columbus',\n",
       " 'tokyo',\n",
       " 'mexico',\n",
       " '__pycache__',\n",
       " 'chicago',\n",
       " 'wmat',\n",
       " 'juvenile',\n",
       " 'clearwater']"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "libpysal.examples.available()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'name': 'mexico',\n",
       " 'description': 'Decennial per capita incomes of Mexican states 1940-2000',\n",
       " 'explanation': ['* mexico.csv: attribute data. (n=32, k=13)',\n",
       "  '* mexico.gal: spatial weights in GAL format.',\n",
       "  '* mexicojoin.shp: Polygon shapefile. (n=32)',\n",
       "  'Data used in Rey, S.J. and M.L. Sastre Gutierrez. (2010) \"Interregional inequality dynamics in Mexico.\" Spatial Economic Analysis, 5: 277-298.']}"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "libpysal.examples.explain('mexico')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Weights from GeoDataFrames"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "import geopandas\n",
    "pth = libpysal.examples.get_path(\"mexicojoin.shp\")\n",
    "gdf = geopandas.read_file(pth)\n",
    "\n",
    "from libpysal.weights import Queen, Rook, KNN"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "import matplotlib.pyplot as plt\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 17296 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "ax = gdf.plot()\n",
    "ax.set_axis_off()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Contiguity Weights\n",
    "\n",
    "The first set of spatial weights we illustrate use notions of contiguity to define neighboring observations. **Rook** neighbors are those states that share an edge on their respective borders:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "w_rook = Rook.from_dataframe(gdf)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "32"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w_rook.n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "12.6953125"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w_rook.pct_nonzero"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 49504 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "ax = gdf.plot(edgecolor='grey', facecolor='w')\n",
    "f,ax = w_rook.plot(gdf, ax=ax, \n",
    "        edge_kws=dict(color='r', linestyle=':', linewidth=1),\n",
    "        node_kws=dict(marker=''))\n",
    "ax.set_axis_off()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>POLY_ID</th>\n",
       "      <th>AREA</th>\n",
       "      <th>CODE</th>\n",
       "      <th>NAME</th>\n",
       "      <th>PERIMETER</th>\n",
       "      <th>ACRES</th>\n",
       "      <th>HECTARES</th>\n",
       "      <th>PCGDP1940</th>\n",
       "      <th>PCGDP1950</th>\n",
       "      <th>PCGDP1960</th>\n",
       "      <th>...</th>\n",
       "      <th>GR9000</th>\n",
       "      <th>LPCGDP40</th>\n",
       "      <th>LPCGDP50</th>\n",
       "      <th>LPCGDP60</th>\n",
       "      <th>LPCGDP70</th>\n",
       "      <th>LPCGDP80</th>\n",
       "      <th>LPCGDP90</th>\n",
       "      <th>LPCGDP00</th>\n",
       "      <th>TEST</th>\n",
       "      <th>geometry</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>7.252751e+10</td>\n",
       "      <td>MX02</td>\n",
       "      <td>Baja California Norte</td>\n",
       "      <td>2040312.385</td>\n",
       "      <td>1.792187e+07</td>\n",
       "      <td>7252751.376</td>\n",
       "      <td>22361.0</td>\n",
       "      <td>20977.0</td>\n",
       "      <td>17865.0</td>\n",
       "      <td>...</td>\n",
       "      <td>0.05</td>\n",
       "      <td>4.35</td>\n",
       "      <td>4.32</td>\n",
       "      <td>4.25</td>\n",
       "      <td>4.40</td>\n",
       "      <td>4.47</td>\n",
       "      <td>4.43</td>\n",
       "      <td>4.48</td>\n",
       "      <td>1.0</td>\n",
       "      <td>(POLYGON ((-113.1397171020508 29.0177764892578...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>7.225988e+10</td>\n",
       "      <td>MX03</td>\n",
       "      <td>Baja California Sur</td>\n",
       "      <td>2912880.772</td>\n",
       "      <td>1.785573e+07</td>\n",
       "      <td>7225987.769</td>\n",
       "      <td>9573.0</td>\n",
       "      <td>16013.0</td>\n",
       "      <td>16707.0</td>\n",
       "      <td>...</td>\n",
       "      <td>0.00</td>\n",
       "      <td>3.98</td>\n",
       "      <td>4.20</td>\n",
       "      <td>4.22</td>\n",
       "      <td>4.39</td>\n",
       "      <td>4.46</td>\n",
       "      <td>4.41</td>\n",
       "      <td>4.42</td>\n",
       "      <td>2.0</td>\n",
       "      <td>(POLYGON ((-111.2061233520508 25.8027763366699...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>2.731957e+10</td>\n",
       "      <td>MX18</td>\n",
       "      <td>Nayarit</td>\n",
       "      <td>1034770.341</td>\n",
       "      <td>6.750785e+06</td>\n",
       "      <td>2731956.859</td>\n",
       "      <td>4836.0</td>\n",
       "      <td>7515.0</td>\n",
       "      <td>7621.0</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.05</td>\n",
       "      <td>3.68</td>\n",
       "      <td>3.88</td>\n",
       "      <td>3.88</td>\n",
       "      <td>4.04</td>\n",
       "      <td>4.13</td>\n",
       "      <td>4.11</td>\n",
       "      <td>4.06</td>\n",
       "      <td>3.0</td>\n",
       "      <td>(POLYGON ((-106.6210784912109 21.5653114318847...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>7.961008e+10</td>\n",
       "      <td>MX14</td>\n",
       "      <td>Jalisco</td>\n",
       "      <td>2324727.436</td>\n",
       "      <td>1.967200e+07</td>\n",
       "      <td>7961008.285</td>\n",
       "      <td>5309.0</td>\n",
       "      <td>8232.0</td>\n",
       "      <td>9953.0</td>\n",
       "      <td>...</td>\n",
       "      <td>0.03</td>\n",
       "      <td>3.73</td>\n",
       "      <td>3.92</td>\n",
       "      <td>4.00</td>\n",
       "      <td>4.21</td>\n",
       "      <td>4.32</td>\n",
       "      <td>4.30</td>\n",
       "      <td>4.33</td>\n",
       "      <td>4.0</td>\n",
       "      <td>POLYGON ((-101.52490234375 21.85663986206055, ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>5.467030e+09</td>\n",
       "      <td>MX01</td>\n",
       "      <td>Aguascalientes</td>\n",
       "      <td>313895.530</td>\n",
       "      <td>1.350927e+06</td>\n",
       "      <td>546702.985</td>\n",
       "      <td>10384.0</td>\n",
       "      <td>6234.0</td>\n",
       "      <td>8714.0</td>\n",
       "      <td>...</td>\n",
       "      <td>0.13</td>\n",
       "      <td>4.02</td>\n",
       "      <td>3.79</td>\n",
       "      <td>3.94</td>\n",
       "      <td>4.21</td>\n",
       "      <td>4.32</td>\n",
       "      <td>4.32</td>\n",
       "      <td>4.44</td>\n",
       "      <td>5.0</td>\n",
       "      <td>POLYGON ((-101.8461990356445 22.01176071166992...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5 rows × 35 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "   POLY_ID          AREA  CODE                   NAME    PERIMETER  \\\n",
       "0        1  7.252751e+10  MX02  Baja California Norte  2040312.385   \n",
       "1        2  7.225988e+10  MX03    Baja California Sur  2912880.772   \n",
       "2        3  2.731957e+10  MX18                Nayarit  1034770.341   \n",
       "3        4  7.961008e+10  MX14                Jalisco  2324727.436   \n",
       "4        5  5.467030e+09  MX01         Aguascalientes   313895.530   \n",
       "\n",
       "          ACRES     HECTARES  PCGDP1940  PCGDP1950  PCGDP1960  \\\n",
       "0  1.792187e+07  7252751.376    22361.0    20977.0    17865.0   \n",
       "1  1.785573e+07  7225987.769     9573.0    16013.0    16707.0   \n",
       "2  6.750785e+06  2731956.859     4836.0     7515.0     7621.0   \n",
       "3  1.967200e+07  7961008.285     5309.0     8232.0     9953.0   \n",
       "4  1.350927e+06   546702.985    10384.0     6234.0     8714.0   \n",
       "\n",
       "                         ...                          GR9000  LPCGDP40  \\\n",
       "0                        ...                            0.05      4.35   \n",
       "1                        ...                            0.00      3.98   \n",
       "2                        ...                           -0.05      3.68   \n",
       "3                        ...                            0.03      3.73   \n",
       "4                        ...                            0.13      4.02   \n",
       "\n",
       "   LPCGDP50  LPCGDP60  LPCGDP70  LPCGDP80  LPCGDP90  LPCGDP00  TEST  \\\n",
       "0      4.32      4.25      4.40      4.47      4.43      4.48   1.0   \n",
       "1      4.20      4.22      4.39      4.46      4.41      4.42   2.0   \n",
       "2      3.88      3.88      4.04      4.13      4.11      4.06   3.0   \n",
       "3      3.92      4.00      4.21      4.32      4.30      4.33   4.0   \n",
       "4      3.79      3.94      4.21      4.32      4.32      4.44   5.0   \n",
       "\n",
       "                                            geometry  \n",
       "0  (POLYGON ((-113.1397171020508 29.0177764892578...  \n",
       "1  (POLYGON ((-111.2061233520508 25.8027763366699...  \n",
       "2  (POLYGON ((-106.6210784912109 21.5653114318847...  \n",
       "3  POLYGON ((-101.52490234375 21.85663986206055, ...  \n",
       "4  POLYGON ((-101.8461990356445 22.01176071166992...  \n",
       "\n",
       "[5 rows x 35 columns]"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gdf.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 22]"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w_rook.neighbors[0] # the first location has two neighbors at locations 1 and 22"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0     Baja California Norte\n",
       "1       Baja California Sur\n",
       "22                   Sonora\n",
       "Name: NAME, dtype: object"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gdf['NAME'][[0, 1,22]]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "So, Baja California Norte has 2 rook neighbors: Baja California Sur and Sonora."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Queen** neighbors are based on a more inclusive condition that requires only a shared vertex between two states:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "w_queen = Queen.from_dataframe(gdf)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w_queen.n == w_rook.n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(w_queen.pct_nonzero > w_rook.pct_nonzero) == (w_queen.n == w_rook.n)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 50264 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "ax = gdf.plot(edgecolor='grey', facecolor='w')\n",
    "f,ax = w_queen.plot(gdf, ax=ax, \n",
    "        edge_kws=dict(color='r', linestyle=':', linewidth=1),\n",
    "        node_kws=dict(marker=''))\n",
    "ax.set_axis_off()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[(1, 1), (2, 6), (3, 6), (4, 6), (5, 5), (6, 2), (7, 3), (8, 2), (9, 1)]"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w_queen.histogram"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[(1, 1), (2, 6), (3, 7), (4, 7), (5, 3), (6, 4), (7, 3), (8, 1)]"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w_rook.histogram"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "c9 = [idx for idx,c in w_queen.cardinalities.items() if c==9]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "28    San Luis Potosi\n",
       "Name: NAME, dtype: object"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gdf['NAME'][c9]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[5, 6, 7, 27, 29, 30, 31]"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w_rook.neighbors[28]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[3, 5, 6, 7, 24, 27, 29, 30, 31]"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w_queen.neighbors[28]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-105.,  -95.,   21.,   26.])"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 71600 characters]\n",
      "text/plain": [
       "<Figure size 720x432 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import numpy as np\n",
    "f,ax = plt.subplots(1,2,figsize=(10, 6), subplot_kw=dict(aspect='equal'))\n",
    "gdf.plot(edgecolor='grey', facecolor='w', ax=ax[0])\n",
    "w_rook.plot(gdf, ax=ax[0], \n",
    "        edge_kws=dict(color='r', linestyle=':', linewidth=1),\n",
    "        node_kws=dict(marker=''))\n",
    "ax[0].set_title('Rook')\n",
    "ax[0].axis(np.asarray([-105.0, -95.0, 21, 26]))\n",
    "\n",
    "ax[0].axis('off')\n",
    "gdf.plot(edgecolor='grey', facecolor='w', ax=ax[1])\n",
    "w_queen.plot(gdf, ax=ax[1], \n",
    "        edge_kws=dict(color='r', linestyle=':', linewidth=1),\n",
    "        node_kws=dict(marker=''))\n",
    "ax[1].set_title('Queen')\n",
    "ax[1].axis('off')\n",
    "ax[1].axis(np.asarray([-105.0, -95.0, 21, 26]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "w_knn = KNN.from_dataframe(gdf, k=4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[(4, 32)]"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w_knn.histogram"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 50988 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "ax = gdf.plot(edgecolor='grey', facecolor='w')\n",
    "f,ax = w_knn.plot(gdf, ax=ax, \n",
    "        edge_kws=dict(color='r', linestyle=':', linewidth=1),\n",
    "        node_kws=dict(marker=''))\n",
    "ax.set_axis_off()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Weights from shapefiles (without geopandas)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "pth = libpysal.examples.get_path(\"mexicojoin.shp\")\n",
    "from libpysal.weights import Queen, Rook, KNN"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [],
   "source": [
    "w_queen = Queen.from_shapefile(pth)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "w_rook = Rook.from_shapefile(pth)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/serge/Dropbox/p/pysal/src/subpackages/libpysal/libpysal/weights/weights.py:170: UserWarning: The weights matrix is not fully connected. There are 2 components\n",
      "  warnings.warn(\"The weights matrix is not fully connected. There are %d components\" % self.n_components)\n"
     ]
    }
   ],
   "source": [
    "w_knn1 = KNN.from_shapefile(pth)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The warning alerts us to the fact that using a first nearest neighbor criterion to define the neighbors results in a connectivity graph that has more than a single component. In this particular case there are 2 components which can be seen in the following plot:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 45672 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "ax = gdf.plot(edgecolor='grey', facecolor='w')\n",
    "f,ax = w_knn1.plot(gdf, ax=ax, \n",
    "        edge_kws=dict(color='r', linestyle=':', linewidth=1),\n",
    "        node_kws=dict(marker=''))\n",
    "ax.set_axis_off()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The two components are separated in the southern part of the country, with the smaller component to the east and the larger component running through the rest of the country to the west. For certain types of spatial analytical methods, it is necessary to have a adjacency structure that consists of a single component. To ensure this for the case of Mexican states, we can increase the number of nearest neighbors to three:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [],
   "source": [
    "w_knn3 = KNN.from_shapefile(pth,k=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 48056 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "ax = gdf.plot(edgecolor='grey', facecolor='w')\n",
    "f,ax = w_knn3.plot(gdf, ax=ax, \n",
    "        edge_kws=dict(color='r', linestyle=':', linewidth=1),\n",
    "        node_kws=dict(marker=''))\n",
    "ax.set_axis_off()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Lattice Weights"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [],
   "source": [
    "from libpysal.weights import lat2W"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [],
   "source": [
    "w = lat2W(4,3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "12"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w.n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "23.61111111111111"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w.pct_nonzero"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{0: [3, 1],\n",
       " 3: [0, 6, 4],\n",
       " 1: [0, 4, 2],\n",
       " 4: [1, 3, 7, 5],\n",
       " 2: [1, 5],\n",
       " 5: [2, 4, 8],\n",
       " 6: [3, 9, 7],\n",
       " 7: [4, 6, 10, 8],\n",
       " 8: [5, 7, 11],\n",
       " 9: [6, 10],\n",
       " 10: [7, 9, 11],\n",
       " 11: [8, 10]}"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w.neighbors"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Handling nonplanar geometries"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [],
   "source": [
    "rs = libpysal.examples.get_path('map_RS_BR.shp')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [],
   "source": [
    "import geopandas as gpd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/serge/Dropbox/p/pysal/src/subpackages/libpysal/libpysal/weights/weights.py:168: UserWarning: There are 29 disconnected observations \n",
      "  Island ids: 0, 4, 23, 27, 80, 94, 101, 107, 109, 119, 122, 139, 169, 175, 223, 239, 247, 253, 254, 255, 256, 261, 276, 291, 294, 303, 321, 357, 374\n",
      "  \" Island ids: %s\" % ', '.join(str(island) for island in self.islands))\n"
     ]
    }
   ],
   "source": [
    "rs_df = gpd.read_file(rs)\n",
    "wq = libpysal.weights.Queen.from_dataframe(rs_df)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "29"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(wq.islands)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{}"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "wq[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [],
   "source": [
    "wf = libpysal.weights.fuzzy_contiguity(rs_df)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[]"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "wf.islands"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{239: 1.0, 59: 1.0, 152: 1.0, 23: 1.0, 107: 1.0}"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "wf[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 634344 characters]\n",
      "text/plain": [
       "<Figure size 1440x1080 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.rcParams[\"figure.figsize\"] = (20,15)\n",
    "ax = rs_df.plot(edgecolor='grey', facecolor='w')\n",
    "f,ax = wq.plot(rs_df, ax=ax, \n",
    "        edge_kws=dict(color='r', linestyle=':', linewidth=1),\n",
    "        node_kws=dict(marker=''))\n",
    "\n",
    "ax.set_axis_off()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 709312 characters]\n",
      "text/plain": [
       "<Figure size 1440x1080 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "\n",
    "ax = rs_df.plot(edgecolor='grey', facecolor='w')\n",
    "f,ax = wf.plot(rs_df, ax=ax, \n",
    "        edge_kws=dict(color='r', linestyle=':', linewidth=1),\n",
    "        node_kws=dict(marker=''))\n",
    "ax.set_title('Rio Grande do Sul: Nonplanar Weights')\n",
    "ax.set_axis_off()\n",
    "plt.savefig('rioGrandeDoSul.png')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
