Updaters and Elections¶
Updaters¶
- class gerrychain.updaters.CountySplit(value)[source]¶
Enum to track county splits in a partition.
- NOT_SPLIT¶
The county is not split.
- Type:
- NEW_SPLIT¶
The county became split after the initial partition.
- Type:
- OLD_SPLIT¶
The county has remained split since the initial partition.
- Type:
- class gerrychain.updaters.DataTally(data: Mapping[Hashable, float] | Sequence[float] | Series | str, alias: str)[source]¶
An updater for tallying numerical data that is not necessarily stored as node attributes
- data¶
A Dict or Series indexed by the graph’s nodes, or the string key for a node attribute containing the Tally’s data.
- Type:
dict | pandas.Series | str
Initialize a DataTally instance.
- Parameters:
data (dict | Sequence | pandas.Series | str) – A Dict, Series, or sequence indexed by the graph’s nodes, or the string key for a node attribute containing the Tally’s data.
alias (str) – The name of the tally in the Partition’s updaters dictionary
- class gerrychain.updaters.Election(name: str, party_names_to_node_attribute_names: Mapping[str, str | Sequence[float]] | list[str], alias: str | None = None)[source]¶
Represents the data of one election, with races conducted in each part of the partition.
As we vary the districting plan, we can use the same node-level vote totals to tabulate hypothetical elections. To do this manually with tallies, we would have to maintain tallies for each party, as well as the total number of votes, and then compute the electoral results and percentages from scratch every time. To make this simpler, this class provides an ElectionUpdater to manage these tallies. The updater returns an ElectionResults class giving a convenient view of the election results, with methods like ElectionResults.wins or ElectionResults.percent for common queries the user might make on election results.
Example usage:
# Assuming your nodes have attributes "2008_D", "2008_R" # with (for example) 2008 senate election vote totals election = Election( "2008 Senate", {"Democratic": "2008_D", "Republican": "2008_R"}, alias="2008_Sen" ) # Assuming you already have a graph and assignment: partition = Partition( graph, assignment, updaters={"2008_Sen": election} ) # The updater returns an ElectionResults instance, which # we can use (for example) to see how many seats a given # party would win in this partition using this election's # vote distribution: partition["2008_Sen"].wins("Republican")
- data that
hold the vote totals for each party.
- the¶
node_attribute_names in the graph’s node data that hold the vote totals for that party.
- objects¶
that manage the vote totals for that party.
- updater¶
An ElectionUpdater object that manages the tallies and returns an ElectionResults object.
- Type:
- alias¶
The name that the election is registered under in the partition’s dictionary of updaters.
- Type:
Initialize a Election instance.
- Parameters:
name (str) – The name of the election. (e.g. “2008 Presidential”)
party_names_to_node_attribute_names (dict | list) –
A mapping from the name of a party to the name of an attribute of a node that contains the vote totals for that party. This parameter can be either a list or a dict. If a list, then the name of the party and the name of the node attribute are the same, for instance: [“Dem”, “Rep”] would indicate that the “Dem” party vote totals are stored in the “Dem” node attribute. If a list, then there are two possibilities.
A dictionary matching party names to their data node_attribute_names, either as actual node_attribute_names (list-like, indexed by nodes) or as string keys for the node attributes that hold the party’s vote totals. Or, a list of strings which will serve as both the party names and the node attribute keys.
alias (str | None, optional) – Alias that the election is registered under in the Partition’s dictionary of updaters. Defaults to
None, which usesname.
- class gerrychain.updaters.Tally(fields: str | list[str], alias: str | None = None, dtype_fn: ~collections.abc.Callable[[], float] = <class 'int'>)[source]¶
An updater for keeping a tally of one or more node attributes.
- a¶
single attribute name as a string.
- alias¶
The aliased name of this Tally (meaning, the key corresponding to this Tally in the Partition’s updaters dictionary)
- Type:
str | None
- dtype_fn¶
A zero-argument callable that creates the tally’s initial value.
- Type:
Callable[[], float]
Initialize a Tally instance.
- Parameters:
fields (str | list[str]) – The list of node attributes that you want to tally. Or a just a single attribute name as a string.
alias (str | None, optional) – The aliased name of this Tally (meaning, the key corresponding to this Tally in the Partition’s updaters dictionary). Default is None.
dtype_fn (Callable[[], float], optional) – A zero-argument callable that creates the tally’s initial value. Defaults to
int.
- gerrychain.updaters.boundary_nodes(partition: Partition, alias: str = 'boundary_nodes') set[Hashable][source]¶
Return set of nodes in the partition that are on the boundary.
- gerrychain.updaters.compute_edge_flows(partition: Partition) dict[Hashable, dict[str, set[tuple[int, int]]]][source]¶
Computes the flow of cut edges between a partition and its parent.
- gerrychain.updaters.county_splits(partition_name: str, county_field_name: str) Callable[[Partition], dict[Hashable, CountyInfo]][source]¶
An updater for tracking the number of counties that are split in a partition.
- Parameters:
- Returns:
- The tracked data is a
dict[Hashable, CountyInfo]keyed on the county ID. Each CountyInfois a named tuple with fields split (a CountySplit enum), nodes (a list of node IDs in the county), and contains (aset[Hashable]of the assignment IDs the county intersects).
- The tracked data is a
- Return type:
Callable
- gerrychain.updaters.cut_edges(partition: Partition) set[tuple[int, int]][source]¶
Computes the set of edges for a given partition.
- gerrychain.updaters.cut_edges_by_part(partition: Partition, previous: set[tuple[int, int]], new_edges: set[tuple[int, int]], old_edges: set[tuple[int, int]]) set[tuple[int, int]][source]¶
Updater that returns a dictionary mapping each part of a partition to the set of cut edges in that part.
- Parameters:
partition (Partition) – A partition of a Graph
previous (set[tuple]) – The previous set of edges for a fixed part of the given partition.
new_edges (set[tuple]) – The set of edges that have flowed into the given part of the partition.
old_edges (set[tuple]) – The set of cut edges in the previous partition.
- Returns:
The new set of cut edges for the newly generated partition.
- Return type:
- gerrychain.updaters.exterior_boundaries(partition: Partition, previous: float, inflow: set[Hashable], outflow: set[Hashable]) float[source]¶
Computes the total perimeter of the boundary nodes in each part of the partition.
- Parameters:
- Returns:
The updated exterior boundary perimeter for the part.
- Return type:
- gerrychain.updaters.exterior_boundaries_as_a_set(partition: Partition, previous: set[Hashable], inflow: set[Hashable], outflow: set[Hashable]) set[Hashable][source]¶
Updater function that responds to the flow of nodes between different partitions.
- Parameters:
- Returns:
The updated exterior boundary nodes for the part.
- Return type:
set[Hashable]
- gerrychain.updaters.flips(partition: Any) Any¶
Compatibility updater returning
Partition.flips.- Parameters:
partition (Any) – Partition whose flips should be returned.
- Returns:
The partition’s flips mapping, or
Nonewhen it has no flips.- Return type:
Any
- gerrychain.updaters.flows_from_changes(old_partition: Partition, new_partition: Partition) dict[Hashable, dict[str, set[Hashable]]][source]¶
Return per-part node flow updates between two partitions.
- Parameters:
- Returns:
- A dictionary mapping each node that changed assignment between the previous and
current partitions to a dictionary of the form {‘in’: <set of nodes that flowed in>, ‘out’: <set of nodes that flowed out>}.
- Return type:
- gerrychain.updaters.interior_boundaries(partition: Partition, previous: float, new_edges: set[tuple[int, int]], old_edges: set[tuple[int, int]]) float[source]¶
Computes the total perimeter of the shared boundary between different parts of the partition.
- Parameters:
- Returns:
The updated interior boundary perimeter for the part.
- Return type:
- gerrychain.updaters.num_spanning_trees(partition: Partition) dict[Hashable, int][source]¶
Return number of spanning trees in each part (district) of a partition.
- gerrychain.updaters.perimeter(partition: Partition) dict[Hashable, float][source]¶
Computes the perimeter of each part in the partition.
- gerrychain.updaters.tally_region_splits(region_attr_lst: Sequence[str]) Callable[[Partition], dict[str, int]][source]¶
A naive updater for tallying the number of times a region attribute is split.
Here “region” is the generic term for an administrative unit you would prefer not to split (e.g. a county, municipality, or other locality). Each entry in
region_attr_lstis the name of a node attribute holding the region label; thecountyand locality updaters are just specific instances of this region concept.- Parameters:
region_attr_lst (Sequence[str]) – Region attribute names to tally splits for.
- Returns:
- A function that takes a partition and returns a dictionary which maps the region
name to the number of times that it is split in a a particular partition.
- Return type:
Callable
Elections¶
- class gerrychain.updaters.election.Election(name: str, party_names_to_node_attribute_names: Mapping[str, str | Sequence[float]] | list[str], alias: str | None = None)[source]¶
Represents the data of one election, with races conducted in each part of the partition.
As we vary the districting plan, we can use the same node-level vote totals to tabulate hypothetical elections. To do this manually with tallies, we would have to maintain tallies for each party, as well as the total number of votes, and then compute the electoral results and percentages from scratch every time. To make this simpler, this class provides an ElectionUpdater to manage these tallies. The updater returns an ElectionResults class giving a convenient view of the election results, with methods like ElectionResults.wins or ElectionResults.percent for common queries the user might make on election results.
Example usage:
# Assuming your nodes have attributes "2008_D", "2008_R" # with (for example) 2008 senate election vote totals election = Election( "2008 Senate", {"Democratic": "2008_D", "Republican": "2008_R"}, alias="2008_Sen" ) # Assuming you already have a graph and assignment: partition = Partition( graph, assignment, updaters={"2008_Sen": election} ) # The updater returns an ElectionResults instance, which # we can use (for example) to see how many seats a given # party would win in this partition using this election's # vote distribution: partition["2008_Sen"].wins("Republican")
- data that
hold the vote totals for each party.
- the¶
node_attribute_names in the graph’s node data that hold the vote totals for that party.
- objects¶
that manage the vote totals for that party.
- updater¶
An ElectionUpdater object that manages the tallies and returns an ElectionResults object.
- Type:
- alias¶
The name that the election is registered under in the partition’s dictionary of updaters.
- Type:
Initialize a Election instance.
- Parameters:
name (str) – The name of the election. (e.g. “2008 Presidential”)
party_names_to_node_attribute_names (dict | list) –
A mapping from the name of a party to the name of an attribute of a node that contains the vote totals for that party. This parameter can be either a list or a dict. If a list, then the name of the party and the name of the node attribute are the same, for instance: [“Dem”, “Rep”] would indicate that the “Dem” party vote totals are stored in the “Dem” node attribute. If a list, then there are two possibilities.
A dictionary matching party names to their data node_attribute_names, either as actual node_attribute_names (list-like, indexed by nodes) or as string keys for the node attributes that hold the party’s vote totals. Or, a list of strings which will serve as both the party names and the node attribute keys.
alias (str | None, optional) – Alias that the election is registered under in the Partition’s dictionary of updaters. Defaults to
None, which usesname.
- class gerrychain.updaters.election.ElectionResults(election: Election, counts: dict[str, dict[Hashable, float]], regions: Iterable[Hashable])[source]¶
Represents the results of an election. Provides helpful methods to answer common questions you might have about an election (Who won? How many seats?, etc.).
- totals_for_party¶
Party names mapped to their vote totals in each part.
- percents_for_party¶
Party names mapped to their vote percentages in each part.
Note
The variable “regions” is generally called “parts” in other sections of the codebase, but we have changed it here to avoid confusion with the parameter “party” that often appears within the class.
Initialize a ElectionResults instance.
- Parameters:
election (Election) – The Election object that these results are associated with.
counts (dict[str, dict[Hashable, float]]) – Party names mapped to the total number of votes that party received in each part of the partition.
regions (Iterable[Hashable]) – Regions to consider, such as congressional districts.
- count(party: str, region: Hashable | None = None) float[source]¶
Return vote total for
partyin one region or overall.If
regionis provided, this returns the total vote count in that region. Otherwise, it returns the overall vote total ofpartyacross all regions.- Parameters:
party (str) – Party ID.
region (Hashable | None, optional) – ID of the part of the partition whose votes we want to tally.
- Returns:
- The total number of votes that
partyreceived in a given region (part of the partition). If
regionis omitted, returns the overall vote total ofparty.
- The total number of votes that
- Return type:
- counts(party: str) tuple[float, ...][source]¶
Return tuple of the total votes cast for
partyin each part of the partition.
- efficiency_gap() float[source]¶
Computes the efficiency gap for this ElectionResults object.
See: gerrychain.metrics.partisan.efficiency_gap
- Returns:
The efficiency gap for this election.
- Return type:
- mean_median() float[source]¶
Computes the mean-median score for this ElectionResults object.
See: gerrychain.metrics.partisan.mean_median
- Returns:
The mean-median score for this election.
- Return type:
- mean_thirdian() float[source]¶
Computes the mean-thirdian score for this ElectionResults object.
See: gerrychain.metrics.partisan.mean_thirdian
- Returns:
The mean-thirdian score for this election.
- Return type:
- partisan_bias() float[source]¶
Computes the partisan bias for this ElectionResults object.
See: gerrychain.metrics.partisan.partisan_bias
- Returns:
The partisan bias for this election.
- Return type:
- partisan_gini() float[source]¶
Computes the Gini score for this ElectionResults object.
See: gerrychain.metrics.partisan.partisan_gini
- Returns:
The partisan Gini score for this election.
- Return type:
- percent(party: str, region: Hashable | None = None) float[source]¶
Return vote share for
partyin one region or overall.If
regionis provided, this returns the vote share in that region. Otherwise, it returns the overall vote share ofpartyacross all regions.- Parameters:
party (str) – Party ID.
region (Hashable | None, optional) – ID of the part of the partition whose votes we want to tally.
- Returns:
- The percentage of the vote that
partyreceived in a given region (part of the partition). If
regionis omitted, returns the overall vote share ofparty.
- The percentage of the vote that
- Return type:
- percents(party: str) tuple[float, ...][source]¶
Return vote shares for
partyacross all regions.The returned tuple contains one vote-share value per region, in the order of
self.regions.
- total_votes() float[source]¶
Return total number of votes cast in the election.
- Returns:
The total number of votes cast in the election.
- Return type:
- votes(party: str) tuple[float, ...][source]¶
An alias for counts.
It returns a tuple of the total votes cast for
partyin each part of the partition.
- class gerrychain.updaters.election.ElectionUpdater(election: Election)[source]¶
The updater for computing the election results in each part of the partition after each step in the Markov chain. The actual results are returned to the user as an ElectionResults instance.
- get_previous_values(partition: Partition) Mapping[str, dict[Hashable, float] | None][source]¶
Returns a dictionary mapping party names to the vote totals that party received in each.
- Parameters:
partition (Partition) – The partition whose parent we want to obtain the previous vote totals from.
- Returns:
- A dictionary mapping party names to the
vote totals that party received in each part of the parent of the current partition.
- Return type:
- gerrychain.updaters.election.format_part_results(percents_for_party: Mapping[str, Mapping[Hashable, float]], part: Hashable) str[source]¶
Return A formatted string containing the results for the given part of the partition.
- Parameters:
- Returns:
A formatted string containing the results for the given part of the partition.
- Return type:
- gerrychain.updaters.election.get_percents(counts: Mapping[Hashable, float], totals: Mapping[Hashable, float]) dict[Hashable, float][source]¶
Returns a dictionary mapping each part in a partition to the percentage of votes that a party received in that part.
- Parameters:
- Returns:
A dictionary mapping each part in a partition to the percentage
- Return type: