Exemple #1
0
def set_endog(y, x, w, yend, q, w_lags, lag_q):
    # Create spatial lag of y
    yl = lag_spatial(w, y)
    # spatial and non-spatial instruments
    if issubclass(type(yend), np.ndarray):
        if lag_q:
            lag_vars = sphstack(x, q)
        else:
            lag_vars = x
        spatial_inst = get_lags(w, lag_vars, w_lags)
        q = sphstack(q, spatial_inst)
        yend = sphstack(yend, yl)
    elif yend == None:  # spatial instruments only
        q = get_lags(w, x, w_lags)
        yend = yl
    else:
        raise Exception("invalid value passed to yend")
    return yend, q

    lag = lag_spatial(w, x)
    spat_lags = lag
    for i in range(w_lags - 1):
        lag = lag_spatial(w, lag)
        spat_lags = sphstack(spat_lags, lag)
    return spat_lags
Exemple #2
0
def get_lags(w, x, w_lags):
    '''
    Calculates a given order of spatial lags and all the smaller orders

    Parameters
    ----------
    w       : weight
              PySAL weights instance
    x       : array
              nxk arrays with the variables to be lagged  
    w_lags  : integer
              Maximum order of spatial lag

    Returns
    --------
    rs      : array
              nxk*(w_lags+1) array with original and spatially lagged variables

    '''
    lag = lag_spatial(w, x)
    spat_lags = lag
    for i in range(w_lags - 1):
        lag = lag_spatial(w, lag)
        spat_lags = sphstack(spat_lags, lag)
    return spat_lags
Exemple #3
0
 def __calc(self, z):
     zl = lag_spatial(self.w, z)
     bb = sum(z * zl) / 2.0
     zw = 1 - z
     zl = lag_spatial(self.w, zw)
     ww = sum(zw * zl) / 2.0
     bw = self.J - (bb + ww)
     return (bb, ww, bw)
Exemple #4
0
 def __calc(self, z):
     zl = lag_spatial(self.w, z)
     bb = sum(z * zl) / 2.0
     zw = 1 - z
     zl = lag_spatial(self.w, zw)
     ww = sum(zw * zl) / 2.0
     bw = self.J - (bb + ww)
     return (bb, ww, bw)
Exemple #5
0
 def __calc(self, z, op):
     if op == 'c':     # cross-product
         zl = lag_spatial(self.w, z)
         g = (z * zl).sum()
     elif op == 's':   # squared difference
         zs = np.zeros(z.shape)
         z2 = z ** 2
         for i, i0 in enumerate(self.w.id_order):
             neighbors = self.w.neighbor_offsets[i0]
             wijs = self.w.weights[i0]
             zw = list(zip(neighbors, wijs))
             zs[i] = sum([wij * (z2[i] - 2.0 * z[i] * z[
                 j] + z2[j]) for j, wij in zw])
         g = zs.sum()
     elif op == 'a':    # absolute difference
         zs = np.zeros(z.shape)
         for i, i0 in enumerate(self.w.id_order):
             neighbors = self.w.neighbor_offsets[i0]
             wijs = self.w.weights[i0]
             zw = list(zip(neighbors, wijs))
             zs[i] = sum([wij * abs(z[i] - z[j]) for j, wij in zw])
         g = zs.sum()
     else:              # any previously defined function op
         zs = np.zeros(z.shape)
         for i, i0 in enumerate(self.w.id_order):
             neighbors = self.w.neighbor_offsets[i0]
             wijs = self.w.weights[i0]
             zw = list(zip(neighbors, wijs))
             zs[i] = sum([wij * op(z, i, j) for j, wij in zw])
         g = zs.sum()
     return g
Exemple #6
0
 def __calc(self, z, op):
     if op == 'c':  # cross-product
         zl = lag_spatial(self.w, z)
         g = (z * zl).sum()
     elif op == 's':  # squared difference
         zs = np.zeros(z.shape)
         z2 = z**2
         for i, i0 in enumerate(self.w.id_order):
             neighbors = self.w.neighbor_offsets[i0]
             wijs = self.w.weights[i0]
             zw = list(zip(neighbors, wijs))
             zs[i] = sum([
                 wij * (z2[i] - 2.0 * z[i] * z[j] + z2[j]) for j, wij in zw
             ])
         g = zs.sum()
     elif op == 'a':  # absolute difference
         zs = np.zeros(z.shape)
         for i, i0 in enumerate(self.w.id_order):
             neighbors = self.w.neighbor_offsets[i0]
             wijs = self.w.weights[i0]
             zw = list(zip(neighbors, wijs))
             zs[i] = sum([wij * abs(z[i] - z[j]) for j, wij in zw])
         g = zs.sum()
     else:  # any previously defined function op
         zs = np.zeros(z.shape)
         for i, i0 in enumerate(self.w.id_order):
             neighbors = self.w.neighbor_offsets[i0]
             wijs = self.w.weights[i0]
             zw = list(zip(neighbors, wijs))
             zs[i] = sum([wij * op(z, i, j) for j, wij in zw])
         g = zs.sum()
     return g
Exemple #7
0
def hac_multi(reg, gwk, constant=False):
    """
    HAC robust estimation of the variance-covariance matrix for multi-regression object 

    Parameters
    ----------

    reg             : Regression object (OLS or TSLS)
                      output instance from a regression model

    gwk             : PySAL weights object
                      Spatial weights based on kernel functions

    Returns
    --------

    psi             : kxk array
                      Robust estimation of the variance-covariance

    """
    if not constant:
        reg.hac_var = check_constant(reg.hac_var)
    xu = spbroadcast(reg.hac_var, reg.u)
    gwkxu = lag_spatial(gwk, xu)
    psi0 = spdot(xu.T, gwkxu)
    counter = 0
    for m in reg.multi:
        reg.multi[m].robust = 'hac'
        reg.multi[m].name_gwk = reg.name_gwk
        try:
            psi1 = spdot(reg.multi[m].varb, reg.multi[m].zthhthi)
            reg.multi[m].vm = spdot(psi1, np.dot(psi0, psi1.T))
        except:
            reg.multi[m].vm = spdot(
                reg.multi[m].xtxi, np.dot(psi0, reg.multi[m].xtxi))
        reg.vm[(counter * reg.kr):((counter + 1) * reg.kr),
               (counter * reg.kr):((counter + 1) * reg.kr)] = reg.multi[m].vm
        counter += 1
