Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

COMPAT: compatibility with numpy #147

Merged
merged 3 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ci/envs/310-minimal.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ dependencies:
- pandas=1.4
- scipy=1.10
- shapely=2
- fiona<1.10
# tests
- scikit-learn=1.2
- statsmodels
Expand Down
2 changes: 2 additions & 0 deletions pointpats/centrography.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,8 @@ def mean_center(points):
return points.mean(axis=0)




def weighted_mean_center(points, weights):
"""
Find weighted mean center of a marked point pattern.
Expand Down
68 changes: 36 additions & 32 deletions pointpats/pointpattern.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,20 @@
Planar Point Pattern Class

"""

import numpy as np
import sys
from libpysal.cg import KDTree
from .centrography import hull
from .window import as_window, poly_from_bbox
from .window import as_window, poly_from_bbox
from .util import cached_property
import pandas as pd
from matplotlib import pyplot as plt
from matplotlib.collections import PatchCollection
from matplotlib.patches import Polygon

__author__ = "Serge Rey [email protected]"
__all__ = ['PointPattern']
__all__ = ["PointPattern"]

if sys.version_info[0] > 2:
xrange = range
Expand Down Expand Up @@ -63,8 +64,8 @@
7638.200000000001

"""
def __init__(self, points, window=None, names=None, coord_names=None):

def __init__(self, points, window=None, names=None, coord_names=None):
# first two series in df are x, y unless coor_names and names are
# specified

Expand All @@ -75,12 +76,12 @@
if names is not None:
coord_names = names[:2]
else:
coord_names = ['x', 'y']
coord_names = ["x", "y"]
if names is None:
col_names = coord_names
if p > 2:
for m in range(2, p):
col_names.append("mark_{}".format(m-2))
col_names.append("mark_{}".format(m - 2))

Check warning on line 84 in pointpats/pointpattern.py

View check run for this annotation

Codecov / codecov/patch

pointpats/pointpattern.py#L84

Added line #L84 was not covered by tests
coord_names = coord_names[:2]
else:
col_names = names
Expand Down Expand Up @@ -143,19 +144,19 @@

:class:`.window.Window`
"""
if not hasattr(self, '_window') or self._window is None:
if not hasattr(self, "_window") or self._window is None:

Check warning on line 147 in pointpats/pointpattern.py

View check run for this annotation

Codecov / codecov/patch

pointpats/pointpattern.py#L147

Added line #L147 was not covered by tests
# use bbox as window
self.set_window(as_window(poly_from_bbox(self.mbb)))
return self._window

window = property(get_window, set_window)

def summary(self):
'''
"""
Description of the point pattern.
'''
"""

print('Point Pattern')
print("Point Pattern")

Check warning on line 159 in pointpats/pointpattern.py

View check run for this annotation

Codecov / codecov/patch

pointpats/pointpattern.py#L159

Added line #L159 was not covered by tests
print("{} points".format(self.n))
print("Bounding rectangle [({},{}), ({},{})]".format(*self.mbb))
print("Area of window: {}".format(self.window.area))
Expand All @@ -165,13 +166,12 @@
def add_marks(self, marks, mark_names=None):
if mark_names is None:
nm = range(len(marks))
mark_names = ["mark_{}".format(self._n_marks+1+j) for j in nm]
mark_names = ["mark_{}".format(self._n_marks + 1 + j) for j in nm]

Check warning on line 169 in pointpats/pointpattern.py

View check run for this annotation

Codecov / codecov/patch

pointpats/pointpattern.py#L169

Added line #L169 was not covered by tests
for name, mark in zip(mark_names, marks):
self.df[name] = mark
self._n_marks += 1

def plot(self, window=False, title="Point Pattern", hull=False,
get_ax=False):
def plot(self, window=False, title="Point Pattern", hull=False, get_ax=False):
"""
Plot function for a point pattern.

Expand All @@ -187,15 +187,15 @@
pattern. If not, don't plot convex hull.
get_ax : boolean
If get_ax is True, return the current plot ax.

Returns
-------
ax : matplotlib.axes._subplots.AxesSubplot
Current plot ax. Only return it when get_ax is True.

"""
fig, ax = plt.subplots()
plt.plot(self.df[self._x], self.df[self._y], '.')
plt.plot(self.df[self._x], self.df[self._y], ".")

Check warning on line 198 in pointpats/pointpattern.py

View check run for this annotation

Codecov / codecov/patch

pointpats/pointpattern.py#L198

Added line #L198 was not covered by tests
# plt.scatter(self.df[self._x], self.df[self._y])
plt.title(title)
if window:
Expand Down Expand Up @@ -234,7 +234,7 @@
Area of minimum bounding box
"""

