Author: Serge Rey sjsrey@gmail.com and Wei Kang weikang9009@gmail.com
One philosophy of applying inferential statistics to spatial data is to think in terms of spatial processes and their possible realizations. In this view, an observed map pattern is one of the possible patterns that might have been generated by a hypothesized process. In this notebook, we are going to regard point patterns as the outcome of point processes. There are three major types of point process, which will result in three types of point patterns:
We will investigate how to generate these point patterns via simulation (Data Generating Processes (DGP) is the correponding point process), and inspect how these resulting point patterns differ from each other visually. In Quadrat statistics notebook and distance statistics notebook, we will adpot some statistics to infer whether it is a Complete Spaital Randomness (CSR) process.
A python file named "process.py" contains several point process classes with which we can generate point patterns of different types.
from pointpats import PoissonPointProcess, PoissonClusterPointProcess, Window, poly_from_bbox, PointPattern
import libpysal as ps
from libpysal.cg import shapely_ext
%matplotlib inline
import numpy as np
#import matplotlib.pyplot as plt
Random point patterns are the outcome of CSR. CSR has two major characteristics:
It usually serves as the null hypothesis in testing whether a point pattern is the outcome of a random process.
There are two types of CSR:
We are going to generate several point patterns (200 events) from CSR within Virginia state boundary.
# open the virginia polygon shapefile
va = ps.io.open(ps.examples.get_path("virginia.shp"))
polys = [shp for shp in va]
# Create the exterior polygons for VA from the union of the county shapes
state = shapely_ext.cascaded_union(polys)
# create window from virginia state boundary
window = Window(state.parts)
# simulate a csr process in the same window (200 points, 1 realization)
# by specifying "asPP" false, we can generate a point series
# by specifying "conditioning" false, we can simulate a N-conditioned CSR
np.random.seed(5)
samples = PoissonPointProcess(window, 200, 1, conditioning=False, asPP=False)
samples
<pointpats.process.PoissonPointProcess at 0x1b122d7b70>
samples.realizations[0] # simulated event points
array([[-76.3326571 , 36.57893856], [-81.93206633, 37.0243966 ], [-79.55664806, 37.35242254], [-78.5166233 , 37.55701527], [-77.21660795, 38.26514268], [-82.09226973, 37.00701809], [-77.44823305, 38.6714618 ], [-79.95384378, 37.99268412], [-81.36397951, 37.03187854], [-78.37289635, 38.78731506], [-78.78567678, 37.07057506], [-78.61625258, 36.89065808], [-82.45957129, 36.95802405], [-77.77370645, 37.01124988], [-78.80401745, 38.78711285], [-78.2800756 , 37.64869473], [-76.33475868, 37.41755285], [-79.71621808, 37.22853963], [-80.31108929, 36.90895769], [-76.81331831, 37.13340462], [-77.17489798, 37.62727824], [-79.58599474, 37.17903022], [-78.34778262, 37.31439593], [-76.78862975, 36.56978482], [-78.90167513, 38.14339807], [-78.31750801, 38.6042175 ], [-80.63065732, 37.39418456], [-79.0679983 , 38.20670684], [-76.97054563, 37.43228348], [-78.28781253, 38.80715429], [-79.51445209, 37.05899454], [-78.75479687, 36.94362059], [-76.56183486, 37.14352317], [-82.8250185 , 36.77946552], [-75.57058942, 37.84115351], [-83.57095518, 36.62173807], [-82.73830125, 36.76063464], [-79.64158321, 36.68065846], [-76.92510237, 36.92895731], [-80.20619679, 37.80498897], [-77.74757811, 37.55846008], [-80.89034305, 36.65326387], [-79.23362271, 38.12835879], [-78.10257435, 36.59838991], [-76.14501324, 36.74210979], [-77.18266793, 36.84631799], [-77.27402385, 37.404438 ], [-77.68764731, 37.34273888], [-77.20460382, 37.91075633], [-81.8075696 , 36.94054096], [-76.84214327, 37.82794034], [-76.86353526, 36.82540288], [-76.8056485 , 37.18366661], [-78.70526218, 38.89314571], [-78.11460871, 39.00196074], [-78.77656343, 37.61506248], [-78.1748728 , 37.29187339], [-78.33817368, 38.36125302], [-79.22973299, 37.54091061], [-75.5696782 , 37.90756983], [-77.02179404, 36.72052872], [-79.48678905, 38.05681891], [-78.58205854, 37.41314179], [-77.36276352, 37.04549049], [-77.30130598, 37.53465902], [-79.10398846, 38.25305909], [-82.54221637, 36.90375945], [-77.94793345, 38.75199833], [-78.9452502 , 37.54473244], [-79.048031 , 37.65131473], [-78.25853547, 38.2769875 ], [-77.54648155, 36.66647077], [-78.48230503, 38.91668951], [-78.71263077, 38.2499848 ], [-78.57345575, 37.83448379], [-78.57683725, 38.88609472], [-81.60393528, 37.14655422], [-80.41085679, 37.23246613], [-79.45003004, 37.75664579], [-78.00505977, 39.15971417], [-79.5153296 , 38.36726525], [-79.69680058, 37.87120598], [-77.87487209, 37.85508792], [-76.78504902, 36.99733473], [-81.76182614, 36.88421234], [-81.96888594, 36.99263064], [-77.86127482, 37.16191786], [-79.91539534, 36.57794908], [-82.27493376, 36.93038256], [-75.89989311, 37.49087981], [-80.83633012, 37.38476674], [-77.93737278, 37.73587757], [-78.80405416, 38.2423914 ], [-80.09426594, 36.77163754], [-78.55997549, 36.9372054 ], [-80.74982401, 36.69837703], [-79.89144123, 37.27287164], [-77.53568375, 38.42234669], [-79.36034573, 37.9199658 ], [-78.39624506, 39.22046697], [-77.32624847, 37.32763411], [-77.14780326, 38.1270279 ], [-80.24638938, 37.5142178 ], [-77.41027396, 36.97299833], [-78.73229552, 37.60233533], [-79.50446982, 38.04796476], [-77.34484259, 37.05615369], [-80.66964982, 37.07084403], [-77.15297781, 37.29870784], [-78.28959166, 39.29418715], [-77.10310375, 37.3812618 ], [-78.11943302, 37.92836454], [-80.31267194, 36.665347 ], [-76.6777552 , 36.75870423], [-79.31751436, 38.06910198], [-77.02234401, 38.29308642], [-77.44257801, 38.34724139], [-77.54221373, 37.50425399], [-75.67749041, 37.81841772], [-80.21661887, 37.67742691], [-78.75115924, 38.71767437], [-78.95485683, 36.59501015], [-76.86872936, 38.02181925], [-79.21340288, 37.13898883], [-80.00081862, 36.81108808], [-77.77941742, 36.66281858], [-77.3124049 , 38.04905423], [-77.9213301 , 36.92944526], [-77.66093307, 38.33654176], [-77.21170491, 38.93214783], [-76.68169985, 36.70007358], [-77.30664489, 37.89347582], [-82.34535364, 36.75272866], [-76.86645645, 37.8687134 ], [-77.3709068 , 38.3866506 ], [-78.8063798 , 37.3391586 ], [-80.03257936, 37.4129918 ], [-78.68101007, 38.44562521], [-77.63204774, 36.87786176], [-78.88306754, 38.49431963], [-77.45255789, 37.83099746], [-79.5298396 , 37.78361184], [-81.55542816, 36.61994736], [-78.47299022, 36.8579181 ], [-79.02176971, 36.65214546], [-78.28147935, 37.80847913], [-79.58518375, 38.20539312], [-77.77610921, 37.82863786], [-80.58914692, 37.04572831], [-81.84584342, 36.68964681], [-79.5701122 , 37.36705848], [-76.7064535 , 36.5658754 ], [-79.68195266, 37.01713442], [-76.22771852, 36.73171684], [-77.16980606, 38.0809812 ], [-77.10609198, 37.20993371], [-77.83263118, 37.30642911], [-77.3096478 , 38.04267336], [-80.09196435, 37.69627213], [-77.06346097, 37.66044069], [-78.39635026, 38.35692905], [-80.70881825, 37.33395262], [-77.77980079, 36.81863702], [-77.48032587, 37.53013036], [-80.64284755, 37.29151092], [-78.31970329, 39.03988516], [-77.99991705, 38.62963975], [-81.39136576, 36.6361113 ], [-76.2500645 , 36.58381878], [-77.75281574, 38.09955844], [-79.18848841, 36.86516089], [-78.10679754, 37.23406281], [-77.72774175, 37.75365148], [-80.79353455, 36.66466322], [-79.09248227, 38.11065381], [-79.43627162, 36.9317042 ], [-80.67513179, 36.98716053], [-79.23362918, 37.89815733], [-78.88007206, 38.63625233], [-77.102715 , 36.9571268 ], [-79.16601272, 37.50364778], [-78.17995667, 37.56372944], [-78.55397235, 38.94719771], [-82.21842212, 37.31977937], [-75.70804637, 37.73079071], [-76.86774363, 37.59858498], [-79.2410832 , 36.73533614], [-75.63397197, 37.85672189], [-78.43974651, 36.73714428], [-79.63776485, 38.06933981], [-78.32258504, 38.01500577], [-77.85944265, 36.88932439], [-77.86902482, 39.14909625], [-81.97464747, 36.8508439 ], [-78.99980174, 37.44186754], [-77.36680988, 38.99916544], [-79.9150312 , 37.36377025], [-80.36600514, 36.67015317], [-77.42381708, 37.2241776 ], [-77.93652737, 38.17731926]])
# build a point pattern from the simulated point series
pp_csr = PointPattern(samples.realizations[0])
pp_csr
<pointpats.pointpattern.PointPattern at 0x1b1231dcc0>
pp_csr.plot(window=True, hull=True, title='Random Point Pattern')
pp_csr.n
200
# simulate a csr process in the same window (200 points, 1 realization)
# by specifying "asPP" false, we can generate a point series
# by specifying "conditioning" True, we can simulate a lamda-conditioned CSR
np.random.seed(5)
samples = PoissonPointProcess(window, 200, 1, conditioning=True, asPP=False)
samples
<pointpats.process.PoissonPointProcess at 0x1b1aaf25c0>
samples.realizations[0] # simulated points
array([[-79.55664806, 38.25720619], [-78.5166233 , 38.30532302], [-77.21660795, 37.57582983], [-77.44823305, 36.74925133], [-79.95384378, 37.55525777], [-81.36397951, 36.71747455], [-80.18215183, 37.35242254], [-78.37289635, 38.26514268], [-78.78567678, 38.80097021], [-78.61625258, 38.36290302], [-81.43369537, 37.00701809], [-81.95031135, 37.07057506], [-77.77370645, 36.89065808], [-78.80401745, 38.72566936], [-79.32844778, 36.95802405], [-78.2800756 , 38.90863979], [-81.49037579, 36.99262809], [-76.90806444, 37.72828737], [-77.17489798, 37.64869473], [-79.58599474, 37.9904752 ], [-78.34778262, 37.22853963], [-76.78862975, 37.8189276 ], [-78.90167513, 36.90895769], [-78.31750801, 37.13340462], [-75.86084614, 37.62727824], [-75.97937462, 37.17903022], [-79.0679983 , 38.62297192], [-76.96164707, 37.31439593], [-76.97054563, 37.09732441], [-78.28781253, 39.27775751], [-79.51445209, 37.2942029 ], [-78.75479687, 37.39418456], [-75.75445326, 37.78241231], [-79.37160467, 37.43228348], [-79.64158321, 38.491645 ], [-79.33464281, 37.14352317], [-79.90916235, 37.50562343], [-76.92510237, 36.77946552], [-76.91730122, 36.62173807], [-82.06902468, 36.76063464], [-79.8601599 , 36.68065846], [-77.74757811, 39.05919615], [-79.23362271, 36.56074643], [-78.10257435, 37.80365574], [-77.18266793, 37.63777248], [-77.27402385, 37.57885055], [-77.68764731, 37.21503901], [-77.75929316, 36.61739054], [-77.20460382, 38.67318986], [-80.52384818, 36.65326387], [-80.60914236, 36.74210979], [-76.84214327, 38.07338722], [-79.88271974, 37.404438 ], [-76.81805705, 37.34273888], [-82.02798408, 36.94054096], [-76.84238532, 37.82794034], [-78.70526218, 38.83337292], [-76.71235091, 37.95435389], [-78.11460871, 36.82540288], [-78.77656343, 37.18366661], [-78.1748728 , 38.89314571], [-81.63574287, 37.11455891], [-79.08592614, 38.45792181], [-78.33817368, 37.64663718], [-79.22973299, 37.19362583], [-79.48678905, 37.29187339], [-78.58205854, 37.40208832], [-77.36276352, 38.76896337], [-77.30130598, 37.47745852], [-79.64493717, 36.72052872], [-79.10398846, 38.05681891], [-81.12955413, 37.04549049], [-77.94793345, 37.59843086], [-78.60434598, 38.89933921], [-79.048031 , 37.77049293], [-78.25853547, 39.16083334], [-78.72462602, 37.17396404], [-77.29314545, 37.9220836 ], [-77.28147432, 38.79060528], [-76.66696623, 36.58417386], [-80.46513532, 36.64153932], [-78.65541452, 38.74225794], [-76.805115 , 36.78532921], [-79.93532984, 37.08143783], [-78.29407639, 39.34140688], [-78.14216323, 38.3665535 ], [-78.00505977, 36.7069097 ], [-81.18975884, 36.62150498], [-80.79290321, 37.05030562], [-79.5153296 , 37.75664579], [-77.87487209, 37.40994143], [-76.78504902, 38.11807362], [-80.09560083, 37.35129105], [-75.85714598, 37.57460507], [-77.86127482, 38.34868698], [-82.27493376, 36.99263064], [-80.83633012, 37.16191786], [-77.93737278, 36.57794908], [-78.55997549, 37.60246875], [-80.74982401, 36.93038256], [-81.89152421, 37.32986349], [-76.60039544, 37.49087981], [-79.89144123, 38.026734 ], [-77.53568375, 37.64300141], [-79.36034573, 36.77163754], [-77.32624847, 36.9372054 ], [-82.34166665, 36.69837703], [-77.14780326, 37.60598513], [-80.24638938, 37.27287164], [-77.41027396, 37.9199658 ], [-78.73229552, 37.32763411], [-79.50446982, 37.98941026], [-77.34484259, 37.24072148], [-80.34358018, 36.97299833], [-78.28959166, 38.70289952], [-79.23938464, 37.60233533], [-77.10310375, 38.04796476], [-78.11943302, 37.5521639 ], [-82.63246378, 37.05615369], [-76.6777552 , 36.99804193], [-79.31751436, 37.29870784], [-77.02234401, 37.83495451], [-77.54221373, 37.3812618 ], [-75.71630753, 37.92836454], [-80.21661887, 36.75870423], [-78.75115924, 38.06910198], [-76.86872936, 37.50425399], [-79.21340288, 37.25364651], [-77.77941742, 39.02429976], [-77.3124049 , 38.7084587 ], [-77.9591418 , 38.05055288], [-77.9213301 , 38.71767437], [-77.66093307, 36.59501015], [-77.21170491, 37.13898883], [-81.91956901, 36.81108808], [-76.68169985, 36.66281858], [-77.30664489, 36.92944526], [-81.85918569, 36.80543902], [-76.86645645, 37.57131542], [-80.68521276, 37.18782022], [-81.41932788, 36.70007358], [-78.8063798 , 38.30071805], [-77.14952496, 37.89347582], [-79.07890941, 37.5601488 ], [-83.00313472, 36.75272866], [-78.68101007, 38.87234553], [-77.63204774, 37.61550741], [-78.88306754, 38.05667036], [-77.45255789, 37.3391586 ], [-78.47299022, 37.4129918 ], [-79.02176971, 37.37256883], [-78.28147935, 37.91147075], [-79.58518375, 37.78361184], [-77.77610921, 37.97641435], [-80.99224637, 36.61994736], [-80.58914692, 36.8579181 ], [-77.80923356, 37.58006348], [-78.86249696, 36.73878708], [-82.21675753, 36.74153288], [-83.24670184, 36.69004968], [-81.28732939, 36.87113389], [-75.84594392, 37.54487864], [-79.22235094, 36.87297199], [-78.48547431, 38.52479965], [-78.20476584, 38.54799414], [-77.89852106, 38.1201838 ], [-81.37405706, 37.04456699], [-78.02587914, 37.64685616], [-78.42418842, 36.88536942], [-76.68842544, 36.74893391], [-80.81565379, 36.84864385], [-77.83641513, 37.17473795], [-77.50393746, 38.0087299 ], [-82.66226354, 37.12507361], [-81.50584616, 36.91097209], [-78.50980015, 38.35200834], [-77.99991705, 39.2235099 ], [-77.75281574, 38.65985656], [-79.18848841, 37.81637356], [-75.99527387, 36.67900083], [-78.10679754, 38.48234391], [-77.72774175, 37.44640927], [-79.16298721, 38.41845743], [-80.79353455, 36.6361113 ], [-79.09248227, 38.09955844], [-79.43627162, 37.75365148], [-82.44550608, 36.66466322], [-78.88007206, 38.4383976 ]])
# build a point pattern from the simulated point series
pp_csr = PointPattern(samples.realizations[0])
pp_csr
<pointpats.pointpattern.PointPattern at 0x1b1ab022e8>
pp_csr.plot(window=True, hull=True, title='Random Point Pattern')
pp_csr.n
188
The simulated point pattern has $194$ events rather than the Possion mean $200$.
# simulate a csr process in the same window (200 points, 1 realization)
# by specifying "asPP" True, we can generate a point pattern
# by specifying "conditioning" false, we can simulate a N-conditioned CSR
np.random.seed(5)
samples = PoissonPointProcess(window, 200, 1, conditioning=False, asPP=True)
samples
<pointpats.process.PoissonPointProcess at 0x1b1abceeb8>
pp_csr = samples.realizations[0] # simulated point pattern
pp_csr
<pointpats.pointpattern.PointPattern at 0x1b1abc6550>
pp_csr.plot(window=True, hull=True, title='Random Point Pattern')
pp_csr.n
200
# simulate a csr process in the same window (200 points, 1 realization)
# by specifying "asPP" True, we can generate a point pattern
# by specifying "conditioning" True, we can simulate a lamda-conditioned CSR
np.random.seed(5)
samples = PoissonPointProcess(window, 200, 1, conditioning=True, asPP=True)
samples
<pointpats.process.PoissonPointProcess at 0x1b1acb4dd8>
pp_csr = samples.realizations[0] # simulated point pattern
pp_csr
<pointpats.pointpattern.PointPattern at 0x1b11e26ac8>
pp_csr.plot(window=True, hull=True, title='Random Point Pattern')
pp_csr.n
188
Clustered Patterns are more grouped than random patterns. Visually, we can observe more points at short distances. There are two sources of clustering:
We are going to focus on simulating correlated point process in this notebook. One example of correlated point process is Poisson cluster process. Two stages are involved in simulating a Poisson cluster process. First, parent events are simulted from a $\lambda$-conditioned or $N$-conditioned CSR. Second, $n$ offspring events for each parent event are simulated within a circle of radius $r$ centered on the parent. Offspring events are independently and identically distributed.
np.random.seed(5)
csamples = PoissonClusterPointProcess(window, 200, 10, 0.5, 1, asPP=True, conditioning=False)
csamples
<pointpats.process.PoissonClusterPointProcess at 0x1b1ad8af28>
csamples.parameters #number of total events for each realization
{0: {'n': 200}}
csamples.num_parents #number of parent events for each realization
{0: 10}
csamples.children # number of children events centered on each parent event
20
pp_pcp = csamples.realizations[0]
pp_pcp
<pointpats.pointpattern.PointPattern at 0x1b1ad5e080>
pp_pcp.plot(window=True, hull=True, title='Clustered Point Pattern') #plot the first realization
It is obvious that there are several clusters in the above point pattern.
import numpy as np
np.random.seed(10)
csamples = PoissonClusterPointProcess(window, 200, 10, 0.5, 1, asPP=True, conditioning=True)
csamples
<pointpats.process.PoissonClusterPointProcess at 0x1b1ae4c6a0>
csamples.parameters #number of events for the realization might not be equal to 200
{0: {'n': 260}}
csamples.num_parents #number of parent events for the realization, not equal to 10
{0: 13}
csamples.children # number of children events centered on each parent event
20
pp_pcp = csamples.realizations[0]
pp_pcp.plot(window=True, hull=True, title='Clustered Point Pattern')
np.random.seed(10)
csamples = PoissonClusterPointProcess(window, 200, 5, 0.5, 1, asPP=True)
pp_pcp = csamples.realizations[0]
pp_pcp.plot(window=True, hull=True, title='Clustered Point Pattern')