Exemple #8
0
def plot_local_autocorrelation(moran_loc,
                               gdf,
                               attribute,
                               p=0.05,
                               region_column=None,
                               mask=None,
                               mask_color='#636363',
                               quadrant=None,
                               legend=True,
                               scheme='Quantiles',
                               cmap='YlGnBu',
                               figsize=(15, 4),
                               scatter_kwds=None,
                               fitline_kwds=None):
    '''
    Produce three-plot visualisation of Moran Scatteprlot, LISA cluster
    and Choropleth maps, with Local Moran region and quadrant masking

    Parameters
    ----------
    moran_loc : esda.moran.Moran_Local or Moran_Local_BV instance
        Values of Moran's Local Autocorrelation Statistic
    gdf : geopandas dataframe
        The Dataframe containing information to plot the two maps.
    attribute : str
        Column name of attribute which should be depicted in Choropleth map.
    p : float, optional
        The p-value threshold for significance. Points and polygons will
        be colored by significance. Default = 0.05.
    region_column: string, optional
        Column name containing mask region of interest. Default = None
    mask: str, optional
        Identifier or name of the region to highlight. Default = None
    mask_color: str, optional
        Color of mask. Default = '#636363'
    quadrant : int, optional
        Quadrant 1-4 in scatterplot masking values in LISA cluster and
        Choropleth maps. Default = None
    figsize: tuple, optional
        W, h of figure. Default = (15,4)
    legend: boolean, optional
        If True, legend for maps will be depicted. Default = True
    scheme: str, optional
        Name of PySAL classifier to be used. Default = 'Quantiles'
    cmap: str, optional
        Name of matplotlib colormap used for plotting the Choropleth.
        Default = 'YlGnBu'
    scatter_kwds : keyword arguments, optional
        Keywords used for creating and designing the scatter points.
        Default =None.
    fitline_kwds : keyword arguments, optional
        Keywords used for creating and designing the moran fitline
        in the scatterplot. Default =None.

    Returns
    -------
    fig : Matplotlib figure instance
        Moran Scatterplot, LISA cluster map and Choropleth.
    axs : list of Matplotlib axes
        Lisat of Matplotlib axes plotted.

    Examples
    --------
    Imports
    
    >>> import matplotlib.pyplot as plt
    >>> from pysal.lib.weights.contiguity import Queen
    >>> from pysal.lib import examples
    >>> import geopandas as gpd
    >>> from pysal.explore.esda.moran import Moran_Local
    >>> from pysal.viz.splot.esda import plot_local_autocorrelation

    Data preparation and analysis
    
    >>> link = examples.get_path('Guerry.shp')
    >>> gdf = gpd.read_file(link)
    >>> y = gdf['Donatns'].values
    >>> w = Queen.from_dataframe(gdf)
    >>> w.transform = 'r'
    >>> moran_loc = Moran_Local(y, w)

    Plotting with quadrant mask and region mask
    
    >>> fig = plot_local_autocorrelation(moran_loc, gdf, 'Donatns', p=0.05,
    ...                                  region_column='Dprtmnt',
    ...                                  mask=['Ain'], quadrant=1)
    >>> plt.show()
    
    '''
    fig, axs = plt.subplots(1,
                            3,
                            figsize=figsize,
                            subplot_kw={'aspect': 'equal'})
    # Moran Scatterplot
    moran_scatterplot(moran_loc,
                      p=p,
                      ax=axs[0],
                      scatter_kwds=scatter_kwds,
                      fitline_kwds=fitline_kwds)
    axs[0].set_aspect('auto')

    # Lisa cluster map
    # TODO: Fix legend_kwds: display boxes instead of points
    lisa_cluster(moran_loc,
                 gdf,
                 p=p,
                 ax=axs[1],
                 legend=legend,
                 legend_kwds={
                     'loc': 'upper left',
                     'bbox_to_anchor': (0.92, 1.05)
                 })
    axs[1].set_aspect('equal')

    # Choropleth for attribute
    gdf.plot(column=attribute,
             scheme=scheme,
             cmap=cmap,
             legend=legend,
             legend_kwds={
                 'loc': 'upper left',
                 'bbox_to_anchor': (0.92, 1.05)
             },
             ax=axs[2],
             alpha=1)
    axs[2].set_axis_off()
    axs[2].set_aspect('equal')

    # MASKING QUADRANT VALUES
    if quadrant is not None:
        # Quadrant masking in Scatterplot
        mask_angles = {1: 0, 2: 90, 3: 180, 4: 270}  # rectangle angles
        # We don't want to change the axis data limits, so use the current ones
        xmin, xmax = axs[0].get_xlim()
        ymin, ymax = axs[0].get_ylim()
        # We are rotating, so we start from 0 degrees and
        # figured out the right dimensions for the rectangles for other angles
        mask_width = {1: abs(xmax), 2: abs(ymax), 3: abs(xmin), 4: abs(ymin)}
        mask_height = {1: abs(ymax), 2: abs(xmin), 3: abs(ymin), 4: abs(xmax)}
        axs[0].add_patch(
            patches.Rectangle((0, 0),
                              width=mask_width[quadrant],
                              height=mask_height[quadrant],
                              angle=mask_angles[quadrant],
                              color='#E5E5E5',
                              zorder=-1,
                              alpha=0.8))
        # quadrant selection in maps
        non_quadrant = ~(moran_loc.q == quadrant)
        mask_quadrant = gdf[non_quadrant]
        df_quadrant = gdf.iloc[~non_quadrant]
        union2 = df_quadrant.unary_union.boundary

        # LISA Cluster mask and cluster boundary
        with warnings.catch_warnings(
        ):  # temorarily surpress geopandas warning
            warnings.filterwarnings('ignore', category=UserWarning)
            mask_quadrant.plot(column=attribute,
                               scheme=scheme,
                               color='white',
                               ax=axs[1],
                               alpha=0.7,
                               zorder=1)
        gpd.GeoSeries([union2]).plot(linewidth=1, ax=axs[1], color='#E5E5E5')

        # CHOROPLETH MASK
        with warnings.catch_warnings(
        ):  # temorarily surpress geopandas warning
            warnings.filterwarnings('ignore', category=UserWarning)
            mask_quadrant.plot(column=attribute,
                               scheme=scheme,
                               color='white',
                               ax=axs[2],
                               alpha=0.7,
                               zorder=1)
        gpd.GeoSeries([union2]).plot(linewidth=1, ax=axs[2], color='#E5E5E5')

    # REGION MASKING
    if region_column is not None:
        # masking inside axs[0] or Moran Scatterplot
        ix = gdf[region_column].isin(mask)
        df_mask = gdf[ix]
        x_mask = moran_loc.z[ix]
        y_mask = lag_spatial(moran_loc.w, moran_loc.z)[ix]
        axs[0].plot(x_mask,
                    y_mask,
                    color=mask_color,
                    marker='o',
                    markersize=14,
                    alpha=.8,
                    linestyle="None",
                    zorder=-1)

        # masking inside axs[1] or Lisa cluster map
        union = df_mask.unary_union.boundary
        gpd.GeoSeries([union]).plot(linewidth=2, ax=axs[1], color=mask_color)

        # masking inside axs[2] or Chloropleth
        gpd.GeoSeries([union]).plot(linewidth=2, ax=axs[2], color=mask_color)
    return fig, axs
Exemple #9
0
def _moran_loc_scatterplot(moran_loc,
                           zstandard=True,
                           p=None,
                           ax=None,
                           scatter_kwds=None,
                           fitline_kwds=None):
    """
    Moran Scatterplot with option of coloring of Local Moran Statistics

    Parameters
    ----------
    moran_loc : esda.moran.Moran_Local instance
        Values of Moran's I Local Autocorrelation Statistics
    p : float, optional
        If given, the p-value threshold for significance. Points will
        be colored by significance. By default it will not be colored.
        Default =None.
    ax : Matplotlib Axes instance, optional
        If given, the Moran plot will be created inside this axis.
        Default =None.
    scatter_kwds : keyword arguments, optional
        Keywords used for creating and designing the scatter points.
        Default =None.
    fitline_kwds : keyword arguments, optional
        Keywords used for creating and designing the moran fitline.
        Default =None.

    Returns
    -------
    fig : Matplotlib Figure instance
        Moran Local scatterplot figure
    ax : matplotlib Axes instance
        Axes in which the figure is plotted

    Examples
    --------
    Imports
    
    >>> import matplotlib.pyplot as plt
    >>> import geopandas as gpd
    >>> from pysal.lib.weights.contiguity import Queen
    >>> from pysal.lib import examples
    >>> from pysal.explore.esda.moran import Moran_Local
    >>> from pysal.viz.splot.esda import moran_scatterplot
    
    Load data and calculate Moran Local statistics
    
    >>> link = examples.get_path('Guerry.shp')
    >>> gdf = gpd.read_file(link)
    >>> y = gdf['Donatns'].values
    >>> w = Queen.from_dataframe(gdf)
    >>> w.transform = 'r'
    >>> m = Moran_Local(y, w)
    
    plot
    
    >>> moran_scatterplot(m)
    >>> plt.show()
    
    customize plot
    
    >>> moran_scatterplot(m, p=0.05,
    ...                   fitline_kwds=dict(color='#4393c3'))
    >>> plt.show()
    
    """
    # to set default as an empty dictionary that is later filled with defaults
    if scatter_kwds is None:
        scatter_kwds = dict()
    if fitline_kwds is None:
        fitline_kwds = dict()

    if p is not None:
        if not isinstance(moran_loc, Moran_Local):
            raise ValueError("`moran_loc` is not a\n " +
                             "esda.moran.Moran_Local instance")
        if 'color' in scatter_kwds or 'c' in scatter_kwds or 'cmap' in scatter_kwds:
            warnings.warn(
                'To change the color use cmap with a colormap of 5,\n' +
                ' color defines the LISA category')

        # colors
        spots = moran_hot_cold_spots(moran_loc, p)
        hmap = colors.ListedColormap(
            ['#bababa', '#d7191c', '#abd9e9', '#2c7bb6', '#fdae61'])

    # define customization
    scatter_kwds.setdefault('alpha', 0.6)
    scatter_kwds.setdefault('s', 40)
    fitline_kwds.setdefault('alpha', 0.9)

    # get fig and ax
    fig, ax = _create_moran_fig_ax(ax, figsize=(7, 7))

    # set labels
    ax.set_xlabel('Attribute')
    ax.set_ylabel('Spatial Lag')
    ax.set_title('Moran Local Scatterplot')

    # plot and set standards
    if zstandard is True:
        lag = lag_spatial(moran_loc.w, moran_loc.z)
        fit = OLS(moran_loc.z[:, None], lag[:, None])
        # v- and hlines
        ax.axvline(0, alpha=0.5, color='k', linestyle='--')
        ax.axhline(0, alpha=0.5, color='k', linestyle='--')
        if p is not None:
            fitline_kwds.setdefault('color', 'k')
            scatter_kwds.setdefault('cmap', hmap)
            scatter_kwds.setdefault('c', spots)
            ax.plot(lag, fit.predy, **fitline_kwds)
            ax.scatter(moran_loc.z, fit.predy, **scatter_kwds)
        else:
            scatter_kwds.setdefault('color', splot_colors['moran_base'])
            fitline_kwds.setdefault('color', splot_colors['moran_fit'])
            ax.plot(lag, fit.predy, **fitline_kwds)
            ax.scatter(moran_loc.z, fit.predy, **scatter_kwds)
    else:
        lag = lag_spatial(moran_loc.w, moran_loc.y)
        b, a = np.polyfit(moran_loc.y, lag, 1)
        # dashed vert at mean of the attribute
        ax.vlines(moran_loc.y.mean(),
                  lag.min(),
                  lag.max(),
                  alpha=0.5,
                  linestyle='--')
        # dashed horizontal at mean of lagged attribute
        ax.hlines(lag.mean(),
                  moran_loc.y.min(),
                  moran_loc.y.max(),
                  alpha=0.5,
                  linestyle='--')
        if p is not None:
            fitline_kwds.setdefault('color', 'k')
            scatter_kwds.setdefault('cmap', hmap)
            scatter_kwds.setdefault('c', spots)
            ax.plot(moran_loc.y, a + b * moran_loc.y, **fitline_kwds)
            ax.scatter(moran_loc.y, lag, **scatter_kwds)
        else:
            scatter_kwds.setdefault('c', splot_colors['moran_base'])
            fitline_kwds.setdefault('color', splot_colors['moran_fit'])
            ax.plot(moran_loc.y, a + b * moran_loc.y, **fitline_kwds)
            ax.scatter(moran_loc.y, lag, **scatter_kwds)
    return fig, ax