return np.product(self.mbb[[2, 3]]-self.mbb[[0, 1]])
return np.prod(self.mbb[[2, 3]] - self.mbb[[0, 1]])

mbb_area = cached_property(_mbb_area)

Expand All @@ -253,15 +253,15 @@
One-quarter the smallest side of the mbb.
"""
w, s, e, n = self.mbb
return 0.25 * min(e-w, n-s)
return 0.25 * min(e - w, n - s)

Check warning on line 256 in pointpats/pointpattern.py

View check run for this annotation

Codecov / codecov/patch

pointpats/pointpattern.py#L256

Added line #L256 was not covered by tests

rot = cached_property(_rot)

def _lambda_mbb(self):
"""
Intensity based on minimum bounding box
"""
return self.n * 1. / self.mbb_area
return self.n * 1.0 / self.mbb_area

lambda_mbb = cached_property(_lambda_mbb)

Expand Down Expand Up @@ -304,24 +304,25 @@
Area of convex hull
"""
h = self.hull
if not np.alltrue(h[0] == h[-1]):
if not np.all(h[0] == h[-1]):
# not in closed cartographic form
h = np.vstack((h, h[0]))
s = h[:-1, 0] * h[1:, 1] - h[1:, 0] * h[:-1, 1]
return s.sum() / 2.
return s.sum() / 2.0

hull_area = cached_property(_hull_area)

def _lambda_hull(self):
"""
Intensity based on convex hull
"""
return self.n * 1. / self.hull_area
return self.n * 1.0 / self.hull_area

lambda_hull = cached_property(_lambda_hull)

def _build_tree(self):
return KDTree(self.points)

tree = cached_property(_build_tree)

def knn(self, k=1):
Expand All @@ -343,8 +344,8 @@
nearest neighbor
"""
if k < 1:
raise ValueError('k must be at least 1')
nn = self.tree.query(self.tree.data, k=k+1)
raise ValueError("k must be at least 1")
nn = self.tree.query(self.tree.data, k=k + 1)
return nn[1][:, 1:], nn[0][:, 1:]

def _nn_sum(self):
Expand Down Expand Up @@ -419,7 +420,7 @@
nearest neighbor
"""
if k < 1:
raise ValueError('k must be at least 1')
raise ValueError("k must be at least 1")
try:
nn = self.tree.query(np.asarray(other.points), k=k)
except:
Expand Down Expand Up @@ -447,10 +448,10 @@
pps = [self.df[self.df[mark] == v] for v in uv]
names = self.df.columns.values.tolist()
cnames = self.coord_names
return[PointPattern(pp, names=names, coord_names=cnames) for pp in pps]
return [PointPattern(pp, names=names, coord_names=cnames) for pp in pps]

def unique(self):
""" Remove duplicate points in the point pattern.
"""Remove duplicate points in the point pattern.

Two points in a point pattern are deemed to be identical if their
coordinates are the same, and their marks are the same (if any)
Expand All @@ -475,8 +476,9 @@
coord_names = self.coord_names
window = self.set_window
unique_df = self.df.drop_duplicates()
return PointPattern(unique_df, names=names, coord_names=coord_names,
window=window)
return PointPattern(

Check warning on line 479 in pointpats/pointpattern.py

View check run for this annotation

Codecov / codecov/patch

pointpats/pointpattern.py#L479

Added line #L479 was not covered by tests
unique_df, names=names, coord_names=coord_names, window=window
)

def superimpose(self, point_pattern):
"""Returns a superimposed point pattern.
Expand Down Expand Up @@ -511,14 +513,16 @@
names_pp2 = point_pattern.df.columns.values.tolist()
cnames_pp2 = point_pattern.coord_names
if names_pp1 != names_pp2 or cnames_pp1 != cnames_pp2:
raise TypeError('Both point patterns should have similar\
attributes and spatial coordinates ')
raise TypeError(

Check warning on line 516 in pointpats/pointpattern.py

View check run for this annotation

Codecov / codecov/patch

pointpats/pointpattern.py#L516

Added line #L516 was not covered by tests
"Both point patterns should have similar\
attributes and spatial coordinates "
)
pp = pd.concat((self.df, point_pattern.df))
pp = pp.drop_duplicates()
return PointPattern(pp, names=names_pp1, coord_names=cnames_pp1)

def flip_coordinates(self):
""" Flips the coordinates of a point pattern.
"""Flips the coordinates of a point pattern.

Doesn't change the structure of data frame. This function swaps
`_x` and `_y` variables, which are used to represent coordinates.
Expand All @@ -527,5 +531,5 @@

# Pandas facade
def _facade(self):
self.head = self.df.head
self.tail = self.df.tail
self.head = self.df.head
self.tail = self.df.tail