Skip to main content

geo

geo

Places and the movement between them: a geography (ss.geo.geography), and movement between its places: a movement model (ss.geo.gravity, ss.geo.radiation), a matrix (ss.geo.Mobility), or a register of moves on given dates (ss.geo.register)

These exist so that a model of more than one place can be built from named places and a standard movement model. Movement applies to a model stratified by place (sir.stratify(patch=...)), whose networks then pair people within each place; a geography can also be used by a network (ssl.GeoNet), for a disease of either kind.

Used with: agents and compartments; declared and coded modules

Classes

Name Description
Mobility Movement between the levels of a spatial stratification, given as a matrix
geography A geography: named places with populations and positions, used as the levels of a spatial stratification
gravity The gravity model of movement: the fraction of their time that a person from place i spends in place j (or, for migration,
radiation The radiation model of movement (Simini et al. 2012), which has no parameters to fit: of the people from place i who travel,
register A movement register: a table of moves between places on given dates, e.g. livestock sales between farms

Mobility

geo.Mobility(matrix=None, kind=None, away=None, **kwargs)

Movement between the levels of a spatial stratification, given as a matrix

People either commute (they keep their home, and spend a fraction of their time in other places, where they are exposed and expose others), visit (the same, but they are exposed to the residents of the places they go to and do not expose anyone there, as flepiMoP has it), or migrate (they relocate). Or, with kind='force', nobody moves and the force of infection does, as in LASER: with M[i,k] the movement from place i to place k, each place keeps 1 − Σ_k M[i,k] of its own force of infection and receives M[k,i] of each other place’s.

The movement models (ss.geo.gravity(), ss.geo.radiation()) take the same kind= and away= themselves, and a register of moves on given dates is ss.geo.register().

Other forms are written with the general pieces. Commuters who come back at a finite rate (Keeling and Rohani’s model 7.3) are a second spatial dimension of where people are now, with transfers between its levels at rates by home.

Note: CRN safe as agents.

Parameters

Name Type Description Default
matrix array the movement from each place (rows) to each place: for commuting the fraction of time spent there, and for migration the rate of moving there (a SciPy sparse array for many places, most pairs of which share no one) None
kind str ‘commute’, ‘visit’, ‘migrate’, or ‘force’ (default ‘commute’) None
away float for commuting and visiting, the fraction of their time people spend away from home (for ‘force’, the fraction of each place’s force of infection that goes to the others); the movement is rescaled to give every place that fraction (to keep the differences between places, scale the matrix by hand and give no away=) None

Examples

sir.stratify(patch=ss.levels(['a', 'b'], mobility=ss.geo.Mobility([[0, 0.1], [0.2, 0]])))

# LASER's coupling, with the force of infection moving: M[i,k] is the fraction of i's force that goes to k
sir.stratify(patch=ss.levels(places, mobility=ss.geo.Mobility(M, kind='force')))

Methods

Name Description
blank Whether an entry of a register is empty
by_value A function of each entry of a column of a register, worked out once for each distinct value, since a register can have millions of rows
coupling For a moving force of infection: the fraction of the force of infection of each level (columns) that each level (rows) receives, as a sparse array
events The register, resolved against the levels and the timeline of a sim
fitted The parameters (ss.par) in the movement, by attribute (away, and the movement model’s scale, and gravity’s source_power, dest_power, distance_power), which set the mixing when a sim is built
from_model The movement of a movement model (ss.geo.gravity(), ss.geo.radiation()), with its kind and amount
load Read a movement register, with a blank from or to (or a blank states) as None
matrix The movement between each pair of levels, with nothing on the diagonal
setup Check the kind and amount, and set them
time_frac For commuting: the fraction of their time that people from each level (rows) spend in each level; rows sum to 1. A sparse array, since most pairs of places share no one
blank
geo.Mobility.blank(v)

Whether an entry of a register is empty

by_value
geo.Mobility.by_value(vals, func, missing)

A function of each entry of a column of a register, worked out once for each distinct value, since a register can have millions of rows

Returns the results for the distinct values, then missing (for None and NaN), and the index of each entry’s result.

coupling
geo.Mobility.coupling(strat)

For a moving force of infection: the fraction of the force of infection of each level (columns) that each level (rows) receives, as a sparse array

Parameters
Name Type Description Default
strat Strat the stratification required
events
geo.Mobility.events(strat, sim)

The register, resolved against the levels and the timeline of a sim

Returns the step at whose start each event happens, the position of the place each leaves (-1 for none) and goes to (-1 for none), the number of people, and the states it names (None for the default), in the order of the table within each step. Events before the start or after the last step are dropped, with a note. Also the distinct pairs of states and to_states (sets, in the order they first appear), and which of them each event names (set_of).

fitted
geo.Mobility.fitted()

The parameters (ss.par) in the movement, by attribute (away, and the movement model’s scale, and gravity’s source_power, dest_power, distance_power), which set the mixing when a sim is built

from_model
geo.Mobility.from_model(model)

The movement of a movement model (ss.geo.gravity(), ss.geo.radiation()), with its kind and amount

load
geo.Mobility.load(data)

Read a movement register, with a blank from or to (or a blank states) as None

matrix
geo.Mobility.matrix(strat)

The movement between each pair of levels, with nothing on the diagonal

Parameters
Name Type Description Default
strat Strat the stratification required
setup
geo.Mobility.setup(kind=None, away=None, model=None, given=None, data=None)

Check the kind and amount, and set them

time_frac
geo.Mobility.time_frac(strat)

For commuting: the fraction of their time that people from each level (rows) spend in each level; rows sum to 1. A sparse array, since most pairs of places share no one

Parameters
Name Type Description Default
strat Strat the stratification required

geography

geo.geography(
    data=None,
    names=None,
    populations=None,
    x=None,
    y=None,
    lat=None,
    lon=None,
    distances=None,
    adjacency=None,
    level=1,
    year=None,
    places=None,
)

A geography: named places with populations and positions, used as the levels of a spatial stratification

A country’s administrative units come from starsim_data by name (ss.geo.geography('Kenya', level=1)): their names, populations, centroids, areas, p-codes, and which share a border. Levels 0 and 1 are bundled (for 184 countries and territories), so they need no download; level 2 is downloaded on first use.

Parameters

Name Type Description Default
data dataframe / str / list a country (or a list of them) by name or code, e.g. ‘Kenya’ or ‘KE’; or a table (or the name of a file holding one) with a column name, and optionally population (or pop), and x and y or lat and lon; or your own shapes, as a GeoDataFrame or a .shp, .geojson, or .gpkg file (read with geopandas), whose places are at the centroids of their shapes (in degrees, if it has a coordinate reference system) None
level int / str for a country, the administrative level: 1 (the default) for its first-level units (counties, provinces, states), 2 for the next (fetched), 0 for the country itself 1
year int for a country, the year of the populations (default: those bundled, for 2020; another year is fetched) None
places list for a country, only these units, by name, dot_name (‘Kenya:Nairobi’), or p-code None
names list the name of each place (instead of data) None
populations list the number of people in each place; sets the fraction of people who start in each (for a country, in place of the bundled ones), and the sizes of the places for movement between them (ss.geo.gravity, ss.geo.radiation) None
x list a position for each place, in any unit of distance None
y list the other coordinate None
lat list latitudes in degrees (instead of x and y); distances are then great-circle distances in km None
lon list longitudes in degrees None
distances array the distance between each pair of places (instead of positions) None
adjacency array whether each pair of places shares a border None

Examples

kenya = ss.geo.geography('Kenya', level=1) # Its 47 counties
towns = ss.geo.geography(names=['north', 'south', 'east'], populations=[50_000, 30_000, 20_000], x=[0, 0, 40], y=[0, 30, 0])
districts = ss.geo.geography('districts.shp') # Your own shapes, with columns name and population
S, I, R = ss.states(3)
sir = ss.Disease(infection=S >> I @ 0.3*I, recovery=ss.Transition(I, R, dur=10), init_prev=0.01)
sir.stratify(patch=ss.levels(towns, mobility=ss.geo.gravity(scale=0.01)))

Methods

Name Description
by_place Values in the order of the places, from an array, or a dict or series by name
draw Draw the places into axes, as shapes or as points sized by population, for plot() and maps of results; returns what was drawn, whose colors map() updates
get_shapes The shapes of the places to draw, if any: those the geography was made from, or for a country, its boundaries (shapes=True, which downloads them, and needs geopandas)
plot Draw a map of the places, colored by a value for each place if given
positions Where each place is, as x and y: the positions given, or longitudes and latitudes
by_place
geo.geography.by_place(values)

Values in the order of the places, from an array, or a dict or series by name

draw
geo.geography.draw(ax, colors=None, shapes=None, names=None)

Draw the places into axes, as shapes or as points sized by population, for plot() and maps of results; returns what was drawn, whose colors map() updates

get_shapes
geo.geography.get_shapes(shapes=None)

The shapes of the places to draw, if any: those the geography was made from, or for a country, its boundaries (shapes=True, which downloads them, and needs geopandas)

plot
geo.geography.plot(
    values=None,
    label=None,
    shapes=None,
    names=None,
    cmap='Reds',
    vmin=None,
    vmax=None,
    ax=None,
    **kwargs,
)

Draw a map of the places, colored by a value for each place if given

Places are drawn as shapes if the geography has them (it was made from shapes, or shapes=True for a country), and otherwise as points at their positions, with areas in proportion to their populations. For a map of a result over time, use the result’s map(), e.g. sim.results.sir.prevalence.map().

Parameters
Name Type Description Default
values array / dict / series a value for each place, in order or by name, e.g. a summary of a result by place None
label str what the values are, for the color bar None
shapes bool whether to draw shapes (by default, if the geography has them); True for a country downloads its boundaries, which needs geopandas None
names bool whether to label the places by name (by default, if there are 15 or fewer) None
cmap str the colormap of the values 'Reds'
vmin float the value at the bottom of the color scale (by default, 0, or the smallest value if it is negative) None
vmax float the value at the top of the color scale (by default, the largest value) None
ax Axes if given, draw into these axes None
kwargs dict passed to ss.plot_args(), e.g. figsize or filename
Examples
towns = ss.geo.geography(names=['a', 'b', 'c'], populations=[50_000, 30_000, 20_000], x=[0, 0, 40], y=[0, 30, 0])
towns.plot() # Where the places are, and their populations
towns.plot(values=sim.results.sir.infection.by('patch').summarize(), label='Infections') # A summary of a result
ss.geo.geography('Kenya').plot(shapes=True) # Kenya's counties, with their boundaries
positions
geo.geography.positions()

Where each place is, as x and y: the positions given, or longitudes and latitudes

gravity

geo.gravity(
    away=None,
    scale=None,
    kind=None,
    source_power=1.0,
    dest_power=1.0,
    distance_power=2.0,
)

The gravity model of movement: the fraction of their time that a person from place i spends in place j (or, for migration, the rate at which they move there) is scale × pop[i]^(source_power−1) × pop[j]^dest_power / distance[i,j]^distance_power

Populations and distances come from the geography of the dimension it is used on (ss.geo.geography). The model gives the shape of the movement, and away= its amount: the fraction of their time that people spend away from home, split between the other places by gravity. scale has units of distance^distance_power / pop^(source_power+dest_power−1), so no default fits both three towns and a country; give it only if it has been calibrated. With neither, people spend 10% of their time away. kind= says how people move (see ss.geo.Mobility).

Parameters

Name Type Description Default
away float for commuting and visiting, the fraction of their time people spend away from home (for ‘force’, the fraction of each place’s force of infection that goes to the others; default 0.1, unless scale is given) None
scale float the overall amount of movement, instead of away; for migration, the scale of the rates (required) None
kind str ‘commute’ (the default), ‘visit’, ‘migrate’, or ‘force’ (see ss.geo.Mobility) None
source_power float the exponent of the population of the place people come from 1.0
dest_power float the exponent of the population of the place they go to 1.0
distance_power float the exponent of the distance between the two 2.0

Examples

sir.stratify(patch=ss.levels(towns, mobility=ss.geo.gravity(away=0.1, source_power=1.0, dest_power=1.0, distance_power=2.0)))
sir.stratify(patch=ss.levels(towns, mobility=ss.geo.gravity(scale=2e-4))) # A calibrated amount
sir.stratify(patch=ss.levels(towns, mobility=ss.geo.gravity(away=0.1, kind='visit'))) # Travelers do not infect the people they visit

Methods

Name Description
matrix The movement between each pair of levels of a stratification, from its geography
matrix
geo.gravity.matrix(strat)

The movement between each pair of levels of a stratification, from its geography

Parameters
Name Type Description Default
strat Strat the stratification, whose geography gives the populations and distances required

radiation

geo.radiation(away=None, scale=None, kind=None)

The radiation model of movement (Simini et al. 2012), which has no parameters to fit: of the people from place i who travel, the fraction who go to place j is pop[i] × pop[j] / ((pop[i] + s) × (pop[i] + pop[j] + s)), where s is the population of the other places nearer to i than j is

It is used as ss.geo.gravity is, with the populations and distances of the geography of the dimension it is used on (ss.geo.geography): the model gives where people go, and away= how much they travel. With neither away nor scale, people spend 10% of their time away. The fractions are normalized to sum to 1 for each place, so for migration scale is the rate at which each person moves. kind= says how people move (see ss.geo.Mobility).

Parameters

Name Type Description Default
away float for commuting and visiting, the fraction of their time people spend away from home (for ‘force’, the fraction of each place’s force of infection that goes to the others; default 0.1, unless scale is given) None
scale float the overall amount of movement, instead of away: the fraction of their time away, or for migration the rate of moving (required) None
kind str ‘commute’ (the default), ‘visit’, ‘migrate’, or ‘force’ (see ss.geo.Mobility) None

Examples

sir.stratify(patch=ss.levels(towns, mobility=ss.geo.radiation(away=0.1)))
sir.stratify(patch=ss.levels(towns, mobility=ss.geo.radiation(scale=2e-5, kind='migrate'))) # 2e-5 moves per person per unit of time

Methods

Name Description
matrix The movement between each pair of levels of a stratification, from its geography
matrix
geo.radiation.matrix(strat)

The movement between each pair of levels of a stratification, from its geography

Parameters
Name Type Description Default
strat Strat the stratification, whose geography gives the populations and distances required

register

geo.register(data)

A movement register: a table of moves between places on given dates, e.g. livestock sales between farms

It has columns date, from, to, n, and optionally states (and to_states). Each row moves n people from one place to another; a row with no from adds them to to (births, purchases), and one with no to removes them from from (deaths, sales out of the model). The people who move or leave are chosen at random from those in states (by default, everyone); people who are added go into states (by default, the first state). With to_states, they also move from each of states to the matching one of to_states. Each event happens at the start of the first step that begins on or after its date, before that step’s transitions, and the events of a step happen in the order of the table.

Note: CRN safe as agents.

Parameters

Name Type Description Default
data str / df the register: a file name or a dataframe required

Examples

sir.stratify(herd=ss.levels(herds, mobility=ss.geo.register('movements.csv')))