Exemple #10
0
def _moran_bv_scatterplot(moran_bv,
                          ax=None,
                          scatter_kwds=None,
                          fitline_kwds=None):
    """
    Bivariate Moran Scatterplot.

    Parameters
    ----------
    moran_bv : esda.moran.Moran_BV instance
        Values of Bivariate Moran's I Autocorrelation Statistics
    ax : Matplotlib Axes instance, optional
        If given, the Moran plot will be created inside this axis.
        Default =None.
    scatter_kwds : keyword arguments, optional
        Keywords used for creating and designing the scatter points.
        Default =None.
    fitline_kwds : keyword arguments, optional
        Keywords used for creating and designing the moran fitline.
        Default =None.

    Returns
    -------
    fig : Matplotlib Figure instance
        Bivariate moran scatterplot figure
    ax : matplotlib Axes instance
        Axes in which the figure is plotted

    Examples
    --------
    Imports
    
    >>> import matplotlib.pyplot as plt
    >>> from pysal.lib.weights.contiguity import Queen
    >>> from pysal.lib import examples
    >>> import geopandas as gpd
    >>> from pysal.explore.esda.moran import Moran_BV
    >>> from pysal.viz.splot.esda import moran_scatterplot
    
    Load data and calculate weights
    
    >>> link_to_data = examples.get_path('Guerry.shp')
    >>> gdf = gpd.read_file(link_to_data)
    >>> x = gdf['Suicids'].values
    >>> y = gdf['Donatns'].values
    >>> w = Queen.from_dataframe(gdf)
    >>> w.transform = 'r'
    
    Calculate Bivariate Moran
    
    >>> moran_bv = Moran_BV(x, y, w)
    
    plot
    
    >>> moran_scatterplot(moran_bv)
    >>> plt.show()
    
    customize plot
    
    >>> moran_scatterplot(moran_bv,
    ...                      fitline_kwds=dict(color='#4393c3'))
    >>> plt.show()
    
    """
    # to set default as an empty dictionary that is later filled with defaults
    if scatter_kwds is None:
        scatter_kwds = dict()
    if fitline_kwds is None:
        fitline_kwds = dict()

    # define customization
    scatter_kwds.setdefault('alpha', 0.6)
    scatter_kwds.setdefault('color', splot_colors['moran_base'])
    scatter_kwds.setdefault('s', 40)

    fitline_kwds.setdefault('alpha', 0.9)
    fitline_kwds.setdefault('color', splot_colors['moran_fit'])

    # get fig and ax
    fig, ax = _create_moran_fig_ax(ax, figsize=(7, 7))

    # set labels
    ax.set_xlabel('Attribute X')
    ax.set_ylabel('Spatial Lag of Y')
    ax.set_title('Bivariate Moran Scatterplot' + ' (' +
                 str(round(moran_bv.I, 2)) + ')')

    # plot and set standards
    lag = lag_spatial(moran_bv.w, moran_bv.zy)
    fit = OLS(moran_bv.zy[:, None], lag[:, None])
    # plot
    ax.scatter(moran_bv.zx, lag, **scatter_kwds)
    ax.plot(lag, fit.predy, **fitline_kwds)
    # v- and hlines
    ax.axvline(0, alpha=0.5, color='k', linestyle='--')
    ax.axhline(0, alpha=0.5, color='k', linestyle='--')
    return fig, ax
Exemple #11
0
def _moran_global_scatterplot(moran,
                              zstandard=True,
                              ax=None,
                              scatter_kwds=None,
                              fitline_kwds=None):
    """
    Global Moran's I Scatterplot.

    Parameters
    ----------
    moran : esda.moran.Moran instance
        Values of Moran's I Global Autocorrelation Statistics
    zstandard : bool, optional
        If True, Moran Scatterplot will show z-standardized attribute and
        spatial lag values. Default =True.
    ax : Matplotlib Axes instance, optional
        If given, the Moran plot will be created inside this axis.
        Default =None.
    scatter_kwds : keyword arguments, optional
        Keywords used for creating and designing the scatter points.
        Default =None.
    fitline_kwds : keyword arguments, optional
        Keywords used for creating and designing the moran fitline.
        Default =None.

    Returns
    -------
    fig : Matplotlib Figure instance
        Moran scatterplot figure
    ax : matplotlib Axes instance
        Axes in which the figure is plotted

    Examples
    --------
    Imports
    
    >>> import matplotlib.pyplot as plt
    >>> from pysal.lib.weights.contiguity import Queen
    >>> from pysal.lib import examples
    >>> import geopandas as gpd
    >>> from pysal.explore.esda.moran import Moran
    >>> from pysal.viz.splot.esda import moran_scatterplot
    
    Load data and calculate weights
    
    >>> link_to_data = examples.get_path('Guerry.shp')
    >>> gdf = gpd.read_file(link_to_data)
    >>> y = gdf['Donatns'].values
    >>> w = Queen.from_dataframe(gdf)
    >>> w.transform = 'r'
    
    Calculate Global Moran
    
    >>> moran = Moran(y, w)
    
    plot
    
    >>> moran_scatterplot(moran)
    >>> plt.show()
    
    customize plot
    
    >>> fig, ax = moran_scatterplot(moran, zstandard=False,
    ...                             fitline_kwds=dict(color='#4393c3'))
    >>> ax.set_xlabel('Donations')
    >>> plt.show()
    
    """
    # to set default as an empty dictionary that is later filled with defaults
    if scatter_kwds is None:
        scatter_kwds = dict()
    if fitline_kwds is None:
        fitline_kwds = dict()

    # define customization defaults
    scatter_kwds.setdefault('alpha', 0.6)
    scatter_kwds.setdefault('color', splot_colors['moran_base'])
    scatter_kwds.setdefault('s', 40)

    fitline_kwds.setdefault('alpha', 0.9)
    fitline_kwds.setdefault('color', splot_colors['moran_fit'])

    # get fig and ax
    fig, ax = _create_moran_fig_ax(ax, figsize=(7, 7))

    # set labels
    ax.set_xlabel('Attribute')
    ax.set_ylabel('Spatial Lag')
    ax.set_title('Moran Scatterplot' + ' (' + str(round(moran.I, 2)) + ')')

    # plot and set standards
    if zstandard is True:
        lag = lag_spatial(moran.w, moran.z)
        fit = OLS(moran.z[:, None], lag[:, None])
        # plot
        ax.scatter(moran.z, lag, **scatter_kwds)
        ax.plot(lag, fit.predy, **fitline_kwds)
        # v- and hlines
        ax.axvline(0, alpha=0.5, color='k', linestyle='--')
        ax.axhline(0, alpha=0.5, color='k', linestyle='--')
    else:
        lag = lag_spatial(moran.w, moran.y)
        b, a = np.polyfit(moran.y, lag, 1)
        # plot
        ax.scatter(moran.y, lag, **scatter_kwds)
        ax.plot(moran.y, a + b * moran.y, **fitline_kwds)
        # dashed vert at mean of the attribute
        ax.vlines(moran.y.mean(),
                  lag.min(),
                  lag.max(),
                  alpha=0.5,
                  linestyle='--')
        # dashed horizontal at mean of lagged attribute
        ax.hlines(lag.mean(),
                  moran.y.min(),
                  moran.y.max(),
                  alpha=0.5,
                  linestyle='--')
    return fig, ax
