Skip to content

Commit

Permalink
Merge pull request #359 from martinfleis/missing
Browse files Browse the repository at this point in the history
ENH: move moran_facet plotting from splot
  • Loading branch information
knaaptime authored Jan 21, 2025
2 parents 89e3ddd + 634e5c5 commit 8ae798d
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 1 deletion.
1 change: 1 addition & 0 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ Moran Statistics
esda.Moran_Local_BV
esda.Moran_Rate
esda.Moran_Local_Rate
esda.plot_moran_facet


Shape Statistics
Expand Down
1 change: 1 addition & 0 deletions esda/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
Moran_Local_BV,
Moran_Local_Rate,
Moran_Rate,
plot_moran_facet,
)
from .silhouettes import boundary_silhouette, path_silhouette # noqa F401
from .smaup import Smaup # noqa F401
Expand Down
112 changes: 111 additions & 1 deletion esda/moran.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"Levi John Wolf <[email protected]>"
)

from warnings import simplefilter, warn
from warnings import simplefilter

import numpy as np
import pandas as pd
Expand All @@ -32,6 +32,7 @@
"Moran_Local_BV",
"Moran_Rate",
"Moran_Local_Rate",
"plot_moran_facet",
]

PERMUTATIONS = 999
Expand Down Expand Up @@ -784,6 +785,115 @@ def _Moran_BV_Matrix_array(variables, w, permutations=0, varnames=None): # noqa
return results


def plot_moran_facet(
moran_matrix,
figsize=(16, 12),
scatter_bv_kwds=None,
fitline_bv_kwds=None,
scatter_glob_kwds=dict(color="#737373"),
fitline_glob_kwds=None,
):
"""
Moran Facet visualization.
A matrix containing bivariate Moran plots between all pairs of variables present in
the ``moran_matrix`` dictionary. On the diagonal contains global Moran plot.
Parameters
----------
moran_matrix : dict
Dictionary of Moran_BV objects returned by Moran_BV_matrix
figsize : tuple, optional
Size of the figure. Default is (16,12)
scatter_bv_kwds : keyword arguments, optional
Keywords used for creating and designing the scatter points of
off-diagonal Moran_BV plots.
Default =None.
fitline_bv_kwds : keyword arguments, optional
Keywords used for creating and designing the moran fitline of
off-diagonal Moran_BV plots.
Default =None.
scatter_glob_kwds : keyword arguments, optional
Keywords used for creating and designing the scatter points of
diagonal Moran plots.
Default =None.
fitline_glob_kwds : keyword arguments, optional
Keywords used for creating and designing the moran fitline of
diagonal Moran plots.
Default =None.
Returns
-------
ax : matplotlib Axes instance
Axes in which the figure is plotted
"""
try:
from matplotlib import pyplot as plt
except ImportError as err:
raise ImportError(
"matplotlib must be installed to plot the simulation."
) from err

nrows = int(np.sqrt(len(moran_matrix))) + 1
ncols = nrows

fig, axarr = plt.subplots(nrows, ncols, figsize=figsize, sharey=True, sharex=True)
fig.suptitle("Moran Facet")

for row in range(nrows):
for col in range(ncols):
if row == col:
global_m = Moran(
moran_matrix[row, (row + 1) % 4].zy,
moran_matrix[row, (row + 1) % 4].w,
)
_scatterplot(
global_m,
crit_value=None,
ax=axarr[row, col],
scatter_kwds=scatter_glob_kwds,
fitline_kwds=fitline_glob_kwds,
)
axarr[row, col].set_facecolor("#d9d9d9")
else:
_scatterplot(
moran_matrix[row, col],
bivariate=True,
crit_value=None,
ax=axarr[row, col],
scatter_kwds=scatter_bv_kwds,
fitline_kwds=fitline_bv_kwds,
)

axarr[row, col].spines[["left", "right", "top", "bottom"]].set_visible(
False
)
if row == nrows - 1:
axarr[row, col].set_xlabel(
str(moran_matrix[(col + 1) % 4, col].varnames["x"]).format(col)
)
axarr[row, col].spines["bottom"].set_visible(True)
else:
axarr[row, col].set_xlabel("")

if col == 0:
axarr[row, col].set_ylabel(
(
"Spatial Lag of "
+ str(moran_matrix[row, (row + 1) % 4].varnames["y"])
).format(row)
)
axarr[row, col].spines["left"].set_visible(True)
else:
axarr[row, col].set_ylabel("")

axarr[row, col].set_title("")

plt.tight_layout()

return axarr


class Moran_Rate(Moran): # noqa: N801
"""
Adjusted Moran's I Global Autocorrelation Statistic for Rate
Expand Down
20 changes: 20 additions & 0 deletions esda/tests/test_moran.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,26 @@ def test_Moran_BV_matrix(self, w):
np.testing.assert_allclose(res[(0, 1)].I, 0.19362610652874668)
np.testing.assert_allclose(res[(3, 0)].I, 0.37701382542927858)

@parametrize_sids
def test_plot_moran_facet(self, w):
matrix = moran.Moran_BV_matrix(self.vars, w, varnames=self.names)
axes = moran.plot_moran_facet(matrix)
assert axes.shape == (4, 4)

assert axes[0][0].spines["left"].get_visible()
assert not axes[0][0].spines["bottom"].get_visible()
assert axes[3][0].spines["left"].get_visible()
assert axes[3][0].spines["bottom"].get_visible()
assert not axes[3][1].spines["left"].get_visible()
assert axes[3][1].spines["bottom"].get_visible()
assert not axes[1][1].spines["left"].get_visible()
assert not axes[1][1].spines["bottom"].get_visible()

np.testing.assert_array_almost_equal(
axes[1][1].get_facecolor(),
(0.8509803921568627, 0.8509803921568627, 0.8509803921568627, 1.0),
)


class TestMoranLocal:
def setup_method(self):
Expand Down

0 comments on commit 8ae798d

Please sign in to comment.