1""" 2Distance statistics for planar point patterns 3 4""" 5__author__ = "Serge Rey sjsrey@gmail.com" 6__all__ = [ 7 "DStatistic", 8 "G", 9 "F", 10 "J", 11 "K", 12 "L", 13 "Envelopes", 14 "Genv", 15 "Fenv", 16 "Jenv", 17 "Kenv", 18 "Lenv", 19] 20 21from .process import PoissonPointProcess as csr 22import numpy as np 23from matplotlib import pyplot as plt 24import warnings 25 26 27class DStatistic(object): 28 """ 29 Abstract Base Class for distance statistics. 30 31 Parameters 32 ---------- 33 name : string 34 Name of the function. ("G", "F", "J", "K" or "L") 35 36 Attributes 37 ---------- 38 d : array 39 The distance domain sequence. 40 41 """ 42 43 def __init__(self, name): 44 self.name = name 45 warnings.warn( 46 f"This class is deprecated! Please use the alternative function" 47 f" {name.lower()} in pointpats.distance_statistics.", 48 DeprecationWarning, 49 stacklevel=2, 50 ) 51 52 def plot(self, qq=False): 53 """ 54 Plot the distance function 55 56 Parameters 57 ---------- 58 qq: Boolean 59 If False the statistic is plotted against distance. If Frue, the 60 quantile-quantile plot is generated, observed vs. CSR. 61 """ 62 63 # assuming mpl 64 x = self.d 65 if qq: 66 plt.plot(self.ev, self._stat) 67 plt.plot(self.ev, self.ev) 68 else: 69 plt.plot(x, self._stat, label="{}".format(self.name)) 70 plt.ylabel("{}(d)".format(self.name)) 71 plt.xlabel("d") 72 plt.plot(x, self.ev, label="CSR") 73 plt.title("{} distance function".format(self.name)) 74 75 76class G(DStatistic): 77 """ 78 Estimates the nearest neighbor distance distribution function G for a 79 point pattern. 80 81 Parameters 82 ---------- 83 pp : :class:`.PointPattern` 84 Point Pattern instance. 85 intervals : int 86 The length of distance domain sequence. 87 dmin : float 88 The minimum of the distance domain. 89 dmax : float 90 The maximum of the distance domain. 91 d : sequence 92 The distance domain sequence. 93 If d is specified, intervals, dmin and dmax are ignored. 94 95 Attributes 96 ---------- 97 name : string 98 Name of the function. ("G", "F", "J", "K" or "L") 99 d : array 100 The distance domain sequence. 101 G : array 102 The cumulative nearest neighbor distance distribution over d. 103 104 Notes 105 ----- 106 In the analysis of planar point processes, the estimate of :math:`G` is 107 typically compared to the value expected from a completely spatial 108 random (CSR) process given as: 109 110 .. math:: 111 112 G(d) = 1 - e^{-\lambda \pi d^2} 113 114 where :math:`\lambda` is the intensity (points per unit area) of the point 115 process and :math:`d` is distance. 116 117 For a clustered pattern, the empirical function will be above the 118 expectation, while for a uniform pattern the empirical function falls below 119 the expectation. 120 121 """ 122 123 def __init__(self, pp, intervals=10, dmin=0.0, dmax=None, d=None): 124 res = _g(pp, intervals, dmin, dmax, d) 125 self.d = res[:, 0] 126 self.G = self._stat = res[:, 1] 127 self.ev = 1 - np.exp(-pp.lambda_window * np.pi * self.d * self.d) 128 self.pp = pp 129 super(G, self).__init__(name="G") 130 131 132class F(DStatistic): 133 """ 134 Estimates the empty space distribution function for a point pattern: F(d). 135 136 Parameters 137 ---------- 138 pp : :class:`.PointPattern` 139 Point Pattern instance. 140 n : int 141 Number of empty space points (random points). 142 intervals : int 143 The length of distance domain sequence. 144 dmin : float 145 The minimum of the distance domain. 146 dmax : float 147 The maximum of the distance domain. 148 d : sequence 149 The distance domain sequence. 150 If d is specified, intervals, dmin and dmax are ignored. 151 152 Attributes 153 ---------- 154 d : array 155 The distance domain sequence. 156 G : array 157 The cumulative empty space nearest event distance distribution 158 over d. 159 160 Notes 161 ----- 162 In the analysis of planar point processes, the estimate of :math:`F` is 163 typically compared to the value expected from a process that displays 164 complete spatial randomness (CSR): 165 166 .. math:: 167 168 F(d) = 1 - e^{-\lambda \pi d^2} 169 170 where :math:`\lambda` is the intensity (points per unit area) of the point 171 process and :math:`d` is distance. 172 173 The expectation is identical to the expectation for the :class:`G` function 174 for a CSR process. However, for a clustered pattern, the empirical G 175 function will be below the expectation, while for a uniform pattern the 176 empirical function falls above the expectation. 177 178 """ 179 180 def __init__(self, pp, n=100, intervals=10, dmin=0.0, dmax=None, d=None): 181 res = _f(pp, n, intervals, dmin, dmax, d) 182 self.d = res[:, 0] 183 self.F = self._stat = res[:, 1] 184 self.ev = 1 - np.exp(-pp.lambda_window * np.pi * self.d * self.d) 185 super(F, self).__init__(name="F") 186 187 188class J(DStatistic): 189 """ 190 Estimates the J function for a point pattern :cite:`VanLieshout1996` 191 192 Parameters 193 ---------- 194 pp : :class:`.PointPattern` 195 Point Pattern instance. 196 n : int 197 Number of empty space points (random points). 198 intervals : int 199 The length of distance domain sequence. 200 dmin : float 201 The minimum of the distance domain. 202 dmax : float 203 The maximum of the distance domain. 204 d : sequence 205 The distance domain sequence. 206 If d is specified, intervals, dmin and dmax are ignored. 207 208 Attributes 209 ---------- 210 d : array 211 The distance domain sequence. 212 j : array 213 F function over d. 214 215 Notes 216 ----- 217 218 The :math:`J` function is a ratio of the hazard functions defined for 219 :math:`G` and :math:`F`: 220 221 .. math:: 222 223 J(d) = \\frac{1-G(d) }{1-F(d)} 224 225 where :math:`G(d)` is the nearest neighbor distance distribution function 226 (see :class:`G`) 227 and :math:`F(d)` is the empty space function (see :class:`F`). 228 229 For a CSR process the J function equals 1. Empirical values larger than 1 230 are indicative of uniformity, while values below 1 suggest clustering. 231 232 233 """ 234 235 def __init__(self, pp, n=100, intervals=10, dmin=0.0, dmax=None, d=None): 236 res = _j(pp, n, intervals, dmin, dmax, d) 237 self.d = res[:, 0] 238 self.j = self._stat = res[:, 1] 239 self.ev = self.j / self.j 240 super(J, self).__init__(name="J") 241 242 243class K(DStatistic): 244 """ 245 Estimates the K function for a point pattern. 246 247 Parameters 248 ---------- 249 pp : :class:`.PointPattern` 250 Point Pattern instance. 251 intervals : int 252 The length of distance domain sequence. 253 dmin : float 254 The minimum of the distance domain. 255 dmax : float 256 The maximum of the distance domain. 257 d : sequence 258 The distance domain sequence. 259 If d is specified, intervals, dmin and dmax are ignored. 260 261 Attributes 262 ---------- 263 d : array 264 The distance domain sequence. 265 k : array 266 K function over d. 267 268 Notes 269 ----- 270 271 The :math:`K` function is estimated using 272 273 .. math:: 274 275 \\hat{K}(h) = \\frac{a}{n (n-1)} \\sum_{i} \\sum_{j \\ne i} I(d_{i,j} \\le h) 276 277 where :math:`a` is the area of the window, :math:`n` the number of event points, and :math:`I(d_{i,j} \le h)` is an indicator function returning 1 when points i and j are separated by a distance of :math:`h` or less, 0 otherwise. 278 279 """ 280 281 def __init__(self, pp, intervals=10, dmin=0.0, dmax=None, d=None): 282 res = _k(pp, intervals, dmin, dmax, d) 283 self.d = res[:, 0] 284 self.k = self._stat = res[:, 1] 285 self.ev = np.pi * self.d * self.d 286 super(K, self).__init__(name="K") 287 288 289class L(DStatistic): 290 """ 291 Estimates the :math:`L` function for a point pattern :cite:`Sullivan2010`. 292 293 Parameters 294 ---------- 295 pp : :class:`.PointPattern` 296 Point Pattern instance. 297 intervals : int 298 The length of distance domain sequence. 299 dmin : float 300 The minimum of the distance domain. 301 dmax : float 302 The maximum of the distance domain. 303 d : sequence 304 The distance domain sequence. 305 If d is specified, intervals, dmin and dmax are ignored. 306 307 Attributes 308 ---------- 309 d : array 310 The distance domain sequence. 311 l : array 312 L function over d. 313 314 Notes 315 ----- 316 317 In the analysis of planar point processes, the :math:`L` function 318 is a scaled version of :math:`K` function. Its estimate is also 319 typically compared to the value expected from a process that displays 320 complete spatial randomness (CSR): 321 322 .. math:: 323 324 L(d) = \\sqrt{\\frac{K(d)}{\\pi}}-d 325 326 where :math:`K(d)` is the estimator for the :math:`K` function 327 and :math:`d` is distance. 328 329 The expectation under the null of CSR is 0 (a horizonal line at 0). 330 For a clustered pattern, the empirical :math:`L` 331 function will be above the expectation, while for a uniform pattern the 332 empirical function falls below the expectation. 333 334 """ 335 336 def __init__(self, pp, intervals=10, dmin=0.0, dmax=None, d=None): 337 res = _l(pp, intervals, dmin, dmax, d) 338 self.d = res[:, 0] 339 self.l = self._stat = res[:, 1] 340 super(L, self).__init__(name="L") 341 342 def plot(self): 343 # assuming mpl 344 x = self.d 345 plt.plot(x, self._stat, label="{}".format(self.name)) 346 plt.ylabel("{}(d)".format(self.name)) 347 plt.xlabel("d") 348 plt.title("{} distance function".format(self.name)) 349 350 351def _g(pp, intervals=10, dmin=0.0, dmax=None, d=None): 352 """ 353 Estimate the nearest neighbor distances function G. 354 355 Parameters 356 ---------- 357 pp : :class:`.PointPattern` 358 Point Pattern instance. 359 intevals : int 360 Number of intervals to evaluate F over. 361 dmin : float 362 Lower limit of distance range. 363 dmax : float 364 Upper limit of distance range. If dmax is None, dmax will be set 365 to maximum nearest neighor distance. 366 d : sequence 367 The distance domain sequence. If d is specified, intervals, dmin 368 and dmax are ignored. 369 370 Returns 371 ------- 372 : array 373 A 2-dimensional numpy array of 2 columns. The first column is 374 the distance domain sequence for the point pattern. The second 375 column is the cumulative nearest neighbor distance distribution. 376 377 Notes 378 ----- 379 See :class:`G`. 380 381 """ 382 if d is None: 383 w = pp.max_nnd / intervals 384 if dmax: 385 w = dmax / intervals 386 d = [w * i for i in range(intervals + 2)] 387 cdf = [0] * len(d) 388 for i, d_i in enumerate(d): 389 smaller = [nndi for nndi in pp.nnd if nndi <= d_i] 390 cdf[i] = len(smaller) * 1.0 / pp.n 391 return np.vstack((d, cdf)).T 392 393 394def _f(pp, n=100, intervals=10, dmin=0.0, dmax=None, d=None): 395 """ 396 F empty space function. 397 398 Parameters 399 ---------- 400 pp : :class:`.PointPattern` 401 Point Pattern instance. 402 n : int 403 Number of empty space points (random points). 404 intevals : int 405 Number of intervals to evaluate F over. 406 dmin : float 407 Lower limit of distance range. 408 dmax : float 409 Upper limit of distance range. If dmax is None, dmax will be set 410 to maximum nearest neighor distance. 411 d : sequence 412 The distance domain sequence. If d is specified, intervals, dmin 413 and dmax are ignored. 414 415 Returns 416 ------- 417 : array 418 A 2-dimensional numpy array of 2 columns. The first column is 419 the distance domain sequence for the point pattern. The second 420 column is corresponding F function. 421 422 Notes 423 ----- 424 See :class:`.F` 425 426 """ 427 428 # get a csr pattern in window of pp 429 c = csr(pp.window, n, 1, asPP=True).realizations[0] 430 # for each point in csr pattern find the closest point in pp and the 431 # associated distance 432 nnids, nnds = pp.knn_other(c, k=1) 433 434 if d is None: 435 w = pp.max_nnd / intervals 436 if dmax: 437 w = dmax / intervals 438 d = [w * i for i in range(intervals + 2)] 439 cdf = [0] * len(d) 440 441 for i, d_i in enumerate(d): 442 smaller = [nndi for nndi in nnds if nndi <= d_i] 443 cdf[i] = len(smaller) * 1.0 / n 444 return np.vstack((d, cdf)).T 445 446 447def _j(pp, n=100, intervals=10, dmin=0.0, dmax=None, d=None): 448 """ 449 J function: Ratio of hazard functions for F and G. 450 451 Parameters 452 ---------- 453 pp : :class:`.PointPattern` 454 Point Pattern instance. 455 n : int 456 Number of empty space points (random points). 457 intevals : int 458 Number of intervals to evaluate F over. 459 dmin : float 460 Lower limit of distance range. 461 dmax : float 462 Upper limit of distance range. If dmax is None, dmax will be set 463 to maximum nearest neighor distance. 464 d : sequence 465 The distance domain sequence. If d is specified, intervals, dmin 466 and dmax are ignored. 467 468 Returns 469 ------- 470 : array 471 A 2-dimensional numpy array of 2 columns. The first column is 472 the distance domain sequence for the point pattern. The second 473 column is corresponding J function. 474 475 Notes 476 ----- 477 See :class:`.J` 478 479 """ 480 481 F = _f(pp, n, intervals=intervals, dmin=dmin, dmax=dmax, d=d) 482 G = _g(pp, intervals=intervals, dmin=dmin, dmax=dmax, d=d) 483 FC = 1 - F[:, 1] 484 GC = 1 - G[:, 1] 485 last_id = len(GC) + 1 486 if np.any(FC == 0): 487 last_id = np.where(FC == 0)[0][0] 488 489 return np.vstack((F[:last_id, 0], GC[:last_id] / FC[:last_id])).T 490 491 492def _k(pp, intervals=10, dmin=0.0, dmax=None, d=None): 493 """ 494 Interevent K function. 495 496 Parameters 497 ---------- 498 pp : :class:`.PointPattern` 499 Point Pattern instance. 500 n : int 501 Number of empty space points (random points). 502 intevals : int 503 Number of intervals to evaluate F over. 504 dmin : float 505 Lower limit of distance range. 506 dmax : float 507 Upper limit of distance range. If dmax is None, dmax will be set to one-quarter of the minimum side of the minimum bounding rectangle. 508 d : sequence 509 The distance domain sequence. If d is specified, intervals, dmin 510 and dmax are ignored. 511 512 Returns 513 ------- 514 kcdf : array 515 A 2-dimensional numpy array of 2 columns. The first column is 516 the distance domain sequence for the point pattern. The second 517 column is corresponding K function. 518 519 Notes 520 ----- 521 522 See :class:`.K` 523 """ 524 525 if d is None: 526 w = pp.rot / intervals 527 if dmax: 528 w = dmax / intervals 529 d = [w * i for i in range(intervals + 2)] 530 den = pp.lambda_window * (pp.n - 1) 531 kcdf = np.asarray([(di, len(pp.tree.query_pairs(di)) * 2 / den) for di in d]) 532 return kcdf 533 534 535def _l(pp, intervals=10, dmin=0.0, dmax=None, d=None): 536 """ 537 Interevent L function. 538 539 Parameters 540 ---------- 541 pp : :class:`.PointPattern` 542 Point Pattern instance. 543 n : int 544 Number of empty space points (random points). 545 intevals : int 546 Number of intervals to evaluate F over. 547 dmin : float 548 Lower limit of distance range. 549 dmax : float 550 Upper limit of distance range. If dmax is None, dmax will be set 551 to length of bounding box diagonal. 552 d : sequence 553 The distance domain sequence. If d is specified, intervals, dmin 554 and dmax are ignored. 555 556 Returns 557 ------- 558 kf : array 559 A 2-dimensional numpy array of 2 columns. The first column is 560 the distance domain sequence for the point pattern. The second 561 column is corresponding L function. 562 563 Notes 564 ----- 565 See :class:`.L` 566 567 """ 568 569 kf = _k(pp, intervals, dmin, dmax, d) 570 kf[:, 1] = np.sqrt(kf[:, 1] / np.pi) - kf[:, 0] 571 return kf 572 573 574class Envelopes(object): 575 """ 576 Abstract base class for simulation envelopes. 577 578 Parameters 579 ---------- 580 pp : :class:`.PointPattern` 581 Point Pattern instance. 582 intervals : int 583 The length of distance domain sequence. Default is 10. 584 dmin : float 585 The minimum of the distance domain. 586 dmax : float 587 The maximum of the distance domain. 588 d : sequence 589 The distance domain sequence. 590 If d is specified, intervals, dmin and dmax are ignored. 591 pct : float 592 1-alpha, alpha is the significance level. Default is 0.05, 593 1-alpha is the confidence level for the envelope. 594 realizations: :class:`.PointProcess` 595 Point process instance with more than 1 realizations. 596 597 Attributes 598 ---------- 599 name : string 600 Name of the function. ("G", "F", "J", "K" or "L") 601 observed : array 602 A 2-dimensional numpy array of 2 columns. The first column is 603 the distance domain sequence for the observed point pattern. 604 The second column is the specific function ("G", "F", "J", 605 "K" or "L") over the distance domain sequence for the 606 observed point pattern. 607 low : array 608 A 1-dimensional numpy array. Lower bound of the simulation 609 envelope. 610 high : array 611 A 1-dimensional numpy array. Higher bound of the simulation 612 envelope. 613 mean : array 614 A 1-dimensional numpy array. Mean values of the simulation 615 envelope. 616 617 """ 618 619 def __init__(self, *args, **kwargs): 620 # setup arguments 621 self.name = kwargs["name"] 622 warnings.warn( 623 f"This class is deprecated! Please use the alternative statistical test" 624 f" {self.name.lower()}_test in pointpats.distance_statistics.", 625 DeprecationWarning, 626 stacklevel=2, 627 ) 628 629 # calculate observed function 630 self.pp = args[0] 631 self.observed = self.calc(*args, **kwargs) 632 self.d = self.observed[:, 0] # domain to be used in all realizations 633 634 # do realizations 635 self.mapper(kwargs["realizations"]) 636 637 def mapper(self, realizations): 638 reals = realizations.realizations 639 res = np.asarray([self.calc(reals[p]) for p in reals]) 640 641 # When calculating the J function for all the simulations, the length 642 # of the returned interval domains might be different. 643 644 if self.name == "J": 645 res = [] 646 for p in reals: 647 j = self.calc(reals[p]) 648 if j.shape[0] < self.d.shape[0]: 649 diff = self.d.shape[0] - j.shape[0] 650 for i in range(diff): 651 j = np.append(j, [[self.d[i + diff], np.inf]], axis=0) 652 res.append(j) 653 res = np.array(res) 654 655 res = res[:, :, -1] 656 res.sort(axis=0) 657 nres = len(res) 658 self.low = res[np.int(nres * self.pct / 2.0)] 659 self.high = res[np.int(nres * (1 - self.pct / 2.0))] 660 self.mean = res.mean(axis=0) 661 662 def calc(self, *args, **kwargs): 663 print("implement in subclass") 664 665 def plot(self): 666 # assuming mpl 667 x = self.d 668 plt.plot(x, self.observed[:, 1], label="{}".format(self.name)) 669 plt.plot(x, self.mean, "g-.", label="CSR") 670 plt.plot(x, self.low, "r-.", label="LB") 671 plt.plot(x, self.high, "r-.", label="UB") 672 plt.ylabel("{}(d)".format(self.name)) 673 plt.xlabel("d") 674 plt.title("{} Simulation Envelopes".format(self.name)) 675 plt.legend(loc=0) 676 677 678class Genv(Envelopes): 679 """ 680 Simulation envelope for G function. 681 682 Parameters 683 ---------- 684 pp : :class:`.PointPattern` 685 Point Pattern instance. 686 intervals : int 687 The length of distance domain sequence. Default is 10. 688 dmin : float 689 The minimum of the distance domain. 690 dmax : float 691 Upper limit of distance range. If dmax is None, dmax will be 692 set to maximum nearest neighbor distance. 693 d : sequence 694 The distance domain sequence. 695 If d is specified, intervals, dmin and dmax are ignored. 696 pct : float 697 1-alpha, alpha is the significance level. Default is 0.05, 698 which means 95% confidence level for the envelopes. 699 realizations: :class:`.PointProcess` 700 Point process instance with more than 1 realizations. 701 702 Attributes 703 ---------- 704 name : string 705 Name of the function. ("G", "F", "J", "K" or "L") 706 observed : array 707 A 2-dimensional numpy array of 2 columns. The first column is 708 the distance domain sequence for the observed point pattern. 709 The second column is cumulative nearest neighbor distance 710 distribution (G function) for the observed point pattern. 711 low : array 712 A 1-dimensional numpy array. Lower bound of the simulation 713 envelope. 714 high : array 715 A 1-dimensional numpy array. Higher bound of the simulation 716 envelope. 717 mean : array 718 A 1-dimensional numpy array. Mean values of the simulation 719 envelope. 720 721 Examples 722 -------- 723 .. plot:: 724 725 >>> import libpysal as ps 726 >>> from pointpats import Genv, PoissonPointProcess, Window 727 >>> from libpysal.cg import shapely_ext 728 >>> va = ps.io.open(ps.examples.get_path("vautm17n.shp")) 729 >>> polys = [shp for shp in va] 730 >>> state = shapely_ext.cascaded_union(polys) 731 >>> pp = PoissonPointProcess(Window(state.parts), 100, 1, asPP=True).realizations[0] 732 >>> csrs = PoissonPointProcess(pp.window, 100, 100, asPP=True) 733 >>> genv_bb = Genv(pp, realizations=csrs) 734 >>> genv_bb.plot() 735 736 """ 737 738 def __init__( 739 self, pp, intervals=10, dmin=0.0, dmax=None, d=None, pct=0.05, realizations=None 740 ): 741 self.pp = pp 742 self.intervals = intervals 743 self.dmin = dmin 744 self.dmax = dmax 745 self.d = d 746 self.pct = pct 747 super(Genv, self).__init__(pp, realizations=realizations, name="G") 748 749 def calc(self, *args, **kwargs): 750 pp = args[0] 751 return _g( 752 pp, intervals=self.intervals, dmin=self.dmin, dmax=self.dmax, d=self.d 753 ) 754 755 756class Fenv(Envelopes): 757 """ 758 Simulation envelope for F function. 759 760 Parameters 761 ---------- 762 pp : :class:`.PointPattern` 763 Point Pattern instance. 764 n : int 765 Number of empty space points (random points). 766 intervals : int 767 The length of distance domain sequence. Default is 10. 768 dmin : float 769 The minimum of the distance domain. 770 dmax : float 771 Upper limit of distance range. If dmax is None, dmax will be 772 set to maximum nearest neighbor distance. 773 d : sequence 774 The distance domain sequence. 775 If d is specified, intervals, dmin and dmax are ignored. 776 pct : float 777 1-alpha, alpha is the significance level. Default is 0.05, 778 which means 95% confidence level for the envelopes. 779 realizations: :class:`.PointProcess` 780 Point process instance with more than 1 realizations. 781 782 Attributes 783 ---------- 784 name : string 785 Name of the function. ("G", "F", "J", "K" or "L") 786 observed : array 787 A 2-dimensional numpy array of 2 columns. The first column is 788 the distance domain sequence for the observed point pattern. 789 The second column is F function for the observed point 790 pattern. 791 low : array 792 A 1-dimensional numpy array. Lower bound of the simulation 793 envelope. 794 high : array 795 A 1-dimensional numpy array. Higher bound of the simulation 796 envelope. 797 mean : array 798 A 1-dimensional numpy array. Mean values of the simulation 799 envelope. 800 801 Examples 802 -------- 803 .. plot:: 804 805 >>> import libpysal as ps 806 >>> from libpysal.cg import shapely_ext 807 >>> from pointpats import PoissonPointProcess,Window,Fenv 808 >>> va = ps.io.open(ps.examples.get_path("vautm17n.shp")) 809 >>> polys = [shp for shp in va] 810 >>> state = shapely_ext.cascaded_union(polys) 811 >>> pp = PoissonPointProcess(Window(state.parts), 100, 1, asPP=True).realizations[0] 812 >>> csrs = PoissonPointProcess(pp.window, 100, 100, asPP=True) 813 >>> fenv = Fenv(pp, realizations=csrs) 814 >>> fenv.plot() 815 816 """ 817 818 def __init__( 819 self, 820 pp, 821 n=100, 822 intervals=10, 823 dmin=0.0, 824 dmax=None, 825 d=None, 826 pct=0.05, 827 realizations=None, 828 ): 829 self.pp = pp 830 self.n = n 831 self.intervals = intervals 832 self.dmin = dmin 833 self.dmax = dmax 834 self.d = d 835 self.pct = pct 836 super(Fenv, self).__init__(pp, realizations=realizations, name="F") 837 838 def calc(self, *args, **kwargs): 839 pp = args[0] 840 return _f( 841 pp, 842 self.n, 843 intervals=self.intervals, 844 dmin=self.dmin, 845 dmax=self.dmax, 846 d=self.d, 847 ) 848 849 850class Jenv(Envelopes): 851 """ 852 Simulation envelope for J function. 853 854 Parameters 855 ---------- 856 pp : :class:`.PointPattern` 857 Point Pattern instance. 858 n : int 859 Number of empty space points (random points). 860 intervals : int 861 The length of distance domain sequence. Default is 10. 862 dmin : float 863 The minimum of the distance domain. 864 dmax : float 865 Upper limit of distance range. If dmax is None, dmax will be 866 set to maximum nearest neighbor distance. 867 d : sequence 868 The distance domain sequence. 869 If d is specified, intervals, dmin and dmax are ignored. 870 pct : float 871 1-alpha, alpha is the significance level. Default is 0.05, 872 which means 95% confidence level for the envelopes. 873 realizations: :class:`.PointProcess` 874 Point process instance with more than 1 realizations. 875 876 Attributes 877 ---------- 878 name : string 879 Name of the function. ("G", "F", "J", "K" or "L") 880 observed : array 881 A 2-dimensional numpy array of 2 columns. The first column is 882 the distance domain sequence for the observed point pattern. 883 The second column is J function for the observed point 884 pattern. 885 low : array 886 A 1-dimensional numpy array. Lower bound of the simulation 887 envelope. 888 high : array 889 A 1-dimensional numpy array. Higher bound of the simulation 890 envelope. 891 mean : array 892 A 1-dimensional numpy array. Mean values of the simulation 893 envelope. 894 895 Examples 896 -------- 897 .. plot:: 898 899 >>> import libpysal as ps 900 >>> from pointpats import Jenv, PoissonPointProcess, Window 901 >>> from libpysal.cg import shapely_ext 902 >>> va = ps.io.open(ps.examples.get_path("vautm17n.shp")) 903 >>> polys = [shp for shp in va] 904 >>> state = shapely_ext.cascaded_union(polys) 905 >>> pp = PoissonPointProcess(Window(state.parts), 100, 1, asPP=True).realizations[0] 906 >>> csrs = PoissonPointProcess(pp.window, 100, 100, asPP=True) 907 >>> jenv = Jenv(pp, realizations=csrs) 908 >>> jenv.plot() 909 910 """ 911 912 def __init__( 913 self, 914 pp, 915 n=100, 916 intervals=10, 917 dmin=0.0, 918 dmax=None, 919 d=None, 920 pct=0.05, 921 realizations=None, 922 ): 923 self.pp = pp 924 self.n = n 925 self.intervals = intervals 926 self.dmin = dmin 927 self.dmax = dmax 928 self.d = d 929 self.pct = pct 930 super(Jenv, self).__init__(pp, realizations=realizations, name="J") 931 932 def calc(self, *args, **kwargs): 933 pp = args[0] 934 return _j( 935 pp, 936 self.n, 937 intervals=self.intervals, 938 dmin=self.dmin, 939 dmax=self.dmax, 940 d=self.d, 941 ) 942 943 944class Kenv(Envelopes): 945 """ 946 Simulation envelope for K function. 947 948 Parameters 949 ---------- 950 pp : :class:`.PointPattern` 951 Point Pattern instance. 952 intervals : int 953 The length of distance domain sequence. Default is 10. 954 dmin : float 955 The minimum of the distance domain. 956 dmax : float 957 Upper limit of distance range. If dmax is None, dmax will be 958 set to maximum nearest neighbor distance. 959 d : sequence 960 The distance domain sequence. 961 If d is specified, intervals, dmin and dmax are ignored. 962 pct : float 963 1-alpha, alpha is the significance level. Default is 0.05, 964 which means 95% confidence level for the envelope. 965 realizations: :class:`.PointProcess` 966 Point process instance with more than 1 realizations. 967 968 Attributes 969 ---------- 970 name : string 971 Name of the function. ("G", "F", "J", "K" or "L") 972 observed : array 973 A 2-dimensional numpy array of 2 columns. The first column is 974 the distance domain sequence for the observed point pattern. 975 The second column is K function for the observed point 976 pattern. 977 low : array 978 A 1-dimensional numpy array. Lower bound of the simulation 979 envelope. 980 high : array 981 A 1-dimensional numpy array. Higher bound of the simulation 982 envelope. 983 mean : array 984 A 1-dimensional numpy array. Mean values of the simulation 985 envelope. 986 987 Examples 988 -------- 989 .. plot:: 990 991 >>> import libpysal as ps 992 >>> from pointpats import Kenv, PoissonPointProcess, Window 993 >>> from libpysal.cg import shapely_ext 994 >>> va = ps.io.open(ps.examples.get_path("vautm17n.shp")) 995 >>> polys = [shp for shp in va] 996 >>> state = shapely_ext.cascaded_union(polys) 997 >>> pp = PoissonPointProcess(Window(state.parts), 100, 1, asPP=True).realizations[0] 998 >>> csrs = PoissonPointProcess(pp.window, 100, 100, asPP=True) 999 >>> kenv = Kenv(pp, realizations=csrs) 1000 >>> kenv.plot() 1001 1002 """ 1003 1004 def __init__( 1005 self, pp, intervals=10, dmin=0.0, dmax=None, d=None, pct=0.05, realizations=None 1006 ): 1007 self.pp = pp 1008 self.intervals = intervals 1009 self.dmin = dmin 1010 self.dmax = dmax 1011 self.d = d 1012 self.pct = pct 1013 super(Kenv, self).__init__(pp, realizations=realizations, name="K") 1014 1015 def calc(self, *args, **kwargs): 1016 pp = args[0] 1017 return _k( 1018 pp, intervals=self.intervals, dmin=self.dmin, dmax=self.dmax, d=self.d 1019 ) 1020 1021 1022class Lenv(Envelopes): 1023 """ 1024 Simulation envelope for L function. 1025 1026 Parameters 1027 ---------- 1028 pp : :class:`.PointPattern` 1029 Point Pattern instance. 1030 intervals : int 1031 The length of distance domain sequence. Default is 10. 1032 dmin : float 1033 The minimum of the distance domain. 1034 dmax : float 1035 Upper limit of distance range. If dmax is None, dmax will be 1036 set to maximum nearest neighbor distance. 1037 d : sequence 1038 The distance domain sequence. 1039 If d is specified, intervals, dmin and dmax are ignored. 1040 pct : float 1041 1-alpha, alpha is the significance level. Default is 0.05, 1042 which means 95% confidence level for the envelopes. 1043 realizations: :class:`.PointProcess` 1044 Point process instance with more than 1 realizations. 1045 1046 Attributes 1047 ---------- 1048 name : string 1049 Name of the function. ("G", "F", "J", "K" or "L") 1050 observed : array 1051 A 2-dimensional numpy array of 2 columns. The first column is 1052 the distance domain sequence for the observed point pattern. 1053 The second column is L function for the observed point 1054 pattern. 1055 low : array 1056 A 1-dimensional numpy array. Lower bound of the simulation 1057 envelope. 1058 high : array 1059 A 1-dimensional numpy array. Higher bound of the simulation 1060 envelope. 1061 mean : array 1062 A 1-dimensional numpy array. Mean values of the simulation 1063 envelope. 1064 1065 Examples 1066 -------- 1067 .. plot:: 1068 1069 >>> import libpysal as ps 1070 >>> from pointpats import Lenv, PoissonPointProcess, Window 1071 >>> from libpysal.cg import shapely_ext 1072 >>> va = ps.io.open(ps.examples.get_path("vautm17n.shp")) 1073 >>> polys = [shp for shp in va] 1074 >>> state = shapely_ext.cascaded_union(polys) 1075 >>> pp = PoissonPointProcess(Window(state.parts), 100, 1, asPP=True).realizations[0] 1076 >>> csrs = PoissonPointProcess(pp.window, 100, 100, asPP=True) 1077 >>> lenv = Lenv(pp, realizations=csrs) 1078 >>> lenv.plot() 1079 1080 """ 1081 1082 def __init__( 1083 self, pp, intervals=10, dmin=0.0, dmax=None, d=None, pct=0.05, realizations=None 1084 ): 1085 self.pp = pp 1086 self.intervals = intervals 1087 self.dmin = dmin 1088 self.dmax = dmax 1089 self.d = d 1090 self.pct = pct 1091 super(Lenv, self).__init__(pp, realizations=realizations, name="L") 1092 1093 def calc(self, *args, **kwargs): 1094 pp = args[0] 1095 return _l( 1096 pp, intervals=self.intervals, dmin=self.dmin, dmax=self.dmax, d=self.d 1097 ) 1098