Exemple #12
0
def robust_vm(reg, gwk=None, sig2n_k=False):
    """
    Robust estimation of the variance-covariance matrix. Estimated by White (default) or HAC (if wk is provided). 

    Parameters
    ----------

    reg             : Regression object (OLS or TSLS)
                      output instance from a regression model

    gwk             : PySAL weights object
                      Optional. Spatial weights based on kernel functions
                      If provided, returns the HAC variance estimation
    sig2n_k         : boolean
                      If True, then use n-k to rescale the vc matrix.
                      If False, use n. (White only)

    Returns
    --------

    psi             : kxk array
                      Robust estimation of the variance-covariance

    Examples
    --------

    >>> import numpy as np
    >>> import pysal.lib
    >>> from ols import OLS
    >>> from twosls import TSLS
    >>> db=pysal.lib.io.open(pysal.lib.examples.get_path("NAT.dbf"),"r")
    >>> y = np.array(db.by_col("HR90"))
    >>> y = np.reshape(y, (y.shape[0],1))
    >>> X = []
    >>> X.append(db.by_col("RD90"))
    >>> X.append(db.by_col("DV90"))
    >>> X = np.array(X).T                       

    Example with OLS with unadjusted standard errors

    >>> ols = OLS(y,X)
    >>> ols.vm
    array([[ 0.17004545,  0.00226532, -0.02243898],
           [ 0.00226532,  0.00941319, -0.00031638],
           [-0.02243898, -0.00031638,  0.00313386]])

    Example with OLS and White

    >>> ols = OLS(y,X, robust='white')
    >>> ols.vm
    array([[ 0.24515481,  0.01093322, -0.03441966],
           [ 0.01093322,  0.01798616, -0.00071414],
           [-0.03441966, -0.00071414,  0.0050153 ]])

    Example with OLS and HAC

    >>> wk = pysal.lib.weights.Kernel.from_shapefile(pysal.lib.examples.get_path('NAT.shp'),k=15,function='triangular', fixed=False)
    >>> wk.transform = 'o'
    >>> ols = OLS(y,X, robust='hac', gwk=wk)
    >>> ols.vm
    array([[ 0.29213532,  0.01670361, -0.03948199],
           [ 0.01655557,  0.02295829, -0.00116874],
           [-0.03941483, -0.00119077,  0.00568314]])

    Example with 2SLS and White

    >>> yd = []
    >>> yd.append(db.by_col("UE90"))
    >>> yd = np.array(yd).T
    >>> q = []
    >>> q.append(db.by_col("UE80"))
    >>> q = np.array(q).T
    >>> tsls = TSLS(y, X, yd, q=q, robust='white')
    >>> tsls.vm
    array([[ 0.29569954,  0.04119843, -0.02496858, -0.01640185],
           [ 0.04119843,  0.03647762,  0.004702  , -0.00987345],
           [-0.02496858,  0.004702  ,  0.00648262, -0.00292891],
           [-0.01640185, -0.00987345, -0.00292891,  0.0053322 ]])

    Example with 2SLS and HAC

    >>> tsls = TSLS(y, X, yd, q=q, robust='hac', gwk=wk)
    >>> tsls.vm
    array([[ 0.41985329,  0.06823119, -0.02883889, -0.02788116],
           [ 0.06867042,  0.04887508,  0.00497443, -0.01367746],
           [-0.02856454,  0.00501402,  0.0072195 , -0.00321604],
           [-0.02810131, -0.01364908, -0.00318197,  0.00713251]])

    """
    if hasattr(reg, 'h'):  # If reg has H, do 2SLS estimator. OLS otherwise.
        tsls = True
        xu = spbroadcast(reg.h, reg.u)
    else:
        tsls = False
        xu = spbroadcast(reg.x, reg.u)

    if gwk:  # If gwk do HAC. White otherwise.
        gwkxu = lag_spatial(gwk, xu)
        psi0 = spdot(xu.T, gwkxu)
    else:
        psi0 = spdot(xu.T, xu)
        if sig2n_k:
            psi0 = psi0 * (1. * reg.n / (reg.n - reg.k))
    if tsls:
        psi1 = spdot(reg.varb, reg.zthhthi)
        psi = spdot(psi1, np.dot(psi0, psi1.T))
    else:
        psi = spdot(reg.xtxi, np.dot(psi0, reg.xtxi))

    return psi
Exemple #13
0
def plot_local_autocorrelation(moran_loc, gdf, attribute, p=0.05,
                               region_column=None, mask=None,
                               mask_color='#636363', quadrant=None,
                               legend=True, scheme='Quantiles',
                               cmap='YlGnBu', figsize=(15, 4),
                               scatter_kwds=None, fitline_kwds=None):
    '''
    Produce three-plot visualisation of Moran Scatteprlot, LISA cluster
    and Choropleth maps, with Local Moran region and quadrant masking

    Parameters
    ----------
    moran_loc : esda.moran.Moran_Local or Moran_Local_BV instance
        Values of Moran's Local Autocorrelation Statistic
    gdf : geopandas dataframe
        The Dataframe containing information to plot the two maps.
    attribute : str
        Column name of attribute which should be depicted in Choropleth map.
    p : float, optional
        The p-value threshold for significance. Points and polygons will
        be colored by significance. Default = 0.05.
    region_column: string, optional
        Column name containing mask region of interest. Default = None
    mask: str, optional
        Identifier or name of the region to highlight. Default = None
    mask_color: str, optional
        Color of mask. Default = '#636363'
    quadrant : int, optional
        Quadrant 1-4 in scatterplot masking values in LISA cluster and
        Choropleth maps. Default = None
    figsize: tuple, optional
        W, h of figure. Default = (15,4)
    legend: boolean, optional
        If True, legend for maps will be depicted. Default = True
    scheme: str, optional
        Name of PySAL classifier to be used. Default = 'Quantiles'
    cmap: str, optional
        Name of matplotlib colormap used for plotting the Choropleth.
        Default = 'YlGnBu'
    scatter_kwds : keyword arguments, optional
        Keywords used for creating and designing the scatter points.
        Default =None.
    fitline_kwds : keyword arguments, optional
        Keywords used for creating and designing the moran fitline
        in the scatterplot. Default =None.

    Returns
    -------
    fig : Matplotlib figure instance
        Moran Scatterplot, LISA cluster map and Choropleth.
    axs : list of Matplotlib axes
        Lisat of Matplotlib axes plotted.

    Examples
    --------
    Imports
    
    >>> import matplotlib.pyplot as plt
    >>> from pysal.lib.weights.contiguity import Queen
    >>> from pysal.lib import examples
    >>> import geopandas as gpd
    >>> from pysal.explore.esda.moran import Moran_Local
    >>> from pysal.viz.splot.esda import plot_local_autocorrelation

    Data preparation and analysis
    
    >>> link = examples.get_path('Guerry.shp')
    >>> gdf = gpd.read_file(link)
    >>> y = gdf['Donatns'].values
    >>> w = Queen.from_dataframe(gdf)
    >>> w.transform = 'r'
    >>> moran_loc = Moran_Local(y, w)

    Plotting with quadrant mask and region mask
    
    >>> fig = plot_local_autocorrelation(moran_loc, gdf, 'Donatns', p=0.05,
    ...                                  region_column='Dprtmnt',
    ...                                  mask=['Ain'], quadrant=1)
    >>> plt.show()
    
    '''
    fig, axs = plt.subplots(1, 3, figsize=figsize,
                            subplot_kw={'aspect': 'equal'})
    # Moran Scatterplot
    moran_scatterplot(moran_loc, p=p, ax=axs[0],
                      scatter_kwds=scatter_kwds, fitline_kwds=fitline_kwds)
    axs[0].set_aspect('auto')

    # Lisa cluster map
    # TODO: Fix legend_kwds: display boxes instead of points
    lisa_cluster(moran_loc, gdf, p=p, ax=axs[1], legend=legend,
                 legend_kwds={'loc': 'upper left',
                 'bbox_to_anchor': (0.92, 1.05)})
    axs[1].set_aspect('equal')

    # Choropleth for attribute
    gdf.plot(column=attribute, scheme=scheme, cmap=cmap,
             legend=legend, legend_kwds={'loc': 'upper left',
                                         'bbox_to_anchor': (0.92, 1.05)},
             ax=axs[2], alpha=1)
    axs[2].set_axis_off()
    axs[2].set_aspect('equal')

    # MASKING QUADRANT VALUES
    if quadrant is not None:
        # Quadrant masking in Scatterplot
        mask_angles = {1: 0, 2: 90, 3: 180, 4: 270}   # rectangle angles
        # We don't want to change the axis data limits, so use the current ones
        xmin, xmax = axs[0].get_xlim()
        ymin, ymax = axs[0].get_ylim()
        # We are rotating, so we start from 0 degrees and
        # figured out the right dimensions for the rectangles for other angles
        mask_width = {1: abs(xmax),
                      2: abs(ymax),
                      3: abs(xmin),
                      4: abs(ymin)}
        mask_height = {1: abs(ymax),
                       2: abs(xmin),
                       3: abs(ymin),
                       4: abs(xmax)}
        axs[0].add_patch(patches.Rectangle((0, 0), width=mask_width[quadrant],
                                           height=mask_height[quadrant],
                                           angle=mask_angles[quadrant],
                                           color='#E5E5E5', zorder=-1, alpha=0.8))
        # quadrant selection in maps
        non_quadrant = ~(moran_loc.q == quadrant)
        mask_quadrant = gdf[non_quadrant]
        df_quadrant = gdf.iloc[~non_quadrant]
        union2 = df_quadrant.unary_union.boundary

        # LISA Cluster mask and cluster boundary
        with warnings.catch_warnings():  # temorarily surpress geopandas warning
            warnings.filterwarnings('ignore', category=UserWarning)
            mask_quadrant.plot(column=attribute, scheme=scheme, color='white',
                               ax=axs[1], alpha=0.7, zorder=1)
        gpd.GeoSeries([union2]).plot(linewidth=1, ax=axs[1], color='#E5E5E5')

        # CHOROPLETH MASK
        with warnings.catch_warnings():  # temorarily surpress geopandas warning
            warnings.filterwarnings('ignore', category=UserWarning)
            mask_quadrant.plot(column=attribute, scheme=scheme, color='white',
                           ax=axs[2], alpha=0.7, zorder=1)
        gpd.GeoSeries([union2]).plot(linewidth=1, ax=axs[2], color='#E5E5E5')

    # REGION MASKING
    if region_column is not None:
        # masking inside axs[0] or Moran Scatterplot
        ix = gdf[region_column].isin(mask)
        df_mask = gdf[ix]
        x_mask = moran_loc.z[ix]
        y_mask = lag_spatial(moran_loc.w, moran_loc.z)[ix]
        axs[0].plot(x_mask, y_mask, color=mask_color, marker='o',
                    markersize=14, alpha=.8, linestyle="None", zorder=-1)

        # masking inside axs[1] or Lisa cluster map
        union = df_mask.unary_union.boundary
        gpd.GeoSeries([union]).plot(linewidth=2, ax=axs[1], color=mask_color)

        # masking inside axs[2] or Chloropleth
        gpd.GeoSeries([union]).plot(linewidth=2, ax=axs[2], color=mask_color)
    return fig, axs
Exemple #14
0
def _moran_loc_scatterplot(moran_loc, zstandard=True, p=None,
                          ax=None, scatter_kwds=None, fitline_kwds=None):
    """
    Moran Scatterplot with option of coloring of Local Moran Statistics

    Parameters
    ----------
    moran_loc : esda.moran.Moran_Local instance
        Values of Moran's I Local Autocorrelation Statistics
    p : float, optional
        If given, the p-value threshold for significance. Points will
        be colored by significance. By default it will not be colored.
        Default =None.
    ax : Matplotlib Axes instance, optional
        If given, the Moran plot will be created inside this axis.
        Default =None.
    scatter_kwds : keyword arguments, optional
        Keywords used for creating and designing the scatter points.
        Default =None.
    fitline_kwds : keyword arguments, optional
        Keywords used for creating and designing the moran fitline.
        Default =None.

    Returns
    -------
    fig : Matplotlib Figure instance
        Moran Local scatterplot figure
    ax : matplotlib Axes instance
        Axes in which the figure is plotted

    Examples
    --------
    Imports
    
    >>> import matplotlib.pyplot as plt
    >>> import geopandas as gpd
    >>> from pysal.lib.weights.contiguity import Queen
    >>> from pysal.lib import examples
    >>> from pysal.explore.esda.moran import Moran_Local
    >>> from pysal.viz.splot.esda import moran_scatterplot
    
    Load data and calculate Moran Local statistics
    
    >>> link = examples.get_path('Guerry.shp')
    >>> gdf = gpd.read_file(link)
    >>> y = gdf['Donatns'].values
    >>> w = Queen.from_dataframe(gdf)
    >>> w.transform = 'r'
    >>> m = Moran_Local(y, w)
    
    plot
    
    >>> moran_scatterplot(m)
    >>> plt.show()
    
    customize plot
    
    >>> moran_scatterplot(m, p=0.05,
    ...                   fitline_kwds=dict(color='#4393c3'))
    >>> plt.show()
    
    """
    # to set default as an empty dictionary that is later filled with defaults
    if scatter_kwds is None:
        scatter_kwds = dict()
    if fitline_kwds is None:
        fitline_kwds = dict()

    if p is not None:
        if not isinstance(moran_loc, Moran_Local):
            raise ValueError("`moran_loc` is not a\n " +
                             "esda.moran.Moran_Local instance")
        if 'color' in scatter_kwds or 'c' in scatter_kwds or 'cmap' in scatter_kwds:
            warnings.warn('To change the color use cmap with a colormap of 5,\n' +
                          ' color defines the LISA category')

        # colors
        spots = moran_hot_cold_spots(moran_loc, p)
        hmap = colors.ListedColormap(['#bababa', '#d7191c', '#abd9e9',
                                      '#2c7bb6', '#fdae61'])

    # define customization
    scatter_kwds.setdefault('alpha', 0.6)
    scatter_kwds.setdefault('s', 40)
    fitline_kwds.setdefault('alpha', 0.9)

    # get fig and ax
    fig, ax = _create_moran_fig_ax(ax, figsize=(7,7))
    
    # set labels
    ax.set_xlabel('Attribute')
    ax.set_ylabel('Spatial Lag')
    ax.set_title('Moran Local Scatterplot')

    # plot and set standards
    if zstandard is True:
        lag = lag_spatial(moran_loc.w, moran_loc.z)
        fit = OLS(moran_loc.z[:, None], lag[:, None])
        # v- and hlines
        ax.axvline(0, alpha=0.5, color='k', linestyle='--')
        ax.axhline(0, alpha=0.5, color='k', linestyle='--')
        if p is not None:
            fitline_kwds.setdefault('color', 'k')
            scatter_kwds.setdefault('cmap', hmap)
            scatter_kwds.setdefault('c', spots)
            ax.plot(lag, fit.predy, **fitline_kwds)
            ax.scatter(moran_loc.z, fit.predy,
                       **scatter_kwds)
        else:
            scatter_kwds.setdefault('color', splot_colors['moran_base'])
            fitline_kwds.setdefault('color', splot_colors['moran_fit'])
            ax.plot(lag, fit.predy, **fitline_kwds)
            ax.scatter(moran_loc.z, fit.predy, **scatter_kwds)
    else:
        lag = lag_spatial(moran_loc.w, moran_loc.y)
        b, a = np.polyfit(moran_loc.y, lag, 1)
        # dashed vert at mean of the attribute
        ax.vlines(moran_loc.y.mean(), lag.min(), lag.max(), alpha=0.5,
                  linestyle='--')
        # dashed horizontal at mean of lagged attribute
        ax.hlines(lag.mean(), moran_loc.y.min(), moran_loc.y.max(), alpha=0.5,
                  linestyle='--')
        if p is not None:
            fitline_kwds.setdefault('color', 'k')
            scatter_kwds.setdefault('cmap', hmap)
            scatter_kwds.setdefault('c', spots)
            ax.plot(moran_loc.y, a + b*moran_loc.y, **fitline_kwds)
            ax.scatter(moran_loc.y, lag, **scatter_kwds)
        else:
            scatter_kwds.setdefault('c', splot_colors['moran_base'])
            fitline_kwds.setdefault('color', splot_colors['moran_fit'])
            ax.plot(moran_loc.y, a + b*moran_loc.y, **fitline_kwds)
            ax.scatter(moran_loc.y, lag, **scatter_kwds)
    return fig, ax
Exemple #15
0
def _moran_bv_scatterplot(moran_bv, ax=None, scatter_kwds=None, fitline_kwds=None):
    """
    Bivariate Moran Scatterplot.

    Parameters
    ----------
    moran_bv : esda.moran.Moran_BV instance
        Values of Bivariate Moran's I Autocorrelation Statistics
    ax : Matplotlib Axes instance, optional
        If given, the Moran plot will be created inside this axis.
        Default =None.
    scatter_kwds : keyword arguments, optional
        Keywords used for creating and designing the scatter points.
        Default =None.
    fitline_kwds : keyword arguments, optional
        Keywords used for creating and designing the moran fitline.
        Default =None.

    Returns
    -------
    fig : Matplotlib Figure instance
        Bivariate moran scatterplot figure
    ax : matplotlib Axes instance
        Axes in which the figure is plotted

    Examples
    --------
    Imports
    
    >>> import matplotlib.pyplot as plt
    >>> from pysal.lib.weights.contiguity import Queen
    >>> from pysal.lib import examples
    >>> import geopandas as gpd
    >>> from pysal.explore.esda.moran import Moran_BV
    >>> from pysal.viz.splot.esda import moran_scatterplot
    
    Load data and calculate weights
    
    >>> link_to_data = examples.get_path('Guerry.shp')
    >>> gdf = gpd.read_file(link_to_data)
    >>> x = gdf['Suicids'].values
    >>> y = gdf['Donatns'].values
    >>> w = Queen.from_dataframe(gdf)
    >>> w.transform = 'r'
    
    Calculate Bivariate Moran
    
    >>> moran_bv = Moran_BV(x, y, w)
    
    plot
    
    >>> moran_scatterplot(moran_bv)
    >>> plt.show()
    
    customize plot
    
    >>> moran_scatterplot(moran_bv,
    ...                      fitline_kwds=dict(color='#4393c3'))
    >>> plt.show()
    
    """
    # to set default as an empty dictionary that is later filled with defaults
    if scatter_kwds is None:
        scatter_kwds = dict()
    if fitline_kwds is None:
        fitline_kwds = dict()

    # define customization
    scatter_kwds.setdefault('alpha', 0.6)
    scatter_kwds.setdefault('color', splot_colors['moran_base'])
    scatter_kwds.setdefault('s', 40)
    
    fitline_kwds.setdefault('alpha', 0.9)
    fitline_kwds.setdefault('color', splot_colors['moran_fit'])

    # get fig and ax
    fig, ax = _create_moran_fig_ax(ax, figsize=(7,7))
    
    # set labels
    ax.set_xlabel('Attribute X')
    ax.set_ylabel('Spatial Lag of Y')
    ax.set_title('Bivariate Moran Scatterplot' +
                 ' (' + str(round(moran_bv.I, 2)) + ')')

    # plot and set standards
    lag = lag_spatial(moran_bv.w, moran_bv.zy)
    fit = OLS(moran_bv.zy[:, None], lag[:, None])
    # plot
    ax.scatter(moran_bv.zx, lag, **scatter_kwds)
    ax.plot(lag, fit.predy, **fitline_kwds)
    # v- and hlines
    ax.axvline(0, alpha=0.5, color='k', linestyle='--')
    ax.axhline(0, alpha=0.5, color='k', linestyle='--')
    return fig, ax
Exemple #16
0
def _moran_global_scatterplot(moran, zstandard=True, ax=None,
                              scatter_kwds=None, fitline_kwds=None):
    """
    Global Moran's I Scatterplot.

    Parameters
    ----------
    moran : esda.moran.Moran instance
        Values of Moran's I Global Autocorrelation Statistics
    zstandard : bool, optional
        If True, Moran Scatterplot will show z-standardized attribute and
        spatial lag values. Default =True.
    ax : Matplotlib Axes instance, optional
        If given, the Moran plot will be created inside this axis.
        Default =None.
    scatter_kwds : keyword arguments, optional
        Keywords used for creating and designing the scatter points.
        Default =None.
    fitline_kwds : keyword arguments, optional
        Keywords used for creating and designing the moran fitline.
        Default =None.

    Returns
    -------
    fig : Matplotlib Figure instance
        Moran scatterplot figure
    ax : matplotlib Axes instance
        Axes in which the figure is plotted

    Examples
    --------
    Imports
    
    >>> import matplotlib.pyplot as plt
    >>> from pysal.lib.weights.contiguity import Queen
    >>> from pysal.lib import examples
    >>> import geopandas as gpd
    >>> from pysal.explore.esda.moran import Moran
    >>> from pysal.viz.splot.esda import moran_scatterplot
    
    Load data and calculate weights
    
    >>> link_to_data = examples.get_path('Guerry.shp')
    >>> gdf = gpd.read_file(link_to_data)
    >>> y = gdf['Donatns'].values
    >>> w = Queen.from_dataframe(gdf)
    >>> w.transform = 'r'
    
    Calculate Global Moran
    
    >>> moran = Moran(y, w)
    
    plot
    
    >>> moran_scatterplot(moran)
    >>> plt.show()
    
    customize plot
    
    >>> fig, ax = moran_scatterplot(moran, zstandard=False,
    ...                             fitline_kwds=dict(color='#4393c3'))
    >>> ax.set_xlabel('Donations')
    >>> plt.show()
    
    """
    # to set default as an empty dictionary that is later filled with defaults
    if scatter_kwds is None:
        scatter_kwds = dict()
    if fitline_kwds is None:
        fitline_kwds = dict()

    # define customization defaults
    scatter_kwds.setdefault('alpha', 0.6)
    scatter_kwds.setdefault('color', splot_colors['moran_base'])
    scatter_kwds.setdefault('s', 40)
    
    fitline_kwds.setdefault('alpha', 0.9)
    fitline_kwds.setdefault('color', splot_colors['moran_fit'])
    
    # get fig and ax
    fig, ax = _create_moran_fig_ax(ax, figsize=(7, 7))
    
    # set labels
    ax.set_xlabel('Attribute')
    ax.set_ylabel('Spatial Lag')
    ax.set_title('Moran Scatterplot' +
                 ' (' + str(round(moran.I, 2)) + ')')

    # plot and set standards
    if zstandard is True:
        lag = lag_spatial(moran.w, moran.z)
        fit = OLS(moran.z[:, None], lag[:, None])
        # plot
        ax.scatter(moran.z, lag, **scatter_kwds)
        ax.plot(lag, fit.predy, **fitline_kwds)
        # v- and hlines
        ax.axvline(0, alpha=0.5, color='k', linestyle='--')
        ax.axhline(0, alpha=0.5, color='k', linestyle='--')
    else:
        lag = lag_spatial(moran.w, moran.y)
        b, a = np.polyfit(moran.y, lag, 1)
        # plot
        ax.scatter(moran.y, lag, **scatter_kwds)
        ax.plot(moran.y, a + b*moran.y, **fitline_kwds)
        # dashed vert at mean of the attribute
        ax.vlines(moran.y.mean(), lag.min(), lag.max(), alpha=0.5,
                  linestyle='--')
        # dashed horizontal at mean of lagged attribute
        ax.hlines(lag.mean(), moran.y.min(), moran.y.max(), alpha=0.5,
                  linestyle='--')
    return fig, ax