API Reference
Ballot
- class votekit.ballot.RankBallot(*, ranking: Sequence[Iterable[str]] | None = None, scores: dict[str, int | float] | None = None, weight: float | int = 1.0, voter_set: set[str] | frozenset[str] = frozenset({}))[source]
Class to handle ballots with rankings. Strips whitespace from candidate names.
- Parameters:
ranking (RankingLike) – Ranking of candidates, defaults to None.
weight (Union[int, float]) – Weight of the ballot, defaults to 1.0.
voter_set (Union[set[str], frozenset[str]]) – Voter set of the ballot, defaults to frozenset().
- ranking
Ranking of candidates.
- Type:
RankingLike
- weight
Weight of the ballot.
- Type:
float
- voter_set
Voter set of the ballot.
- Type:
frozenset[str]
- Raises:
ValueError – Candidate ‘~’ found in ballot ranking.
ValueError – Ballot weight cannot be negative.
- class votekit.ballot.ScoreBallot(*, ranking: Sequence[Iterable[str]] | None = None, scores: dict[str, int | float] | None = None, weight: float | int = 1.0, voter_set: set[str] | frozenset[str] = frozenset({}))[source]
Class to handle ballots with scores. Strips whitespace from candidate names.
- Parameters:
scores (Optional[dict[str, Union[int, float]]]) – Scores of candidates, defaults to None.
weight (Union[int, float]) – Weight of the ballot, defaults to 1.0.
voter_set (Union[set[str], frozenset[str]]) – Voter set of the ballot, defaults to frozenset().
- scores
Scores of candidates.
- Type:
Optional[dict[str, float]]
- weight
Weight of the ballot.
- Type:
float
- voter_set
Voter set of the ballot.
- Type:
frozenset[str]
- Raises:
ValueError – Candidate ‘~’ found in ballot scores.
ValueError – Ballot weight cannot be negative.
TypeError – Score values must be numeric.
Preference Profiles
- class votekit.pref_profile.RankProfile(*, ballots: ~typing.Sequence[~votekit.ballot.Ballot] = (), candidates: ~typing.Sequence[str] = (), max_ranking_length: int = 0, df: ~pandas.core.frame.DataFrame = Empty DataFrame Columns: [] Index: [], **kwargs)[source]
- property ballots: tuple[RankBallot, ...]
Compute the ballot tuple as a cached property.
- classmethod from_csv(fpath: str | PathLike | Path) PreferenceProfile[source]
Creates a PreferenceProfile from a csv, formatted from the
to_csvmethod.- Parameters:
fpath (Union[str, PathLike, Path]) – Path to csv.
- Raises:
ValueError – If csv is improperly formatted for VoteKit.
ProfileError – If read profile has no rankings or scores.
- group_ballots() RankProfile[source]
Groups ballots by rankings and updates weights. Retains voter sets, but loses ballot indices.
- Returns:
A RankProfile object with grouped ballot list.
- Return type:
- to_csv(fpath: str | PathLike | Path, include_voter_set: bool = False, weight_precision: int = 2)[source]
Saves PreferenceProfile to a custom CSV format.
- Parameters:
fpath (Union[str, PathLike, Path]) – Path to the saved csv.
include_voter_set (bool, optional) – Whether or not to include the voter set of each ballot. Defaults to False.
weight_precision (int) – Number of decimals to round float weights to. Defaults to 2.
- Raises:
ProfileError – Cannot write a profile with no ballots to a csv.
ValueError – File path must be provided.
- class votekit.pref_profile.ScoreProfile(*, ballots: ~typing.Sequence[~votekit.ballot.Ballot] = (), candidates: ~typing.Sequence[str] = (), max_ranking_length: int = 0, df: ~pandas.core.frame.DataFrame = Empty DataFrame Columns: [] Index: [], **kwargs)[source]
- property ballots: tuple[ScoreBallot, ...]
Compute the ballot tuple as a cached property.
- classmethod from_csv(fpath: str | PathLike | Path) PreferenceProfile[source]
Creates a PreferenceProfile from a csv, formatted from the
to_csvmethod.- Parameters:
fpath (str) – Path to csv.
- Raises:
ValueError – If csv is improperly formatted for VoteKit.
ProfileError – If read profile has no rankings or scores.
- group_ballots() ScoreProfile[source]
Groups ballots by scores and updates weights. Retains voter sets, but loses ballot ids.
- Returns:
A ScoreProfile object with grouped ballot list.
- Return type:
- to_csv(fpath: str | PathLike | Path, include_voter_set: bool = False, weight_precision: int = 2)[source]
Saves PreferenceProfile to a custom CSV format.
- Parameters:
fpath (Union[str, PathLike, Path]) – Path to the saved csv.
include_voter_set (bool, optional) – Whether or not to include the voter set of each ballot. Defaults to False.
weight_precision (int) – Number of decimals to round float weights to. Defaults to 2.
- Raises:
ProfileError – Cannot write a profile with no ballots to a csv.
ValueError – File path must be provided.
- class votekit.pref_profile.CleanedRankProfile(*args, **kwargs)[source]
CleanedRankProfile class, which is used to keep track of how ballots are altered from the original profile. In addition to a custom __str__ method, this class implements a collection of sets that track the indices of the ballot dataframe, and how they are changed by different cleaning rules. It also retains the parent profile of the CleanedRankProfile, allowing for full recovery of the cleaning steps.
- Parameters:
ballots (tuple[Ballot], optional) – Tuple of
Ballotobjects. Defaults to empty tuple.candidates (tuple[str], optional) – Tuple of candidate strings. Defaults to empty tuple. If empty, computes this from any candidate listed on a ballot with positive weight.
max_ranking_length (int, optional) – The length of the longest allowable ballot, i.e., how many candidates are allowed to be ranked in an election. Defaults to longest observed ballot.
parent_profile (PreferenceProfile | CleanedProfile) – The profile that was altered. If you apply multiple cleaning functions, the parent is always the profile immediately before cleaning, so you need to recurse to get the original, uncleaned profile.
df_index_column (list[int]) – The indices of the ballots in the df from the parent profile.
no_wt_altr_idxs (set[int], optional) – Set of indices of ballots that have 0 weight as a result of cleaning. Indices are with respect to
parent_profile.df.no_rank_altr_idxs (set[int], optional) – Set of indices of ballots that have no ranking as a result of cleaning. Indices are with respect to
parent_profile.df.nonempty_altr_idxs (set[int], optional) – Set of indices of ballots that have been altered but still have weight and (ranking or score) as a result of cleaning. Indices are with respect to
parent_profile.df.unaltr_idxs (set[int], optional) – Set of indices of ballots that have been unaltered by cleaning. Indices are with respect to
parent_profile.df.
- class votekit.pref_profile.CleanedScoreProfile(*args, **kwargs)[source]
CleanedScoreProfile class, which is used to keep track of how ballots are altered from the original profile. In addition to a custom __str__ method, this class implements a collection of sets that track the indices of the ballot dataframe, and how they are changed by different cleaning rules. It also retains the parent profile of the CleanedScoreProfile, allowing for full recovery of the cleaning steps.
- Parameters:
ballots (tuple[Ballot], optional) – Tuple of
Ballotobjects. Defaults to empty tuple.candidates (tuple[str], optional) – Tuple of candidate strings. Defaults to empty tuple. If empty, computes this from any candidate listed on a ballot with positive weight.
parent_profile (ScoreProfile | CleanedScoreProfile) – The profile that was altered. If you apply multiple cleaning functions, the parent is always the profile immediately before cleaning, so you need to recurse to get the original, uncleaned profile.
df_index_column (list[int]) – The indices of the ballots in the df from the parent profile.
no_wt_altr_idxs (set[int], optional) – Set of indices of ballots that have 0 weight as a result of cleaning. Indices are with respect to
parent_profile.df.no_scores_altr_idxs (set[int], optional) – Set of indices of ballots that have no scores as a result of cleaning. Indices are with respect to
parent_profile.df.nonempty_altr_idxs (set[int], optional) – Set of indices of ballots that have been altered but still have weight and (ranking or score) as a result of cleaning. Indices are with respect to
parent_profile.df.unaltr_idxs (set[int], optional) – Set of indices of ballots that have been unaltered by cleaning. Indices are with respect to
parent_profile.df.
- votekit.pref_profile.utils.convert_rank_profile_to_score_profile_via_score_vector(rank_profile: RankProfile, score_vector: Sequence[float]) ScoreProfile[source]
Convert a rank profile to a score profile using a score vector. Ballots must not contain ties. Score vector should be non-increasing and non-negative.
- Parameters:
rank_profile (RankProfile) – Rank profile to convert.
score_vector (Sequence[float]) – Score vector to use.
- Returns:
Score profile.
- Return type:
- Raises:
ValueError – Ballots must not contain ties.
ValueError – Score vector must be non-increasing and non-negative.
- votekit.pref_profile.utils.convert_row_to_rank_ballot(row: Series, max_ranking_length: int = 0) RankBallot[source]
Convert a row of a properly formatted profile.df to a Ballot.
- Parameters:
row (pd.Series) – Row of a profile.df.
max_ranking_length (int, optional) – The maximum length of a ranking. Defaults to 0, which is used for ballots with no ranking.
- Returns:
Ballot corresponding to the row of the df.
- Return type:
- votekit.pref_profile.utils.convert_row_to_score_ballot(row: Series, candidates: tuple[str, ...]) ScoreBallot[source]
Convert a row of a properly formatted profile.df to a Ballot.
- Parameters:
row (pd.Series) – Row of a profile.df.
candidates (tuple[str,...]) – The name of the candidates.
- Returns:
Ballot corresponding to the row of the df.
- Return type:
- votekit.pref_profile.utils.profile_df_head(profile: PreferenceProfile, n: int, sort_by_weight: bool | None = True, percents: bool | None = False, totals: bool | None = False, n_decimals: int = 1) pd.DataFrame[source]
Returns a pd.DataFrame with the top-n ballots in profile.
- Parameters:
n (int) – Number of ballots to view.
sort_by_weight (bool, optional) – If True, rank ballot from most to least votes. If sorting by weight, index resets. Defaults to True.
percents (bool, optional) – If True, show voter share for a given ballot. Defaults to False.
totals (bool, optional) – If True, show total values for Percent and Weight. Defaults to False.
n_decimals (int, optional) – Number of decimals to round to. Defaults to 1.
- Returns:
A dataframe with top-n ballots.
- Return type:
pandas.DataFrame
- Raises:
ZeroDivisionError – Profile has 0 total ballot weight; cannot show percentages.
- votekit.pref_profile.utils.profile_df_tail(profile: PreferenceProfile, n: int, sort_by_weight: bool | None = True, percents: bool | None = False, totals: bool | None = False, n_decimals: int = 1) pd.DataFrame[source]
Returns a pd.DataFrame with the bottom-n ballots in profile.
- Parameters:
n (int) – Number of ballots to view.
sort_by_weight (bool, optional) – If True, rank ballot from least to most votes. Defaults to True.
percents (bool, optional) – If True, show voter share for a given ballot. Defaults to False.
totals (bool, optional) – If True, show total values for Percent and Weight. Defaults to False.
n_decimals (int, optional) – Number of decimals to round to. Defaults to 1.
- Returns:
A data frame with bottom-n ballots.
- Return type:
pandas.DataFrame
- Raises:
ZeroDivisionError – Profile has 0 total ballot weight; cannot show percentages.
- votekit.pref_profile.utils.rank_profile_to_ballot_dict(rank_profile: RankProfile, standardize: bool = False) dict[RankBallot, float][source]
Converts profile to dictionary with keys = ballots and values = corresponding total weights.
- Parameters:
rank_profile (RankProfile) – Profile to convert.
standardize (bool, optional) – If True, divides the weight of each ballot by the total weight. Defaults to False.
- Returns:
A dictionary with ballots (keys) and corresponding total weights (values).
- Return type:
dict[Ballot, float]
- votekit.pref_profile.utils.rank_profile_to_ranking_dict(rank_profile: RankProfile, standardize: bool = False) dict[tuple[frozenset[str], ...], float][source]
Converts profile to dictionary with keys = rankings and values = corresponding total weights.
- Parameters:
rank_profile (RankProfile) – Profile to convert.
standardize (bool, optional) – If True, divides the weight of each ballot by the total weight. Defaults to False.
- Returns:
A dictionary with rankings (keys) and corresponding total weights (values).
- Return type:
dict[tuple[frozenset[str],…], float]
- Raises:
TypeError – Profile must be a RankProfile.
- votekit.pref_profile.utils.score_profile_to_ballot_dict(score_profile: ScoreProfile, standardize: bool = False) dict[ScoreBallot, float][source]
Converts profile to dictionary with keys = ballots and values = corresponding total weights.
- Parameters:
score_profile (ScoreProfile) – Profile to convert.
standardize (bool, optional) – If True, divides the weight of each ballot by the total weight. Defaults to False.
- Returns:
A dictionary with ballots (keys) and corresponding total weights (values).
- Return type:
dict[Ballot, float]
- votekit.pref_profile.utils.score_profile_to_scores_dict(score_profile: ScoreProfile, standardize: bool = False) dict[tuple[str, float], float][source]
Converts profile to dictionary with keys = scores and values = corresponding total weights.
- Parameters:
score_profile (ScoreProfile) – Profile to convert.
standardize (bool, optional) – If True, divides the weight of each ballot by the total weight. Defaults to False.
- Returns:
A dictionary with scores (keys) and corresponding total weights (values).
- Return type:
dict[tuple[str, float], float]
- Raises:
TypeError – Profile must be a ScoreProfile.
Preference Intervals
- class votekit.pref_interval.PreferenceInterval(interval: dict)[source]
PreferenceInterval class, contains preference for individual candidates stored as relative share of the interval [0,1].
- Parameters:
interval (dict) – A dictionary representing the given PreferenceInterval. The keys are candidate names, and the values are floats representing that candidates share of the interval. Does not have to sum to one, the init method will renormalize. Includes candidates with zero support.
- interval
A dictionary representing the given PreferenceInterval. The keys are candidate names, and the values are floats representing that candidates share of the interval. Does not have to sum to one, the init method will renormalize. Does not include candidates with zero support.
- Type:
dict
- candidates
A frozenset of candidates (with zero and non-zero support).
- Type:
frozenset
- non_zero_cands
A frozenset of candidates with non-zero support.
- Type:
frozenset
- zero_cands
A frozenset of candidates with zero support.
- Type:
frozenset
- classmethod from_dirichlet(candidates: list[str], alpha: float)[source]
Samples a PreferenceInterval from the Dirichlet distribution on the candidate simplex. Alpha tends to 0 is strong support, alpha tends to infinity is uniform support, alpha = 1 is all bets are off.
- Parameters:
candidates (list) – List of candidate strings.
alpha (float) – Alpha parameter for Dirichlet distribution.
- Returns:
PreferenceInterval
Ballot Generators
- class votekit.ballot_generator.BallotGenerator(**kwargs)[source]
Bases:
objectBase class for ballot generation models that use the candidate simplex (e.g. Plackett-Luce, Bradley-Terry, etc.).
- Parameters:
**kwargs – Arbitrary keyword arguments needed for different models.
- static ballot_pool_to_profile(ballot_pool, candidates) PreferenceProfile[source]
Given a list of ballots and candidates, convert them into a
PreferenceProfile.- Parameters:
ballot_pool (list) – A list of ballots, where each ballot is a tuple of candidates indicating their ranking from top to bottom.
candidates (list) – A list of candidate strings.
- Returns:
A
PreferenceProfilerepresenting the ballots in the election.- Return type:
PreferenceProfile
- classmethod from_params(slate_to_candidates: dict, bloc_voter_prop: dict, cohesion_parameters: dict, alphas: dict, **data)[source]
Initializes a
BallotGeneratorby constructing preference intervals from parameters.- Parameters:
slate_to_candidates (dict) – Dictionary whose keys are bloc names and whose values are lists of candidate strings that make up the slate.
bloc_voter_prop (dict) – Dictionary whose keys are bloc strings and values are floats denoting population share.
cohesion_parameters (dict) – Dictionary mapping of bloc string to dictionary whose keys are bloc strings and values are cohesion parameters.
alphas (dict) – Dictionary mapping of bloc string to dictionary whose keys are bloc strings and values are alphas for Dirichlet distributions.
**data – kwargs to be passed to the init method.
- Raises:
ValueError – If the voter proportion for blocs don’t sum to 1.
ValueError – Blocs are not the same.
- Returns:
Initialized ballot generator.
- Return type:
- abstractmethod generate_profile(number_of_ballots: int, by_bloc: bool = False) PreferenceProfile | Tuple | dict[source]
Generates a
PreferenceProfile.- Parameters:
number_of_ballots (int) – Number of ballots to generate.
by_bloc (bool) – True if you want the generated profiles returned as a tuple
(pp_by_bloc, pp), wherepp_by_blocis a dictionary with keys = bloc strings and values =PreferenceProfileandppis the aggregated profile. False if you only want the aggregated profile. Defaults to False.
- Returns:
Union[PreferenceProfile, Tuple]
- class votekit.ballot_generator.BlocSlateConfig(*, n_voters: int, slate_to_candidates: Mapping[str, Sequence[str]] | None = None, bloc_proportions: Mapping[str, int | float] | Series | None = None, preference_mapping: Mapping[str, Mapping[str, Mapping[str, float | int] | PreferenceInterval]] | DataFrame | None = None, cohesion_mapping: Mapping[str, Mapping[str, float] | Series] | DataFrame | None = None, silent: bool = False)[source]
Bases:
objectConfiguration object for BlocSlateGenerator that holds all the parameters needed to generate a set of ballots using one of our ballot generation algorithms involving both voter blocs and slates of candidates.
- Parameters:
n_voters (int) – The total number of voters to simulate. Must be > 0.
slate_to_candidates (Optional[Mapping[str, Sequence[str]]]) – A mapping of slate names to sequences of candidate names. Each slate must have a non-empty list of candidates, and no candidate may appear in more than one slate. If None, defaults to an empty mapping.
bloc_proportions (Optional[BlocPropotionMapping]) – A mapping of voter bloc names to their proportions in the electorate. The proportions must be non-negative and sum to 1. If None, defaults to an empty mapping.
preference_mapping (Optional[PreferenceMapping]) – A nested mapping of voter bloc names to slate names to either PreferenceInterval or Mapping[str, float|int] representing the preference scores for each candidate in the slate. Each bloc must have a mapping for every slate defined in slate_to_candidates, and no candidate may appear in more than one slate. The scores for each bloc and slate must be non-negative and sum to 1. If None, defaults to an empty mapping.
cohesion_mapping (Optional[CohesionMapping]) – A mapping of voter bloc names to mappings of slate names to their cohesion parameters. The cohesion parameters must be non-negative and sum to 1 for each bloc. If None, defaults to an empty mapping.
silent (bool) – If True, suppresses warnings about configuration issues. Defaults to False.
- n_voters
The total number of voters to simulate.
- Type:
int
- slate_to_candidates
A mapping of slate names to sequences of names. Behaves like a MutableMapping[str, Sequence[str]] (think dictionary).
- Type:
SlateCandMap
- bloc_proportions
A mapping of voter bloc names to their proportions in the electorate. Behaves like a MutableMapping[str, float] (think dictionary).
- Type:
BlocProportions
- preference_df
A DataFrame with blocs as the index and candidates as columns, containing the preference scores for each candidate in each bloc.
- Type:
pd.DataFrame
- cohesion_df
A DataFrame with blocs as the index and slates as columns, containing the cohesion parameters for each slate in each bloc.
- Type:
pd.DataFrame
- silent
If True, suppresses warnings about configuration issues.
- Type:
bool
- Warns:
ConfigurationWarning – If there is anything in the configuration that, when passed to a ballot generator, would cause an error.
- Raises:
TypeError – On invalid types for any of the arguments or assignments (e.g., non-string keys, non-mapping shapes).
ValueError – On invalid values (e.g., empty candidate lists, duplicate keys, non-finite numbers, negative proportions/scores).
- add_slate(slate: str, slate_candidate_list: Sequence[str]) None[source]
Add a new slate with the given candidates to the configuration.
Note: Also modifies the preference_df and cohesion_df to add dummy values for the new slate and candidates.
- Parameters:
slate (str) – Name of the new slate to add.
slate_candidate_list (Sequence[str]) – List of candidate names for the new slate.
- Raises:
ValueError – If the slate already exists
ValueError – If any candidate in the slate_candidate_list already exists in the configuration.
ValueError – If the slate_candidate_list is empty.
TypeError – If slate is not a str or any candidate in the slate_candidate_list is not a str.
- property blocs: list[str]
A list of all voter blocs. Derived from the keys of bloc_proportions.
- Type:
Computed property
- property candidates: list[str]
A flat list of all candidates in all slate. Derived from the values of slate_to_candidates.
- Type:
Computed property
- copy() BlocSlateConfig[source]
Create a deep copy of the current configuration.
- Returns:
A deep copy of the current configuration.
- Return type:
- get_combined_preference_intervals_by_bloc() dict[str, PreferenceInterval][source]
Get the combined preference intervals for each bloc across all slates.
The combined preference interval for a bloc is computed by combining the preference intervals for each slate, weighted by the bloc’s cohesion parameters for each slate.
- Returns:
- A mapping of bloc names to their combined
preference intervals.
- Return type:
dict[str, PreferenceInterval]
- get_preference_interval_for_bloc_and_slate(bloc_name: str, slate_name: str) PreferenceInterval[source]
Get the preference interval for a given bloc and slate.
- Parameters:
bloc (str) – The name of the voter bloc.
slate (str) – The name of the slate.
- Returns:
The preference interval for the given bloc and slate.
- Return type:
- get_preference_intervals_for_bloc(block_name) dict[str, PreferenceInterval][source]
Get the preference intervals for each bloc and slate.
- Returns:
- A nested mapping of bloc names to
slate names to their preference intervals.
- Return type:
dict[str, dict[str, PreferenceInterval]]
- is_valid(*, raise_errors: bool = False, raise_warnings: bool = True) bool[source]
Check if the current configuration is valid and can be passed to a ballot generator.
- Parameters:
raise_errors (bool) – If True, raises the first error encountered instead of returning False. Defaults to False.
raise_warnings (bool) – If True, raises warnings for non-fatal issues (e.g., bloc proportions not summing to 1). Defaults to True.
- Returns:
True if the configuration is valid, False otherwise.
- Return type:
bool
- normalize_cohesion_df() None[source]
Normalize each bloc’s cohesion parameters so that they sum to 1.
Note: Will set all uninitialized slates (value -1.0) to 0.0 before normalizing.
- normalize_preference_intervals() None[source]
Normalize each bloc’s preference interval so that it sums to 1.
Note: Will set all uninitialized candidates (value -1.0) to 0.0 before normalizing.
- read_dirichlet_alphas() DataFrame | None[source]
Get a copy of the current Dirichlet alphas.
- Returns:
A DataFrame with blocs as the index and slates as columns, containing the Dirichlet alpha values for each slate in each bloc, or None if Dirichlet alphas have not been set.
- Return type:
Optional[pd.DataFrame]
- remove_candidates(candidates: str | Sequence[str]) None[source]
Remove candidates from the configuration.
Note: Also modifies the preference_df and cohesion_df to remove any slates that contained the removed candidates if the slate becomes empty.
- Parameters:
candidates (Union[str, Sequence[str]]) – Candidate name or list of candidate names to remove.
- remove_slate(slate: str) None[source]
Remove a slate and its candidates from the configuration.
Note: Also modifies the preference_df and cohesion_df to remove the slate and its candidates.
- Parameters:
slate (str) – Name of the slate to remove.
- rename_candidates(candidate_mapping: Mapping[str, str]) None[source]
Rename candidates in the configuration in place.
- Parameters:
candidate_mapping (Mapping[str, str]) – A mapping of old candidate names to new candidate names.
- Raises:
ValueError – If any old candidate name does not exist in the configuration.
TypeError – If any key or value in candidate_mapping is not a str.
- resample_preference_intervals_from_dirichlet_alphas() None[source]
Resample the preference intervals for each bloc from the current Dirichlet alphas.
Note: This will overwrite any existing preference intervals in the configuration.
- set_dirichlet_alphas(alphas: Mapping[str, Mapping[str, float | int]] | DataFrame) None[source]
Set the Dirichlet alphas for the configuration and resample the preference intervals.
- Parameters:
alphas (Union[Mapping[str, Mapping[str, Union[float, int]]], pd.DataFrame]) – A mapping of bloc names to mappings of slate names to their Dirichlet alpha values. Each bloc must have a mapping for every slate defined in slate_to_candidates. All alpha values must be positive finite reals.
- Raises:
ConfigurationWarning – If preference intervals have already been set without setting the Dirichlet alphas. Setting the Dirichlet alphas will overwrite the existing preference intervals
- property slates: list[str]
A list of all slates. Derived from the keys of slate_to_candidates.
- Type:
Computed property
- votekit.ballot_generator.cambridge_profile_generator(config: BlocSlateConfig, *, path: Path | None = None, majority_bloc: str | None = None, minority_bloc: str | None = None, group_ballots: bool = False) RankProfile[source]
Generates a RankProfile using historical RCV elections occurring in Cambridge, MA.
Alternative election data can be used if specified. The historical data must be contianed at the path specified by the ‘path’ keyword argument, and the data must be a pickle file containing a dictionary mapping ballot types with labels ‘W’ and ‘C’ (i.e. tuples of the form (‘W’,’C’,’W’,…) and the like) to their frequencies. Here ‘W’ indicates the majority bloc and slate and ‘C’ indicates the minority bloc and slate. Assumes that there are two blocs which mimic the formatting of the historical Cambridge data.
Based on cohesion parameters, decides if a voter casts their top choice within their bloc or in the opposing bloc. Then uses historical data; given their first choice, to choose a ballot type from the historical distribution.
- Parameters:
config (BlocSlateConfig) – Configuration object containing all necessary parameters for working with a bloc-slate ballot generator.
- Kwargs:
- path (Optional[Path]): File path to an election data file to sample from. If none, will
default to Cambridge election data that ships with VoteKit
- majority_bloc (Optional[str]): Name of the bloc corresponding to the majority bloc. Defaults to
whichever bloc has majority via
bloc_voter_prop.- minority_bloc (Optional[str]): Name of the bloc corresponding to the minority bloc. Defaults to
whichever bloc has minority via
bloc_voter_prop.- group_ballots (bool): If True, groups identical ballots in the resulting profiles.
Defaults to False.
- Returns:
- A
RankProfileobjects representing the joint preference profile over all blocs.
- A
- Return type:
- votekit.ballot_generator.cambridge_profiles_by_bloc_generator(config: BlocSlateConfig, *, path: Path | None = None, majority_bloc: str | None = None, minority_bloc: str | None = None, group_ballots: bool = False) dict[str, RankProfile][source]
Generates a dictionary mapping bloc names to RankProfiles using historical RCV elections occurring in Cambridge, MA.
Alternative election data can be used if specified. The historical data must be contianed at the path specified by the ‘path’ keyword argument, and the data must be a pickle file containing a dictionary mapping ballot types with labels ‘W’ and ‘C’ (i.e. tuples of the form (‘W’,’C’,’W’,…) and the like) to their frequencies. Here ‘W’ indicates the majority bloc and slate and ‘C’ indicates the minority bloc and slate. Assumes that there are two blocs which mimic the formatting of the historical Cambridge data.
Based on cohesion parameters, decides if a voter casts their top choice within their bloc or in the opposing bloc. Then uses historical data; given their first choice, to choose a ballot type from the historical distribution.
- Parameters:
config (BlocSlateConfig) – Configuration object containing all necessary parameters for working with a bloc-slate ballot generator.
- Kwargs:
- path (Optional[Path]): File path to an election data file to sample from. If none, will
default to Cambridge election data that ships with VoteKit
- majority_bloc (Optional[str]): Name of the bloc corresponding to the majority bloc. Defaults to
whichever bloc has majority via
bloc_voter_prop.- minority_bloc (Optional[str]): Name of the bloc corresponding to the minority bloc. Defaults to
whichever bloc has minority via
bloc_voter_prop.- group_ballots (bool): If True, groups identical ballots in the resulting profiles.
Defaults to False.
- Returns:
- A dictionary whose keys are bloc strings and values are
RankProfileobjects representing the generated preference profiles for each bloc.
- Return type:
dict[str, RankProfile]
- votekit.ballot_generator.clustered_spacial_profile_and_positions_generator(number_of_ballots: dict[str, int], candidates: list[str], voter_dist: ~typing.Callable[[...], ~numpy.ndarray] = <bound method RandomState.normal of RandomState(MT19937)>, voter_dist_kwargs: ~typing.Dict[str, ~typing.Any] | None = None, candidate_dist: ~typing.Callable[[...], ~numpy.ndarray] = <bound method RandomState.uniform of RandomState(MT19937)>, candidate_dist_kwargs: ~typing.Dict[str, ~typing.Any] | None = None, distance: ~typing.Callable[[~numpy.ndarray, ~numpy.ndarray], float] = <function euclidean_dist>) Tuple[RankProfile, dict[str, ndarray], ndarray][source]
Samples a metric position for each candidate from the input candidate distribution. For each candidate, then sample number_of_ballots[candidate] metric positions for voters which will be centered around the candidate. With sampled positions, this method then creates a ranked RankProfile in which voter’s preferences are consistent with their distances to the candidates in the metric space.
- Parameters:
number_of_ballots (dict[str, int]) – The number of voters attributed to each candidate {candidate string: # voters}.
by_bloc (bool) – Dummy variable from parent class.
- Returns:
A tuple containing the preference profile object, a dictionary with each candidate’s position in the metric space, and a matrix where each row is a single voter’s position in the metric space.
- Return type:
Tuple[RankProfile, dict[str, numpy.ndarray], numpy.ndarray]
- votekit.ballot_generator.convert_bloc_proportion_map_to_series(bloc_prop: Mapping[str, int | float] | Series) Series[source]
Convert a dictionary of bloc proportions to a Series.
- Parameters:
bloc_prop (BlocPropotionMapping) – The bloc proportion mapping to convert.
- Returns:
A pandas Series with bloc names as the index and proportions as values.
- Return type:
pd.Series
- Raises:
TypeError – If bloc_prop is not a Mapping[str, float] or pd.Series with string index and numeric dtype.
ValueError – If bloc_prop contains non-finite values, negative values, or does not sum to 1.
- votekit.ballot_generator.convert_cohesion_map_to_cohesion_df(cohesion_map: Mapping[str, Mapping[str, float] | Series] | DataFrame) DataFrame[source]
Convert a dictionary of cohesion parameters to a DataFrame to pass to BlocSlateConfig.
- Parameters:
cohesion_map (CohesionMapping) – The cohesion mapping to convert.
- Returns:
A pandas DataFrame with blocs as the index and slates as columns.
- Return type:
pd.DataFrame
- Raises:
TypeError – If cohesion_map is not a Mapping[str, Mapping[str, float]] or pd.DataFrame with string index and float dtypes.
ValueError – If cohesion_map contains non-finite values.
ValueError – If cohesion_map contains duplicate blocs or slates.
- votekit.ballot_generator.convert_preference_map_to_preference_df(preference_map: Mapping[str, Mapping[str, Mapping[str, float | int] | PreferenceInterval]] | DataFrame) DataFrame[source]
Convert a dictionary of preference mappings to a DataFrame to pass to BlocSlateConfig.
- Parameters:
preference_map (PreferenceMapping) – The preference mapping to convert.
- Returns:
A pandas DataFrame with blocs as the index and candidates as columns.
- Return type:
pd.DataFrame
- Raises:
TypeError – If preference_map is not a Mapping[str, Mapping[str, PreferenceIntervalLike]] or pd.DataFrame with string index and numeric dtypes. Note that PreferenceIntervalLike is either a Mapping[str, float|int] or PreferenceInterval.
ValueError – If preference_map contains non-finite values.
ValueError – If preference_map contains duplicate blocs or candidates.
- votekit.ballot_generator.iac_profile_generator(candidates: Sequence[str], number_of_ballots: int, max_ballot_length: int | None = None) RankProfile[source]
Generate a profile according to the Impartial Anonymous Culture (IAC) model where each profile is equally likely.
- Parameters:
candidates (Sequence[str]) – List of candidate strings.
number_of_ballots (int) – Number of ballots to generate.
max_ballot_length (Optional[int]) – Maximum length of each ballot. If None, defaults to the number of candidates.
- Returns:
Generated rank profile
- Return type:
- votekit.ballot_generator.ic_profile_generator(candidates: Sequence[str], number_of_ballots: int, max_ballot_length: int | None = None, allow_short_ballots: bool = False) RankProfile[source]
Impartial Culture model where each ballot is equally likely. Equivalent to the ballot simplex with an alpha value of infinity.
- Parameters:
candidates (Sequence[str]) – The list of candidates in the election.
number_of_ballots (int) – The number of ballots to generate for the profile.
max_ballot_length (Optional[int]) – Maximum length of each ballot. If None, defaults to the number of candidates.
allow_short_ballots (bool, optional) – Whether to allow short ballots. Defaults to False.
- Returns:
The generated preference profile
- Return type:
- votekit.ballot_generator.name_bt_profile_generator(config: BlocSlateConfig, *, group_ballots=True) RankProfile[source]
Generate a preference profile using the name-BradleyTerry model.
The probability of sampling the ranking \(X>Y>Z\) is proportional to \(P(X>Y)*P(X>Z)*P(Y>Z)\). These individual probabilities are based on the preference interval: :math: P(X>Y) = x/(x+y).
- Parameters:
config (BlocSlateConfig) – Configuration object containing all necessary parameters for working with a bloc-slate ballot generator.
group_ballots (bool) – If True, group identical ballots in the returned profile and set the weight accordingly. Defaults to True.
- Returns:
Generated preference profile.
- Return type:
- votekit.ballot_generator.name_bt_profile_generator_using_mcmc(config: BlocSlateConfig, *, group_ballots=True, verbose: bool = False, burn_in_time: int = 0, chain_length: int | None = None) RankProfile[source]
Generate a preference profile using MCMC sampling from the name-BradleyTerry model.
- Parameters:
config (BlocSlateConfig) – Configuration object containing all necessary parameters for working with a bloc-slate ballot generator.
- Kwargs:
- group_ballots (bool): If True, group identical ballots in the returned profile and
set the weight accordingly. Defaults to True.
verbose (bool): If True, print the acceptance ratio of the chain. Defaults to False. burn_in_time (int): the number of ballots discarded in the beginning of the chain.
Defaults to 0.
- chain_length (Optional[int]): the length of the Markov Chain. Ballots are subsampled every
chain_length//n_ballots steps from the chain until the desired number of ballots is reached. Defaults to None which sets the chain_length to the number of ballots in the config.
- Returns:
Generated preference profile.
- Return type:
- votekit.ballot_generator.name_bt_profiles_by_bloc_generator(config: BlocSlateConfig, *, group_ballots=True) dict[str, RankProfile][source]
Generate preference profiles by bloc using the name-BradleyTerry model.
The probability of sampling the ranking \(X>Y>Z\) is proportional to \(P(X>Y)*P(X>Z)*P(Y>Z)\). These individual probabilities are based on the preference interval: :math: P(X>Y) = x/(x+y).
- Parameters:
config (BlocSlateConfig) – Configuration object containing all necessary parameters for working with a bloc-slate ballot generator.
group_ballots (bool) – If True, group identical ballots in the returned profile and set the weight accordingly. Defaults to True.
- Returns:
Generated preference profiles by bloc.
- Return type:
dict[str, RankProfile]
- votekit.ballot_generator.name_bt_profiles_by_bloc_generator_using_mcmc(config: BlocSlateConfig, *, group_ballots=True, verbose: bool = False, burn_in_time: int = 0, chain_length: int | None = None) dict[str, RankProfile][source]
Generate a preference profile dictionary by bloc using MCMC sampling from the name-BradleyTerry model.
- Parameters:
config (BlocSlateConfig) – Configuration object containing all necessary parameters for working with a bloc-slate ballot generator.
- Kwargs:
- group_ballots (bool): If True, group identical ballots in the returned profile and
set the weight accordingly. Defaults to True.
verbose (bool): If True, print the acceptance ratio of the chain. Defaults to False. burn_in_time (int): the number of ballots discarded in the beginning of the chain.
Defaults to 0.
- chain_length (Optional[int]): the length of the Markov Chain. Ballots are subsampled every
chain_length//n_ballots steps from the chain until the desired number of ballots is reached. Defaults to None which sets the chain_length to the number of ballots in the config.
- Returns:
Generated preference profiles by bloc.
- Return type:
dict[str, RankProfile]
- votekit.ballot_generator.name_cumulative_ballot_generator_by_bloc(config: BlocSlateConfig, *, total_points: int | None = None, group_ballots: bool = True) dict[str, ScoreProfile][source]
Generates a dictionary mapping bloc names to ScoreProfiles using the name-Cumulative model.
This model samples with replacement from a combined preference interval and counts candidates with multiplicity.
- Parameters:
config (BlocSlateConfig) – Configuration object containing all necessary parameters for working with a bloc-slate ballot generator.
- Kwargs:
- total_points (Optional[int]): The total number of points to distribute among candidates.
If None, defaults to the number of candidates in the configuration. Defaults to None.
- group_ballots (bool): If True, groups identical ballots in the resulting profile.
Defaults to True.
- Returns:
- A dictionary whose keys are bloc strings and values are
ScoreProfile objects representing the generated ballots for each bloc.
- Return type:
dict[str, ScoreProfile]
- votekit.ballot_generator.name_cumulative_profile_generator(config: BlocSlateConfig, *, total_points: int | None = None, group_ballots: bool = True) ScoreProfile[source]
Generates a ScoreProfile using the name-Cumulative.
This model samples with replacement from a combined preference interval and counts candidates with multiplicity.
- Parameters:
config (BlocSlateConfig) – Configuration object containing all necessary parameters for working with a bloc-slate ballot generator.
- Kwargs:
- total_points (Optional[int]): The total number of points to distribute among candidates.
If None, defaults to the number of candidates in the configuration. Defaults to None.
- group_ballots (bool): If True, groups identical ballots in the resulting profile.
Defaults to True.
- Returns:
A ScoreProfile object representing the generated ballots.
- Return type:
- votekit.ballot_generator.name_pl_profile_generator(config: BlocSlateConfig, *, group_ballots: bool = True) RankProfile[source]
Generates a merged preference profile using the name-Plackett-Luce model.
The Plackett-Luce model samples without replacement from each preference interval for each bloc of voters. These profiles are then merged into a single profile.
- Parameters:
config (BlocSlateConfig) – Configuration object containing all necessary parameters for working with a bloc-slate ballot generator.
group_ballots (bool) – If True, group identical ballots in the returned profile and set the weight accordingly. Defaults to True.
- Returns:
Merged
RankProfileobject generated by the model.- Return type:
- votekit.ballot_generator.name_pl_profiles_by_bloc_generator(config: BlocSlateConfig, *, group_ballots: bool = True) dict[str, RankProfile][source]
Generates a dictionary mapping bloc names to preference profiles by bloc using the name-Plackett-Luce model.
The Plackett-Luce model samples without replacement from each preference interval for each bloc of voters.
- Parameters:
config (BlocSlateConfig) – Configuration object containing all necessary parameters for working with a bloc-slate ballot generator.
group_ballots (bool) – If True, group identical ballots in the returned profile and set the weight accordingly. Defaults to True.
- Returns:
- Dictionary whose keys are bloc strings and values are
RankProfileobjects generated by the model for each bloc.
- Return type:
dict[str, RankProfile]
- votekit.ballot_generator.onedim_spacial_profile_generator(candidates: Sequence[str], number_of_ballots: int) RankProfile[source]
Generates a ranked preference profile where voters and candidates are positioned on a one-dimensional line according to a normal distribution. Voter preferences are determined by their proximity to candidates on this line.
- Parameters:
number_of_ballots (int) – The number of ballots to generate.
- Returns:
A ranked preference profile object.
- Return type:
- votekit.ballot_generator.sample_cohesion_ballot_types(slate_to_non_zero_candidates: dict[str, list[str]], num_ballots: int, cohesion_parameters_for_bloc: Mapping[str, float | int]) list[list[str]][source]
Returns a list of ballots; each ballot is a list of slate names (strings) in the order they appear on that ballot.
- Parameters:
slate_to_non_zero_candidates (dict[str, list[str]])
num_ballots (int)
cohesion_parameters_for_bloc (Mapping[str, Union[float, int]])
- Returns:
- A list of lists, where each list contains the bloc names in the order
they appear on the ballot.
- Return type:
list[list[str]]
- votekit.ballot_generator.slate_bt_profile_generator(config: BlocSlateConfig, *, group_ballots=True) RankProfile[source]
Generate a preference profile using the name-BradleyTerry model.
This model first samples a ballot type (e.g. AABABB) according the the Bradley-Terry model using the cohesion parameters for each slate and the candidate counts of those slates (so the utilities of each of the candidates in a slate are assumed to be uniform in this stage).
Once the ballot type is sampled, the candidate names for each of the positions is filled out by sampling without replacement within each slate according to the preference interval of that slate in the given bloc (i.e. according to the name-Plackett-Luce model).
- Parameters:
config (BlocSlateConfig) – Configuration object containing all necessary parameters for working with a bloc-slate ballot generator.
group_ballots (bool) – If True, group identical ballots in the returned profile and set the weight accordingly. Defaults to True.
- Returns:
Generated preference profile.
- Return type:
- votekit.ballot_generator.slate_bt_profile_generator_using_mcmc(config: BlocSlateConfig, *, group_ballots=True) RankProfile[source]
Generate a ranked preference profile using the slate-BradleyTerry model.
This model is mainly useful when then number of possible ballot types is too large to compute the full probability distribution on the present hardware (e.g. more than 12! possible ballot types).
The MCMC version of this model uses a Markov Chain Monte Carlo method to sample ballot types according to the slate-BradleyTerry model. After selecting a seed ballot, the model proposes swaps of adjacent slates in the ballot type and accepts or rejects the swap according to the ratio of the cohesion parameters of the two slates being swapped within a given block.
Once the ballot type is sampled, the candidate names for each of the positions is filled out by sampling without replacement within each slate according to the preference interval of that slate in the given bloc (i.e. according to the name-Plackett-Luce model).
- Parameters:
config (BlocSlateConfig) – Configuration object containing all necessary parameters for working with a bloc-slate ballot generator.
group_ballots (bool) – If True, group identical ballots in the returned profile and set the weight accordingly. Defaults to True.
- Returns:
Generated preference profile.
- Return type:
- votekit.ballot_generator.slate_bt_profiles_by_bloc_generator(config: BlocSlateConfig, *, group_ballots=True) dict[str, RankProfile][source]
Generate a dictionary mapping bloc names to ranked preference profiles using the slate-BradleyTerry model.
This model first samples a ballot type (e.g. AABABB) according the the Bradley-Terry model using the cohesion parameters for each slate and the candidate counts of those slates (so the utilities of each of the candidates in a slate are assumed to be uniform in this stage).
Once the ballot type is sampled, the candidate names for each of the positions is filled out by sampling without replacement within each slate according to the preference interval of that slate in the given bloc (i.e. according to the name-Plackett-Luce model).
- Parameters:
config (BlocSlateConfig) – Configuration object containing all necessary parameters for working with a bloc-slate ballot generator.
group_ballots (bool) – If True, group identical ballots in the returned profile and set the weight accordingly. Defaults to True.
- Returns:
Generated preference profiles by bloc.
- Return type:
dict[str, RankProfile]
- votekit.ballot_generator.slate_bt_profiles_by_bloc_generator_using_mcmc(config: BlocSlateConfig, *, group_ballots=True) dict[str, RankProfile][source]
Generate a dictionary mapping bloc names to ranked preference profiles using the slate-BradleyTerry model.
This model is mainly useful when then number of possible ballot types is too large to compute the full probability distribution on the present hardware (e.g. more than 12! possible ballot types).
The MCMC version of this model uses a Markov Chain Monte Carlo method to sample ballot types according to the slate-BradleyTerry model. After selecting a seed ballot, the model proposes swaps of adjacent slates in the ballot type and accepts or rejects the swap according to the ratio of the cohesion parameters of the two slates being swapped within a given block.
Once the ballot type is sampled, the candidate names for each of the positions is filled out by sampling without replacement within each slate according to the preference interval of that slate in the given bloc (i.e. according to the name-Plackett-Luce model).
- Parameters:
config (BlocSlateConfig) – Configuration object containing all necessary parameters for working with a bloc-slate ballot generator.
group_ballots (bool) – If True, group identical ballots in the returned profile and set the weight accordingly. Defaults to True.
- Returns:
Generated preference profiles by bloc.
- Return type:
dict[str, RankProfile]
- votekit.ballot_generator.slate_pl_profile_generator(config: BlocSlateConfig, *, group_ballots: bool = True) RankProfile[source]
Generates a merged preference profile using the slate-Plackett-Luce model.
This model first samples a ballot type by flipping a cohesion parameter weighted coin. It then fills out the ballot type via sampling without replacement from the preference interval (i.e. according to the name-Plackett-Luce model).
- Parameters:
config (BlocSlateConfig) – Configuration object containing all necessary parameters for working with a bloc-slate ballot generator.
group_ballots (bool) – If True, group identical ballots in the returned profile and set the weight accordingly. Defaults to True.
- Returns:
Merged
RankProfileobject generated by the model.- Return type:
- votekit.ballot_generator.slate_pl_profiles_by_bloc_generator(config: BlocSlateConfig, *, group_ballots: bool = True) dict[str, RankProfile][source]
Generates a dictionary mapping bloc names to preference profiles using the slate-Plackett-Luce model.
This model first samples a ballot type by flipping a cohesion parameter weighted coin. It then fills out the ballot type via sampling without replacement from the preference interval (i.e. according to the name-Plackett-Luce model).
- Parameters:
config (BlocSlateConfig) – Configuration object containing all necessary parameters for working with a bloc-slate ballot generator.
group_ballots (bool) – If True, group identical ballots in the returned profile and set the weight accordingly. Defaults to True.
- Returns:
- Dictionary whose keys are bloc strings and values are
RankProfileobjects generated by the model for each bloc.
- Return type:
dict[str, RankProfile]
- votekit.ballot_generator.spacial_profile_and_positions_generator(number_of_ballots: int, candidates: list[str], voter_dist: ~typing.Callable[[...], ~numpy.ndarray] = <bound method RandomState.uniform of RandomState(MT19937)>, voter_dist_kwargs: ~typing.Dict[str, ~typing.Any] | None = None, candidate_dist: ~typing.Callable[[...], ~numpy.ndarray] = <bound method RandomState.uniform of RandomState(MT19937)>, candidate_dist_kwargs: ~typing.Dict[str, ~typing.Any] | None = None, distance: ~typing.Callable[[~numpy.ndarray, ~numpy.ndarray], float] = <function euclidean_dist>) Tuple[RankProfile, dict[str, ndarray], ndarray][source]
Samples a metric position for number_of_ballots voters from the voter distribution. Samples a metric position for each candidate from the input candidate distribution. With sampled positions, this method then creates a ranked RankProfile in which voter’s preferences are consistent with their distances to the candidates in the metric space.
- Parameters:
number_of_ballots (int) – The number of ballots to generate.
by_bloc (bool) – Dummy variable from parent class.
- Returns:
A tuple containing the preference profile object, a dictionary with each candidate’s position in the metric space, and a matrix where each row is a single voter’s position in the metric space.
- Return type:
Tuple[RankProfile, dict[str, numpy.ndarray], numpy.ndarray]
Cleaning
- votekit.cleaning.clean_rank_profile(profile: RankProfile, clean_ranking_func: Callable[[tuple], tuple], remove_empty_ballots: bool = True, remove_zero_weight_ballots: bool = True, retain_original_candidate_list: bool = True) CleanedRankProfile[source]
Allows user-defined cleaning rules for RankProfile. Input function that applies modification to ranking portion of the df, not weight or voterset.
- Parameters:
profile (RankProfile) – A RankProfile to clean.
clean_ranking_func (Callable[[tuple], tuple]) – Function that takes the ranking portion of a row of the profile df and returns an altered ranking.
remove_empty_ballots (bool, optional) – Whether or not to remove ballots that have no ranking and no scores as a result of the cleaning. Defaults to True.
remove_zero_weight_ballots (bool, optional) – Whether or not to remove ballots that have no weight as a result of the cleaning. Defaults to True.
retain_original_candidate_list (bool, optional) – Whether or not to use the candidate list from the original profile in the new profile. If False, uses only candidates who receive votes. Defaults to True.
- Returns:
A cleaned
RankProfile.- Return type:
- Raises:
ProfileError – Profile must only contain ranked ballots.
- votekit.cleaning.clean_score_profile(profile: ScoreProfile, clean_score_func: Callable[[tuple], tuple], remove_empty_ballots: bool = True, remove_zero_weight_ballots: bool = True, retain_original_candidate_list: bool = True) CleanedScoreProfile[source]
Allows user-defined cleaning rules for ScoreProfile. Cleaning function can only be applied to the score section of the dataframe, not the weight or voter set.
- Parameters:
profile (ScoreProfile) – A ScoreProfile to clean.
clean_score_func (Callable[[tuple], tuple]) – Function that takes the score portion of a row of the profile df and returns an altered score.
remove_empty_ballots (bool, optional) – Whether or not to remove ballots that have no no scores as a result of the cleaning. Defaults to True.
remove_zero_weight_ballots (bool, optional) – Whether or not to remove ballots that have no weight as a result of the cleaning. Defaults to True.
retain_original_candidate_list (bool, optional) – Whether or not to use the candidate list from the original profile in the new profile. If False, uses only candidates who receive votes. Defaults to True.
- Returns:
A cleaned
ScoreProfile.- Return type:
- Raises:
ProfileError – Profile must only contain ranked ballots.
- votekit.cleaning.condense_rank_ballot(ballot: RankBallot) RankBallot[source]
Given a ballot, removes any empty ranking positions and moves up any lower ranked candidates.
- Parameters:
ballot (RankBallot) – Ballot to condense.
- Returns:
Condensed ballot.
- Return type:
- votekit.cleaning.condense_rank_profile(profile: RankProfile, remove_empty_ballots: bool = True, remove_zero_weight_ballots: bool = True, retain_original_candidate_list: bool = True) CleanedRankProfile[source]
Given a ranked profile, removes any empty frozensets from the rankings and condenses the resulting ranking. If a ranking only has trailing empty positions, the condensed ranking is considered equivalent. For example, (A,B,{},{}) is mapped to (A,B) but considered unaltered since the ranking did not change.
Wrapper for clean_rank_profile that does some extra processing to ensure condensed ranking equivalence is handled correctly.
- Parameters:
profile (RankProfile) – Profile to remove repeated candidates from.
remove_empty_ballots (bool, optional) – Whether or not to remove ballots that have no ranking or scores as a result of cleaning. Defaults to True.
remove_zero_weight_ballots (bool, optional) – Whether or not to remove ballots that have no weight as a result of cleaning. Defaults to True.
retain_original_candidate_list (bool, optional) – Whether or not to use the candidate list from the original profile in the new profile. If False, uses only candidates who receive votes. Defaults to True.
- Returns:
A cleaned
RankProfile.- Return type:
- votekit.cleaning.remove_and_condense_rank_profile(removed: str | list, profile: RankProfile, remove_empty_ballots: bool = True, remove_zero_weight_ballots: bool = True, retain_original_candidate_list: bool = False) CleanedRankProfile[source]
Given a ranked profile, remove the given candidate(s) and condense the resulting rankings. If a ranking only has trailing empty positions, the condensed ranking is considered equivalent. For example, (A,B,{},{}) is mapped to (A,B) but considered unaltered since the ranking did not change.
This function is intended to save computational time in election methods, where removing and condensing happen frequently. Researches interested in the difference between removing and condensing should use
remove_candandcondense_profilein series.Wrapper for clean_rank_profile that does some extra processing to ensure the candidate list is handled correctly, and that ballot equivalence is checked.
- Parameters:
removed (Union[str, list]) – Candidate or list of candidates to be removed.
profile (RankProfile) – Profile to remove repeated candidates from.
remove_empty_ballots (bool, optional) – Whether or not to remove ballots that have no ranking or scores as a result of cleaning. Defaults to True.
remove_zero_weight_ballots (bool, optional) – Whether or not to remove ballots that have no weight as a result of cleaning. Defaults to True.
retain_original_candidate_list (bool, optional) – Whether or not to use the candidate list from the orginal profile in the new profile. If False, takes the original candidate list and removes the candidate(s) given in
removed, but preserves all others. Defaults to False.
- Returns:
A cleaned
RankProfile.- Return type:
- votekit.cleaning.remove_cand_rank_ballot(removed: str | list, ballot: RankBallot) RankBallot[source]
Removes specified candidate(s) from ballot. Does not condense the resulting ballot.
- Parameters:
removed (Union[str, list]) – Candidate or list of candidates to be removed.
ballot (RankBallot) – Ballot to remove candidates from.
- Returns:
Ballot with candidate(s) removed.
- Return type:
- votekit.cleaning.remove_cand_rank_profile(removed: str | list, profile: RankProfile, remove_empty_ballots: bool = True, remove_zero_weight_ballots: bool = True, retain_original_candidate_list: bool = False) CleanedRankProfile[source]
Given a ranked profile, remove the given candidate(s) from the ballots. Does not condense the resulting ballots.
Wrapper for clean_rank_profile that does some extra processing to ensure the candidate list is handled correctly.
- Parameters:
removed (Union[str, list]) – Candidate or list of candidates to be removed.
profile (RankProfile) – Profile to remove candidates from.
remove_empty_ballots (bool, optional) – Whether or not to remove ballots that have no ranking or scores as a result of cleaning. Defaults to True.
remove_zero_weight_ballots (bool, optional) – Whether or not to remove ballots that have no weight as a result of cleaning. Defaults to True.
retain_original_candidate_list (bool, optional) – Whether or not to use the candidate list from the orginal profile in the new profile. If False, takes the original candidate list and removes the candidate(s) given in
removed, but preserves all others. Defaults to False.
- Returns:
A cleaned
RankProfile.- Return type:
- Raises:
ProfileError – Profile must only contain ranked ballots.
- votekit.cleaning.remove_cand_score_ballot(removed: str | list, ballot: ScoreBallot) ScoreBallot[source]
Removes specified candidate(s) from ballot.
- Parameters:
removed (Union[str, list]) – Candidate or list of candidates to be removed.
ballot (ScoreBallot) – Ballot to remove candidates from.
- Returns:
Ballot with candidate(s) removed.
- Return type:
- votekit.cleaning.remove_cand_score_profile(removed: str | list, profile: ScoreProfile, remove_empty_ballots: bool = True, remove_zero_weight_ballots: bool = True, retain_original_candidate_list: bool = False) CleanedScoreProfile[source]
Given a score profile, remove the given candidate(s) from the ballots.
Wrapper for clean_score_profile that does some extra processing to ensure the candidate list is handled correctly.
Not as fast as removing the candidate columns directly, but tracks more information about which ballots were adjusted.
- Parameters:
removed (Union[str, list]) – Candidate or list of candidates to be removed.
profile (ScoreProfile) – Profile to remove candidates from.
remove_empty_ballots (bool, optional) – Whether or not to remove ballots that have no ranking or scores as a result of cleaning. Defaults to True.
remove_zero_weight_ballots (bool, optional) – Whether or not to remove ballots that have no weight as a result of cleaning. Defaults to True.
retain_original_candidate_list (bool, optional) – Whether or not to use the candidate list from the orginal profile in the new profile. If False, takes the original candidate list and removes the candidate(s) given in
removed, but preserves all others. Defaults to False.
- Returns:
A cleaned
ScoreProfile.- Return type:
- Raises:
ProfileError – Profile must only contain score ballots.
- votekit.cleaning.remove_repeat_cands_rank_ballot(ballot: RankBallot) RankBallot[source]
Given a ballot, if a candidate appears multiple times on a ballot, keep the first instance, and remove any further instances. Does not condense the ballot. Only works on ranking ballots, not score ballots.
- Parameters:
ballot (RankBallot) – Ballot to remove repeated candidates from.
- Returns:
Ballot with duplicate candidate(s) removed.
- Return type:
- Raises:
TypeError – Ballot must only have rankings, not scores.
TypeError – Ballot must have rankings.
- votekit.cleaning.remove_repeat_cands_rank_profile(profile: RankProfile, remove_empty_ballots: bool = True, remove_zero_weight_ballots: bool = True, retain_original_candidate_list: bool = True) CleanedRankProfile[source]
Given a profile, if a candidate appears multiple times on a ballot, keep the first instance and remove any further instances. Does not condense any empty rankings as as result. Only works on ranking ballots, not score ballots.
Wrapper for clean_rank_profile.
- Parameters:
profile (RankProfile) – Profile to remove repeated candidates from.
remove_empty_ballots (bool, optional) – Whether or not to remove ballots that have no ranking or scores as a result of cleaning. Defaults to True.
remove_zero_weight_ballots (bool, optional) – Whether or not to remove ballots that have no weight as a result of cleaning. Defaults to True.
retain_original_candidate_list (bool, optional) – Whether or not to use the candidate list from the original profile in the new profile. If False, uses only candidates who receive votes. Defaults to True.
- Returns:
A cleaned
RankProfile.- Return type:
- Raises:
ProfileError – Profile must only contain ranked ballots.
Elections
- class votekit.elections.election_state.ElectionState(round_number: int = 0, remaining: tuple[frozenset[str], ...] = (frozenset({}),), elected: tuple[frozenset[str], ...] = (frozenset({}),), eliminated: tuple[frozenset[str], ...] = (frozenset({}),), tiebreaks: dict[frozenset[str], tuple[frozenset[str], ...]] = <factory>, scores: dict[str, float] = <factory>)[source]
Class for storing information about a round of an election. Round 0 should be the initial state of the election. To save memory, the PreferenceProfile is not carried by the ElectionState class.
- round_number
Round number, defaults to 0.
- Type:
int, optional
- remaining
Remaining candidates, ordered to indicate ranking, frozensets to indicate ties. Defaults to tuple with one empty set.
- Type:
tuple[frozenset[str],…], optional
- elected
Elected candidates, ordered to indicate ranking, frozensets to indicate ties. Defaults to tuple with one empty set.
- Type:
tuple[frozenset[str],…], optional
- eliminated
Eliminated candidates, ordered to indicate ranking, frozensets to indicate ties. Defaults to tuple with one empty set.
- Type:
tuple[frozenset[str],…], optional
- tiebreaks
Stores tiebreak resolutions. Keys are frozensets of tied candidates and values are resolutions of tiebreak. Defaults to empty dictionary.
- Type:
dict[frozenset[str], tuple[frozenset[str],…]], optional
- scores
Stores score information. Keys are candidates, values are scores. Only remaining candidates should be stored.
- Type:
dict[str, float], optional
- class votekit.models.Election(profile: P, score_function: Callable[[P], dict[str, float]] | None = None, sort_high_low: bool = True)[source]
Abstract base class for election types.
- Parameters:
profile (PreferenceProfile) – The initial profile of ballots.
score_function (Callable[[PreferenceProfile], dict[str, float]], optional) – A function that converts profiles to a score dictionary mapping candidates to their current score. Used in creating ElectionState objects and sorting candidates in Round 0. If None, no score dictionary is saved and all candidates are tied in Round 0. Defaults to None.
sort_high_low (bool, optional) – How to sort candidates based on score_function. True sorts from high to low. Defaults to True.
- election_states
A list of election states, one for each round of the election. The list is 0 indexed, so the initial state is stored at index 0, round 1 at 1, etc.
- Type:
list[ElectionState]
- score_function
A function that converts profiles to a score dictionary mapping candidates to their current score. Used in creating ElectionState objects. Defaults to None.
- Type:
Callable[[PreferenceProfile], dict[str, float]], optional
- length
The number of rounds of the election.
- Type:
int
- get_elected(round_number: int = -1) tuple[frozenset[str], ...][source]
Fetch the elected candidates up to the given round number.
- Parameters:
round_number (int, optional) – The round number. Supports negative indexing. Defaults to -1, which accesses the final profile.
- Returns:
List of winning candidates in order of election. Candidates in the same set were elected simultaneously, i.e. in the final ranking they are tied.
- Return type:
tuple[frozenset[str],…]
- get_eliminated(round_number: int = -1) tuple[frozenset[str], ...][source]
Fetch the eliminated candidates up to the given round number.
- Parameters:
round_number (int, optional) – The round number. Supports negative indexing. Defaults to -1, which accesses the final profile.
- Returns:
Tuple of eliminated candidates in reverse order of elimination. Candidates in the same set were eliminated simultaneously, i.e. in the final ranking they are tied.
- Return type:
tuple[frozenset[str],…]
- get_profile(round_number: int = -1) P[source]
Fetch the PreferenceProfile of the given round number.
- Parameters:
round_number (int, optional) – The round number. Supports negative indexing. Defaults to -1, which accesses the final profile.
- Returns:
PreferenceProfile
- get_ranking(round_number: int = -1) tuple[frozenset[str], ...][source]
Fetch the ranking of candidates after a given round.
- Parameters:
round_number (int, optional) – The round number. Supports negative indexing. Defaults to -1, which accesses the final profile.
- Returns:
Ranking of candidates.
- Return type:
tuple[frozenset[str],…]
- get_remaining(round_number: int = -1) tuple[frozenset[str], ...][source]
Fetch the remaining candidates after the given round.
- Parameters:
round_number (int, optional) – The round number. Supports negative indexing. Defaults to -1, which accesses the final profile.
- Returns:
Tuple of sets of remaining candidates. Ordering of tuple denotes ranking of remaining candidates, sets denote ties.
- Return type:
tuple[frozenset[str],…]
- get_status_df(round_number: int = -1) DataFrame[source]
Yield the status (elected, eliminated, remaining) of the candidates in the given round. DataFrame is sorted by current ranking.
- Parameters:
round_number (int, optional) – The round number. Supports negative indexing. Defaults to -1, which accesses the final profile.
- Returns:
Data frame displaying candidate, status (elected, eliminated, remaining), and the round their status updated.
- Return type:
pd.DataFrame
- get_step(round_number: int = -1) tuple[P, ElectionState][source]
Fetches the profile and ElectionState of the given round number.
- Parameters:
round_number (int, optional) – The round number. Supports negative indexing. Defaults to -1, which accesses the final profile.
- Returns:
tuple[PreferenceProfile, ElectionState]
Approval-based
- class votekit.elections.election_types.approval.approval.Approval(profile: ScoreProfile, m: int = 1, tiebreak: str | None = None)[source]
Bases:
GeneralRatingApproval election. Standard approval voting lets voters choose any subset of candidates to approve. Winners are the \(m\) candidates who received the most approval votes.
- Parameters:
profile (ScoreProfile) – Profile to conduct election on.
m (int, optional) – Number of seats to elect. Defaults to 1.
tiebreak (str, optional) – Tiebreak method to use. Options are None and ‘random’. Defaults to None, in which case a tie raises a ValueError.
- class votekit.elections.election_types.approval.approval.BlocPlurality(profile: ScoreProfile, m: int = 1, k: int | None = None, tiebreak: str | None = None)[source]
Bases:
GeneralRatingLike approval voting, but there is a user-specified limit of \(k\) approvals per voter. Most commonly, this would be run with \(k=m\).
- Parameters:
profile (ScoreProfile) – Profile to conduct election on.
m (int, optional) – Number of seats to elect. Defaults to 1.
k (int, optional) – Total budget per voter. Defaults to None, which results in
mapprovals per voter.tiebreak (str, optional) – Tiebreak method to use. Options are None and ‘random’. Defaults to None, in which case a tie raises a ValueError.
Ranking-based
- class votekit.elections.election_types.ranking.abstract_ranking.RankingElection(profile: RankProfile, score_function: Callable[[RankProfile], dict[str, float]] | None = None, sort_high_low: bool = True)[source]
Bases:
Election[RankProfile]Abstract class for ranking election types. Validates that profile contains ranked ballots.
- Parameters:
profile (RankProfile) – The initial profile of ballots.
score_function (Callable[[RankProfile], dict[str, float]], optional) – A function that converts profiles to a score dictionary mapping candidates to their current score. Used in creating ElectionState objects and sorting candidates in Round 0. If None, no score dictionary is saved and all candidates are tied in Round 0. Defaults to None.
sort_high_low (bool, optional) – How to sort candidates based on score_function. True sorts from high to low. Defaults to True.
- election_states
a list of election states, one for each round of the election. The list is 0 indexed, so the initial state is stored at index 0, round 1 at 1, etc.
- Type:
list[ElectionState]
- score_function
A function that converts profiles to a score dictionary mapping candidates to their current score. Used in creating ElectionState objects. Defaults to None.
- Type:
Callable[[RankProfile], dict[str, float]], optional
- length
the number of rounds of the election.
- Type:
int
- class votekit.elections.election_types.ranking.alaska.Alaska(profile: ~votekit.pref_profile.pref_profile.RankProfile, m_1: int = 2, m_2: int = 1, transfer: ~typing.Callable[[str, float, tuple[~votekit.ballot.RankBallot] | list[~votekit.ballot.RankBallot], int], tuple[~votekit.ballot.RankBallot, ...]] = <function fractional_transfer>, quota: str = 'droop', simultaneous: bool = True, tiebreak: str | None = None, fpv_tie_convention: ~typing.Literal['high', 'low', 'average'] = 'average')[source]
Bases:
RankingElectionAlaska election. Election method that first runs a Plurality election to choose a user-specified number of final-round candidates, then runs STV to choose \(m\) winners.
- Parameters:
profile (RankProfile) – Profile to conduct election on.
m_1 (int, optional) – Number of final round candidates, i.e. number of winners of Plurality round. Defaults to 2.
m_2 (int, optional) – Number of seats to elect in STV round, i.e. number of overall winners. Defaults to 1.
(Callable[[str (transfer) – tuple[Ballot,…]], optional): Transfer method. Defaults to fractional transfer. Function signature is elected candidate, their number of first-place votes, the list of ballots with them ranked first, and the threshold value. Returns the list of ballots after transfer.
float] – tuple[Ballot,…]], optional): Transfer method. Defaults to fractional transfer. Function signature is elected candidate, their number of first-place votes, the list of ballots with them ranked first, and the threshold value. Returns the list of ballots after transfer.
Union[tuple[Ballot] – tuple[Ballot,…]], optional): Transfer method. Defaults to fractional transfer. Function signature is elected candidate, their number of first-place votes, the list of ballots with them ranked first, and the threshold value. Returns the list of ballots after transfer.
list[Ballot]] – tuple[Ballot,…]], optional): Transfer method. Defaults to fractional transfer. Function signature is elected candidate, their number of first-place votes, the list of ballots with them ranked first, and the threshold value. Returns the list of ballots after transfer.
int] – tuple[Ballot,…]], optional): Transfer method. Defaults to fractional transfer. Function signature is elected candidate, their number of first-place votes, the list of ballots with them ranked first, and the threshold value. Returns the list of ballots after transfer.
- :paramtuple[Ballot,…]], optional):
Transfer method. Defaults to fractional transfer. Function signature is elected candidate, their number of first-place votes, the list of ballots with them ranked first, and the threshold value. Returns the list of ballots after transfer.
- Parameters:
quota (str, optional) – Formula to calculate quota. Accepts “droop” or “hare”. Defaults to “droop”.
simultaneous (bool, optional) – True if all candidates who cross threshold in a round are elected simultaneously, False if only the candidate with highest first-place votes who crosses the threshold is elected in a round. Defaults to True.
tiebreak (str, optional) – Tiebreak method to use. Options are None, ‘random’, and ‘borda’. Defaults to None, in which case a tie raises a ValueError.
fpv_tie_convention (Literal["high", "average", "low"], optional) – How to award points for tied first place votes. Defaults to “average”, where if n candidates are tied for first, each receives 1/n points. “high” would award them each one point, and “low” 0. Only used by
score_functionparameter.
- get_profile(round_number: int = -1) RankProfile[source]
Fetch the RankProfile of the given round number.
- Parameters:
round_number (int, optional) – The round number. Supports negative indexing. Defaults to -1, which accesses the final profile.
- Returns:
RankProfile
- class votekit.elections.election_types.ranking.borda.Borda(profile: RankProfile, m: int = 1, score_vector: Sequence[float] | None = None, tiebreak: str | None = None, scoring_tie_convention: Literal['high', 'average', 'low'] = 'low')[source]
Bases:
RankingElectionBorda election. Positional voting system that assigns a decreasing number of points to candidates based on their ordering. The conventional score vector is \((n, n-1, \dots, 1)\) where \(n\) is the
max_ranking_lengthof the profile. Candidates with the highest scores are elected. This class uses theutils.score_dict_from_score_vector()to handle ballots with ties.- Parameters:
profile (RankProfile) – Profile to conduct election on.
m (int, optional) – Number of seats to elect. Defaults to 1.
score_vector (Sequence[float], optional) – Score vector. Should be non-increasing and non-negative. Vector should be as long as the number of candidates. If it is shorter, we add 0s. Defaults to None, which is the conventional Borda vector.
tiebreak (str, optional) – Tiebreak method to use. Options are None, ‘random’, and ‘first_place’. Defaults to None, in which case a tie raises a ValueError.
scoring_tie_convention (Literal["high", "average", "low"], optional) – How to award points for tied rankings. Defaults to “low”, where any candidates tied receive the lowest possible points for their position, eg three people tied for 3rd would each receive the points for 5th. “high” awards the highest possible points, so in the previous example, they would each receive the points for 3rd. “average” averages the points, so they would each receive the points for 4th place.
- class votekit.elections.election_types.ranking.boosted_random_dictator.BoostedRandomDictator(profile: RankProfile, m: int, fpv_tie_convention: Literal['high', 'average', 'low'] = 'average')[source]
Bases:
RankingElectionModified random dictator where with probability (1 - 1/(n_candidates - 1)) choose a winner randomly from the distribution of first place votes. With probability 1/(n_candidates - 1), choose a winner via a proportional to squares rule.
For multi-winner elections repeat this process for every winner, removing that candidate from every voter’s ballot once they have been elected.
- Parameters:
profile (RankProfile) – RankProfile to run election on.
m (int) – Number of seats to elect.
fpv_tie_convention (Literal["high", "average", "low"], optional) – How to award points for tied first place votes. Defaults to “average”, where if n candidates are tied for first, each receives 1/n points. “high” would award them each one point, and “low” 0.
- class votekit.elections.election_types.ranking.condo_borda.CondoBorda(profile: RankProfile, m: int = 1)[source]
Bases:
RankingElectionJust like DominatingSets (Smith method), but user gets to choose the number of winners, \(m\). Ties are broken with Borda scores.
- Parameters:
profile (RankProfile) – Profile to conduct election on.
m (int, optional) – Number of seats to elect. Defaults to 1.
- class votekit.elections.election_types.ranking.dominating_sets.DominatingSets(profile: RankProfile)[source]
Bases:
RankingElectionA “dominating set” is any set S of candidates such that everyone in S beats everyone outside of S head-to-head. The top tier (which is well defined) is often called the “Smith set,” and if it is just one person, they are called the “Condorcet candidate.” The Smith method of election declares the Smith set to be the winners, which means that users do not get to specify the number of winners.
- Parameters:
profile (RankProfile) – Profile to conduct election on.
- class votekit.elections.election_types.ranking.plurality_veto.PluralityVeto(profile: RankProfile, m: int, tiebreak: str | None = None, fpv_tie_convention: Literal['high', 'low', 'average'] = 'average')[source]
Bases:
RankingElectionScores each candidate by their plurality (number of first) place votes, then in a randomized order it lets each voter decrement the score of their least favorite candidate. The candidate with the largest score at the end is then chosen as the winner.
- Parameters:
profile (RankProfile) – RankProfile to run election on. Note that ballots must have integer weights to be considered valid for this mechanism.
m (int) – Number of seats to elect.
tiebreak (str, optional) – Tiebreak method to use. Options are None, ‘random’, and ‘borda’. Defaults to None, in which case a tie raises a ValueError.
fpv_tie_convention (Literal["high", "average", "low"], optional) – How to award points for tied first place votes. Defaults to “average”, where if n candidates are tied for first, each receives 1/n points. “high” would award them each one point, and “low” 0. Only used by
score_functionparameter.
- m
The number of seats to be filled in the election.
- Type:
int
- tiebreak
The tiebreak method selected for the election. Could be None, ‘random’, or ‘borda’.
- Type:
Optional[str]
- ballot_list
A list of Ballot instances representing the decondensed ballots where each ballot has a weight of 1.
- Type:
List[Ballot]
- random_order
A list of indices representing the randomized order in which voters’ preferences are processed.
- Type:
List[int]
- preference_index
A list of integers where each entry corresponds to the index of the least preferred candidate for each ballot.
- Type:
List[int]
- eliminated_dict
A dictionary mapping each candidate to a boolean value indicating whether the candidate has been eliminated.
- Type:
Dict[str, bool]
- Raises:
ValueError – If
mis not positive or if it exceeds the number of candidates.
Initializes the Plurality Veto election class.
This constructor sets up the initial state of the election, including validating the profile, decondensing ballots (necessary for the running the steps of the election), and preparing other necessary data structures.
- Parameters:
profile (RankProfile) – The preference profile to be used in the election.
m (int) – The number of seats to be filled in the election.
tiebreak (Optional[str]) – The method used to resolve ties. Defaults to None.
- Raises:
ValueError – If
mis less than or equal to 0, or ifmexceeds the number of candidates in the profile.AttributeError – If there are any ballots with ties and no tiebreak method is specified.
TypeError – If the profile contains invalid ballots.
- class votekit.elections.election_types.ranking.plurality.Plurality(profile: RankProfile, m: int = 1, tiebreak: str | None = None, fpv_tie_convention: Literal['high', 'low', 'average'] = 'average')[source]
Bases:
RankingElectionPlurality election. Winners are the m candidates with the most first-place votes.
- Parameters:
profile (RankProfile) – Profile to conduct election on.
m (int, optional) – Number of seats to elect. Defaults to 1.
tiebreak (str, optional) – Tiebreak method to use. Options are None, ‘random’, and ‘borda’. Defaults to None, in which case a tie raises a ValueError.
fpv_tie_convention (Literal["high", "average", "low"], optional) – How to award points for tied first place votes. Defaults to “average”, where if n candidates are tied for first, each receives 1/n points. “high” would award them each one point, and “low” 0. Only used by
score_functionparameter.
- class votekit.elections.election_types.ranking.plurality.SNTV(profile: RankProfile, m: int = 1, tiebreak: str | None = None)[source]
Bases:
PluralityWrapper for Plurality election. Winners are the m candidates with the most first-place votes.
- Parameters:
profile (RankProfile) – Profile to conduct election on.
m (int, optional) – Number of seats to elect. Defaults to 1.
tiebreak (str, optional) – Tiebreak method to use. Options are None, ‘random’, and ‘borda’. Defaults to None, in which case a tie raises a ValueError.
- class votekit.elections.election_types.ranking.random_dictator.RandomDictator(profile: RankProfile, m: int, fpv_tie_convention: Literal['high', 'average', 'low'] = 'average')[source]
Bases:
RankingElectionChoose a winner randomly from the distribution of first place votes. For multi-winner elections repeat this process for every winner, removing that candidate from every voter’s ballot once they have been elected.
- Parameters:
profile (RankProfile) – RankProfile to run election on.
m (int) – Number of seats to elect.
fpv_tie_convention (Literal["high", "average", "low"], optional) – How to award points for tied first place votes. Defaults to “average”, where if n candidates are tied for first, each receives 1/n points. “high” would award them each one point, and “low” 0.
- class votekit.elections.election_types.ranking.ranked_pairs.RankedPairs(profile: RankProfile, tiebreak: str = 'lexicographic', m: int = 1)[source]
Bases:
RankingElectionSee Ranked Pairs for more details. Any ambiguity is resolved lexicographically, so that the candidate with the first name alphabetically is preferred in the case of a tie.
The idea of the Ranked Pairs election is to take the head-to-head results of the candidates and then sort them by the margin of victory. We then lock this order in and construct a directed graph from the head-to-head results by traversing the locked order and skipping any edges that would create a cycle in the directed graph. The final ranking of the election is then determined by the dominating tiers of the directed graph with ties broken lexicographically.
- Parameters:
profile (RankProfile) – Profile to conduct election on.
m (int, optional) – Number of seats to elect. Defaults to 1.
- class votekit.elections.election_types.ranking.stv.FastSTV(profile: RankProfile, m: int = 1, transfer: str = 'fractional', quota: str = 'droop', simultaneous: bool = True, tiebreak: str | None = None)[source]
Bases:
objectSTV elections. All ballots must have no ties.
- Parameters:
profile (RankProfile) – RankProfile to run election on.
m (int) – Number of seats to be elected. Defaults to 1.
transfer – (str): Transfer method to be used. Accepts ‘fractional’ and ‘random’. Defaults to ‘fractional’.
quota (str) – Formula to calculate quota. Accepts “droop” or “hare”. Defaults to “droop”.
simultaneous (bool) – True if all candidates who cross threshold in a round are elected simultaneously, False if only the candidate with highest first-place votes who crosses the threshold is elected in a round. Defaults to True.
tiebreak (Optional[str]) – Method to be used if a tiebreak is needed. Accepts ‘borda’ and ‘random’. Defaults to None, in which case a ValueError is raised if a tiebreak is needed.
- get_elected(round_number: int = -1) tuple[frozenset[str], ...][source]
Fetch the elected candidates up to the given round number.
- Parameters:
round_number (int) – The round number. Supports negative indexing. Defaults to -1, which accesses the final profile.
- Returns:
Tuple of winning candidates in order of election. Candidates in the same set were elected simultaneously, i.e. in the final ranking they are tied.
- Return type:
tuple[frozenset[str], …]
- get_eliminated(round_number: int = -1) tuple[frozenset[str], ...][source]
Fetch the eliminated candidates up to the given round number.
- Parameters:
round_number (int) – The round number. Supports negative indexing. Defaults to -1, which accesses the final profile.
- Returns:
Tuple of eliminated candidates in reverse order of elimination. Candidates in the same set were eliminated simultaneously, i.e. in the final ranking they are tied.
- Return type:
tuple[frozenset[str], …]
- get_profile(round_number: int = -1) RankProfile[source]
Fetch the RankProfile of the given round number.
- get_ranking(round_number: int = -1) tuple[frozenset[str], ...][source]
Fetch the ranking of candidates after a given round.
- Parameters:
round_number (int) – The round number. Supports negative indexing. Defaults to -1, which accesses the final profile.
- Returns:
Ranking of candidates.
- Return type:
tuple[frozenset[str],…]
- get_remaining(round_number: int = -1) tuple[frozenset, ...][source]
Fetch the remaining candidates after the given round.
- Parameters:
round_number (int) – The round number. Supports negative indexing. Defaults to -1, which accesses the final profile.
- Returns:
Tuple of sets of remaining candidates. Ordering of tuple denotes ranking of remaining candidates, sets denote ties.
- Return type:
tuple[frozenset[str], …]
- get_status_df(round_number: int = -1) DataFrame[source]
Yield the status (elected, eliminated, remaining) of the candidates in the given round. DataFrame is sorted by current ranking.
- Parameters:
round_number (int) – The round number. Supports negative indexing. Defaults to -1, which accesses the final profile.
- Returns:
Data frame displaying candidate, status (elected, eliminated, remaining), and the round their status updated.
- Return type:
pd.DataFrame
- get_step(round_number: int = -1) tuple[RankProfile, ElectionState][source]
Fetches the profile and ElectionState of the given round number.
- Parameters:
round_number (int) – The round number. Supports negative indexing. Defaults to -1, which accesses the final profile.
- Returns:
tuple[RankProfile, ElectionState]
- class votekit.elections.election_types.ranking.stv.IRV(profile: RankProfile, quota: str = 'droop', tiebreak: str | None = None)[source]
Bases:
STVIRV (Instant-runoff voting) elections. Elect 1 seat. All ballots must have no ties. Equivalent to STV for m = 1.
- Parameters:
profile (RankProfile) – RankProfile to run election on.
quota (str, optional) – Formula to calculate quota. Accepts “droop” or “hare”. Defaults to “droop”.
tiebreak (str, optional) – Method to be used if a tiebreak is needed. Accepts ‘borda’ and ‘random’. Defaults to None, in which case a ValueError is raised if a tiebreak is needed.
- class votekit.elections.election_types.ranking.stv.STV(profile: ~votekit.pref_profile.pref_profile.RankProfile, m: int = 1, transfer: ~typing.Callable[[str, float, tuple[~votekit.ballot.RankBallot] | list[~votekit.ballot.RankBallot], int], tuple[~votekit.ballot.RankBallot, ...]] = <function fractional_transfer>, quota: str = 'droop', simultaneous: bool = True, tiebreak: str | None = None)[source]
Bases:
RankingElectionSTV elections. All ballots must have no ties.
- Parameters:
profile (RankProfile) – RankProfile to run election on.
m (int) – Number of seats to be elected. Defaults to 1.
(Callable[[str (transfer) – tuple[Ballot,…]], optional): Transfer method. Defaults to fractional transfer. Function signature is elected candidate, their number of first-place votes, the list of ballots with them ranked first, and the threshold value. Returns the list of ballots after transfer.
float – tuple[Ballot,…]], optional): Transfer method. Defaults to fractional transfer. Function signature is elected candidate, their number of first-place votes, the list of ballots with them ranked first, and the threshold value. Returns the list of ballots after transfer.
Union[tuple[Ballot] – tuple[Ballot,…]], optional): Transfer method. Defaults to fractional transfer. Function signature is elected candidate, their number of first-place votes, the list of ballots with them ranked first, and the threshold value. Returns the list of ballots after transfer.
list[Ballot]] – tuple[Ballot,…]], optional): Transfer method. Defaults to fractional transfer. Function signature is elected candidate, their number of first-place votes, the list of ballots with them ranked first, and the threshold value. Returns the list of ballots after transfer.
int] – tuple[Ballot,…]], optional): Transfer method. Defaults to fractional transfer. Function signature is elected candidate, their number of first-place votes, the list of ballots with them ranked first, and the threshold value. Returns the list of ballots after transfer.
- :paramtuple[Ballot,…]], optional): Transfer method. Defaults to fractional transfer.
Function signature is elected candidate, their number of first-place votes, the list of ballots with them ranked first, and the threshold value. Returns the list of ballots after transfer.
- Parameters:
quota (str) – Formula to calculate quota. Accepts “droop” or “hare”. Defaults to “droop”.
simultaneous (bool) – True if all candidates who cross threshold in a round are elected simultaneously, False if only the candidate with highest first-place votes who crosses the threshold is elected in a round. Defaults to True.
tiebreak (str) – Method to be used if a tiebreak is needed. Accepts ‘borda’ and ‘random’. Defaults to None, in which case a ValueError is raised if a tiebreak is needed.
- class votekit.elections.election_types.ranking.stv.SequentialRCV(profile: RankProfile, m: int = 1, quota: str = 'droop', simultaneous: bool = True, tiebreak: str | None = None)[source]
Bases:
STVAn STV election in which votes are not transferred after a candidate has reached threshold, or been elected. This system is actually used in parts of Utah.
- Parameters:
profile (RankProfile) – RankProfile to run election on.
m (int, optional) – Number of seats to be elected. Defaults to 1.
quota (str, optional) – Formula to calculate quota. Accepts “droop” or “hare”. Defaults to “droop”.
simultaneous (bool, optional) – True if all candidates who cross threshold in a round are elected simultaneously, False if only the candidate with highest first-place votes who crosses the threshold is elected in a round. Defaults to True.
tiebreak (str, optional) – Method to be used if a tiebreak is needed. Accepts ‘borda’ and ‘random’. Defaults to None, in which case a ValueError is raised if a tiebreak is needed.
- class votekit.elections.election_types.ranking.top_two.TopTwo(profile: RankProfile, tiebreak: str | None = None, fpv_tie_convention: Literal['high', 'low', 'average'] = 'average')[source]
Bases:
RankingElectionEliminates all but the top two plurality vote-getters, and then conducts a runoff between them, reallocating other ballots.
- Parameters:
profile (RankProfile) – Profile to conduct election on.
tiebreak (str, optional) – Tiebreak method to use. Options are None, ‘random’, and ‘borda’. Defaults to None, in which case a tie raises a ValueError.
fpv_tie_convention (Literal["high", "average", "low"], optional) – How to award points for tied first place votes. Defaults to “average”, where if n candidates are tied for first, each receives 1/n points. “high” would award them each one point, and “low” 0. Only used by
score_functionparameter.
Score-based
- class votekit.elections.election_types.scores.rating.Cumulative(profile: ScoreProfile, m: int = 1, tiebreak: str | None = None)[source]
Bases:
LimitedVoters can score each candidate, but have a total budget of \(m\) points, where \(m\) is the number of seats to be filled. Winners are those with highest total score.
- Parameters:
profile (PreferenceProfile) – Profile to conduct election on.
m (int, optional) – Number of seats to elect. Defaults to 1.
tiebreak (str, optional) – Tiebreak method to use. Options are None, and ‘random’. Defaults to None, in which case a tie raises a ValueError.
- class votekit.elections.election_types.scores.rating.GeneralRating(profile: ScoreProfile, m: int = 1, L: float = 1, k: float | None = None, tiebreak: str | None = None)[source]
Bases:
Election[ScoreProfile]General rating election. To fill \(m\) seats, voters score each candidate from \(0-L\), where \(L\) is some user-specified limit. There is also a total budget of \(k\) points per voter. The \(m\) winners are those with the highest total score.
- Parameters:
profile (ScoreProfile) – Profile to conduct election on.
m (int, optional) – Number of seats to elect. Defaults to 1.
L (float, optional) – Rating per candidate limit. Defaults to 1.
k (float, optional) – Budget per ballot limit. Defaults to None, in which case voters can score each candidate independently.
tiebreak (str, optional) – Tiebreak method to use. Options are None and ‘random’. Defaults to None, in which case a tie raises a ValueError.
- class votekit.elections.election_types.scores.rating.Limited(profile: ScoreProfile, m: int = 1, k: float = 1, tiebreak: str | None = None)[source]
Bases:
GeneralRatingVoters can score each candidate, but have a total budget of \(k\le m\) points. Winners are those with highest total score.
- Parameters:
profile (ScoreProfile) – Profile to conduct election on.
m (int, optional) – Number of seats to elect. Defaults to 1.
k (float, optional) – Total budget per voter. Defaults to 1.
tiebreak (str, optional) – Tiebreak method to use. Options are None, and ‘random’. Defaults to None, in which case a tie raises a ValueError.
- class votekit.elections.election_types.scores.rating.Rating(profile: ScoreProfile, m: int = 1, L: float = 1, tiebreak: str | None = None)[source]
Bases:
GeneralRatingRating election. To fill \(m\) seats, voters score each candidate independently from \(0-L\), where \(L\) is some user-specified limit. The \(m\) winners are those with the highest total score.
- Parameters:
profile (ScoreProfile) – Profile to conduct election on.
m (int, optional) – Number of seats to elect. Defaults to 1.
L (float, optional) – Rating per candidate limit. Defaults to 1.
tiebreak (str, optional) – Tiebreak method to use. Options are None and ‘random’. Defaults to None, in which case a tie raises a ValueError.
Graphs and Viz.
- class votekit.graphs.ballot_graph.BallotGraph(source: RankProfile | int | list, allow_partial: bool | None = True, fix_short: bool | None = True)[source]
Class to build ballot graphs.
- Parameters:
source (Union[RankProfile, int, list]) – data to create graph from, either
RankProfileobject, number of candidates, or list of candidates.allow_partial (bool, optional) – If True, builds graph using all possible ballots, If False, only uses total linear ordered ballots. Defaults to True.
fix_short (bool, optional) – If True, auto completes ballots of length \(n-1\) to \(n\). Ballots of length less than \(n-1\) are preserved. Defaults to True.
- profile
Profile used to create graph, None if not provided.
- Type:
- candidates
Tuple of candidates, None if not provided.
- Type:
tuple[str]
- num_cands
Number of candidates.
- Type:
int
- num_voters
Sum of weights of profile if provided.
- Type:
float
- allow_partial
If True, builds graph using all possible ballots, If False, only uses total linear ordered ballots.
- Type:
bool, optional
- graph
underlying
networkxgraph.- Type:
networkx.Graph
- build_graph(n: int) Graph[source]
Builds graph of all possible ballots given a number of candiates.
- Parameters:
n (int) – Number of candidates in an election.
- Returns:
A
networkxgraph.- Return type:
networkx.Graph
- draw(to_display: ~typing.Callable = <function all_nodes>, neighborhoods: list[tuple] | None = [], show_cast: bool | None = False, labels: bool | None = False, scale: float = 1.0)[source]
Visualize the graph.
- Parameters:
to_display (Callable, optional) – A boolean function that takes the graph and a node as input, returns True if you want that node displayed. Defaults to showing all nodes.
neighborhoods (list[tuple], optional) – A list of neighborhoods to display, given as tuple (node, radius). eg. (n,1) gives all nodes within one step of n. Defaults to empty list which shows all nodes.
show_cast (bool, optional) – If True, show only nodes with “cast” attribute = True. If False, show all nodes. Defaults to False.
labels (bool, optional) – If True, labels nodes with candidate names and vote totals. Defaults to False.
scale (float, optional) – How much to scale the base graph by. Defaults to 1.0.
- fix_short_ballot(ballot: list, candidates: list) list[source]
Adds missing candidates to a short ballot.
- Parameters:
ballot (list) – A list of candidates on the ballot.
candidates (list) – A list of all candidates.
- Returns:
A new list with the missing candidates added to the end of the ballot.
- Return type:
list
- from_profile(profile: RankProfile, fix_short: bool | None = True) Graph[source]
Updates existing graph based on cast ballots from a RankProfile, or creates graph based on RankProfile.
- Parameters:
profile (RankProfile) –
RankProfileassigned to graph.fix_short (bool, optional) – If True, complete short ballots. Defaults to True.
- Returns:
Graph based on
RankProfile, ‘cast’ node attribute indicates ballots cast inRankProfile.- Return type:
networkx.Graph
- label_cands(candidates, to_display: ~typing.Callable = <function all_nodes>)[source]
Assigns candidate labels to ballot graph for plotting.
- Parameters:
candidates (list) – A list of candidates.
to_display (Callable, optional) – A Boolean callable that takes in a graph and node, returns True if node should be displayed. Defaults to showing all nodes.
- label_weights(to_display: ~typing.Callable = <function all_nodes>)[source]
Assigns weight labels to ballot graph for plotting. Only shows weight if non-zero.
- Parameters:
to_display (Callable, optional) – A Boolean callable that takes in a graph and node, returns True if node should be displayed. Defaults to showing all nodes.
- class votekit.graphs.pairwise_comparison_graph.PairwiseComparisonGraph(profile: RankProfile, *, sort_candidate_pairs: bool = True)[source]
Bases:
DiGraphClass to construct the pairwise comparison graph where nodes are candidates and edges are pairwise preferences.
- Parameters:
profile (RankProfile) –
RankProfileto construct graph from.sort_candidate_pairs (bool) – If True, candidate pairs in the pairwise comparison dictionary will be sorted lexicographically. Defaults to True.
- profile
RankProfileto construct graph from.- Type:
- candidates
List of candidates.
- Type:
list
- pairwise_dict
Dictionary constructed from
pairwise_dict. The pairwise dictionary is a dictionary whose keys are candidate pairs (A,B) and whose values are lists [a,b] where ‘a’ denotes the number of times A beats B head to head, and ‘b’ is the number of times B beats A head to head.- Type:
dict[tuple[str, str], tuple[float, float]]
- pairwise_graph
Underlying graph.
- Type:
networkx.DiGraph
- draw(ax: matplotlib.axes.Axes | None = None, candidate_list: list[str] | None = None) matplotlib.axes.Axes[source]
Draws pairwise comparison graph.
- Parameters:
ax (Axes, optional) – Matplotlib axes to plot on. Defaults to None, in which case an axes is generated.
candidate_list (list[str], optional) – List of candidates to plot. Defaults to None, in which case all candidates are used.
- Returns:
Matplotlib axes of pairwise comparison graph.
- Return type:
Axes
- get_condorcet_cycles() list[set[str]][source]
Returns a list of condorcet cycles in the graph, which we define as any cycle of length greater than 2.
- Returns:
List of condorcet cycles sorted by length.
- Return type:
list[set[str]]
- get_condorcet_winner() str[source]
Returns the condorcet winner. Raises a ValueError if no condorcet winner.
- Returns:
The condorcet winner.
- Return type:
str
- Raises:
ValueError – There is no condorcet winner.
- get_dominating_tiers() list[set[str]][source]
Compute the dominating tiers of the pairwise comparison graph. Candidates in a tier beat all other candidates in lower tiers in head to head comparisons.
- Returns:
Dominating tiers, where the first entry of the list is the highest tier.
- Return type:
list[set[str]]
- has_condorcet_cycles() bool[source]
Checks if graph has any condorcet cycles, which we define as any cycle of length greater than 2 in the graph.
- Returns:
True if condorcet cycles exists, False otherwise.
- Return type:
bool
- has_condorcet_winner() bool[source]
Checks if graph has a condorcet winner.
- Returns:
True if condorcet winner exists, False otherwise.
- Return type:
bool
- ties_or_beats(candidate: str) set[str][source]
Returns the predecessors of x, which are all of the nodes m that have a directed path from m to x. In the pairwise comparison graph, these are the candidates that tie or beat the given candidate.
- Parameters:
candidate (str) – Candidate.
- Returns:
Candidates that beat or tie given candidate head to head.
- Return type:
set[str]
- votekit.graphs.pairwise_comparison_graph.get_dominating_tiers_digraph(graph: DiGraph) list[set[str]][source]
Compute the dominating tiers of the pairwise comparison graph. Candidates in a tier beat all other candidates in lower tiers in head to head comparisons. In other words, every candidate in a given tier must have a path to every candidate in the lower tier in the head-to-head graph.
- Parameters:
graph (nx.DiGraph) – A directed graph representing pairwise comparisons.
- Returns:
Dominating tiers, where the first entry of the list is the highest tier.
- Return type:
list[set[str]]
- votekit.graphs.pairwise_comparison_graph.pairwise_dict(profile: RankProfile, *, sort_candidate_pairs: bool = True) dict[tuple[str, str], tuple[float, float]][source]
Computes a dictionary whose keys are candidate pairs (A,B) and whose values are lists [a,b] where ‘a’ denotes the number of times A beats B head to head, and ‘b’ is the reverse.
- Parameters:
profile (RankProfile) – Profile to compute dict on.
sort_candidate_pairs (bool) – If True, candidate pairs in the pairwise comparison dictionary will be sorted lexicographically. Defaults to True.
- Returns:
Pairwise comparison dictionary.
- Return type:
dict[tuple[str, str], tuple[float, float]]
- votekit.graphs.pairwise_comparison_graph.restrict_pairwise_dict_to_subset(cand_subset: list[str] | tuple[str] | set[str], pairwise_dict: dict[tuple[str, str], tuple[float, float]]) dict[tuple[str, str], tuple[float, float]][source]
Restricts the full pairwise dictionary to a subset of candidates. The pairwise dictionary is a dictionary whose keys are candidate pairs (A,B) and whose values are lists [a,b] where ‘a’ denotes the number of times A beats B head to head, and ‘b’ is the reverse.
- Parameters:
cands (list[str] | tuple[str] | set[str]) – Candidate subset to restrict to.
pairwise_dict (dict[tuple[str, str], tuple[float, float]) – Full pairwise comparison dictionary.
- Returns:
- Pairwise dict restricted to the provided
candidates.
- Return type:
dict[tuple[str, str], tuple[float, float]]
- Raises:
ValueError – cand_subset must be at least length 2.
ValueError – cand_subset must be a subset of the candidates in the dictionary.
- votekit.plots.mds.compute_MDS(data: Dict[str, list[PreferenceProfile]], distance: Callable[[...], int], random_seed: int = 47, *args, **kwargs)[source]
Computes the coordinates of an MDS plot. This is time intensive, so it is decoupled from
plot_mdsto allow users to flexibly use the coordinates.- Parameters:
data (Dict[str, list[PreferenceProfile]]) – Dictionary with key being a string label and value being list of PreferenceProfiles. eg.
{'PL with alpha = 4': list[PreferenceProfile]}distance (Callable[..., int]) – Distance function. See distance.py.
random_seed (int, optional) – An integer seed to allow for reproducible MDS plots. Defaults to 47.
*args – args to be passed to
distance_matrix.**kwargs – kwargs to be passed to
distance_matrix.
- Returns:
- a dictionary whose keys match
dataand whose values are tuples of numpy arrays (x_list, y_list) of coordinates for the MDS plot.
- a dictionary whose keys match
- Return type:
coord_dict (dict)
- votekit.plots.mds.distance_matrix(pp_arr: list[PreferenceProfile], distance: Callable[[...], int], *args, **kwargs)[source]
Creates pairwise distance matrix between
PreferenceProfileobjects. The \((i,j)\) entry is the pairwise distance between \(i`th and the :math:`j`th ``PreferenceProfile`\).- Parameters:
pp_arr (list[PreferenceProfiles]) – List of
PreferenceProfiles.distance (Callable[..., int]) – Callable distance function type. See distances.py in the metrics module.
*args – args to be passed to the distance function.
**kwargs – kwargs to be passed to the distance function.
- Returns:
Distance matrix for profiles.
- Return type:
numpy.ndarray
- votekit.plots.mds.plot_MDS(coord_dict: dict, ax: matplotlib.axes.Axes | None = None, plot_kwarg_dict: dict | None = None, legend: bool = True, title: bool = True)[source]
Creates an MDS plot from the output of compute_MDS with legend labels matching the keys of coord_dict.
- Parameters:
coord_dict (dict) – Dictionary with key being a string label and value being tuple (x_list, y_list), coordinates for the MDS plot. Should be piped in from
compute_MDS.ax (axes, optional) – A matplolib axes object to plot the figure on. Defaults to None, in which case the function creates and returns a new axes.
plot_kwarg_dict (dict, optional) – Dictionary with keys matching
coord_dictand values are kwarg dictionaries that will be passed to matplotlibscatter.legend (bool, optional) – boolean for plotting the legend. Defaults to True.
title (bool, optional) – boolean for plotting the title. Defaults to True.
- Returns:
a
matplotlibAxes.- Return type:
Axes
- votekit.plots.bar_plot.add_null_keys(data: dict[str, dict[str, float]]) dict[str, dict[str, float]][source]
Prepares dictionary of dictionaries to be passed to
multi_bar_plot(). If a key is missing from a dictionary, this function adds the key with value 0.- Parameters:
data (dict[str, dict[str, float]]) – Categorical data to be cleaned. The value of each dict should be the frequency of the key which is the category name.
- Returns:
Cleaned data.
- Return type:
dict[str, dict[str, float]]
- votekit.plots.bar_plot.bar_plot(data: dict[str, float], *, data_set_label: str = 'Data set', normalize: bool = False, data_set_color: str = '#0099cd', bar_width: float | None = None, category_ordering: list[str] | None = None, x_axis_name: str | None = None, y_axis_name: str | None = None, title: str | None = None, show_data_set_legend: bool = False, categories_legend: dict[str, str] | None = None, threshold_values: list[float] | float | None = None, threshold_kwds: list[dict] | dict | None = None, legend_font_size: float | None = None, ax: matplotlib.axes.Axes | None = None) matplotlib.axes.Axes[source]
Plots bar plot of a single categorical data set. Wrapper for
multi_bar_plot.- Parameters:
data (dict[str, float]) – Categorical data set to be plotted. Keys are categories, and values are the height of the bars.
data_set_label (str, optional) – Label for data set. Defaults to “Data set”.
normalize (bool, optional) – Whether or not to normalize data. Defaults to False.
data_set_color (str, optional) – Color of data set. Defaults to the first color from
COLOR_LISTfromutilsmodule.bar_width (float, optional) – Width of bars. Defaults to None which computes the bar width as 0.7 divided by the number of data sets. Must be in the interval \((0,1]\).
category_ordering (list[str], optional) – Ordering of x-labels. Defaults to order retrieved from data dictionary.
x_axis_name (str, optional) – Name of x-axis. Defaults to None, which does not plot a name.
y_axis_name (str, optional) – Name of y-axis. Defaults to None, which does not plot a name.
title (str, optional) – Title for the figure. Defaults to None, which does not plot a title.
show_data_set_legend (bool, optional) – Whether or not to plot the data set legend. Defaults to False. Is automatically shown if any threshold lines have the keyword “label” passed through
threshold_kwds.categories_legend (dict[str, str], optional) – Dictionary mapping data categories to description. Defaults to None. If provided, generates a second legend for data categories.
threshold_values (Union[list[float], float], optional) – List of values to plot horizontal lines at. Can be provided as a list or a single float.
threshold_kwds (Union[list[dict], dict], optional) – List of plotting keywords for the horizontal lines. Can be a list or single dictionary. These will be passed to plt.axhline(). Common keywords include “linestyle”, “linewidth”, and “label”. If “label” is passed, automatically plots the data set legend with the labels.
legend_font_size (float, optional) – The font size to use for the legend. Defaults to 10.0 + the number of categories.
legend_loc (str, optional) – The location parameter to pass to
Axes.legend(loc=). Defaults to “center left”.legend_bbox_to_anchor (Tuple[float, float], otptional) – The bounding box to anchor the legend to. Defaults to (1, 0.5).
ax (Axes, optional) – A matplotlib axes object to plot the figure on. Defaults to None, in which case the function creates and returns a new axes. The figure height is 6 inches and the figure width is 3 inches times the number of categories.
- Returns:
A
matplotlibaxes with a bar plot of the given data.- Return type:
Axes
- votekit.plots.bar_plot.multi_bar_plot(data: dict[str, dict[str, float]], *, normalize: bool = False, data_set_colors: dict[str, str] | None = None, bar_width: float | None = None, category_ordering: list[str] | None = None, x_axis_name: str | None = None, y_axis_name: str | None = None, title: str | None = None, show_data_set_legend: bool = False, categories_legend: dict[str, str] | None = None, threshold_values: list[float] | float | None = None, threshold_kwds: list[dict] | dict | None = None, legend_font_size: float | None = None, ax: matplotlib.axes.Axes | None = None) matplotlib.axes.Axes[source]
Plots bar plot of categorical data.
- Parameters:
data (dict[str, dict[str, float]]) – Categorical data to be plotted. Top level keys are data set labels. Inner keys are categories, and inner values are the height of the bars.
normalize (bool, optional) – Whether or not to normalize data. Defaults to False.
data_set_colors (dict[str, str], optional) – Dictionary mapping data set labels to colors. Defaults to None, in which case we use a subset of
COLOR_LISTfromutilsmodule. Dictionary keys can be a subset of the data sets.bar_width (float, optional) – Width of bars. Defaults to None which computes the bar width as 0.7 divided by the number of data sets. Must be in the interval \((0,1]\).
category_ordering (list[str], optional) – Ordering of x-labels. Defaults to order retrieved from data dictionary.
x_axis_name (str, optional) – Name of x-axis. Defaults to None, which does not plot a name.
y_axis_name (str, optional) – Name of y-axis. Defaults to None, which does not plot a name.
title (str, optional) – Title for the figure. Defaults to None, which does not plot a title.
show_data_set_legend (bool, optional) – Whether or not to plot the data set legend. Defaults to False. Is automatically shown if any threshold lines have the keyword “label” passed through
threshold_kwds.categories_legend (dict[str, str], optional) – Dictionary mapping data categories to relabeling. Defaults to None. If provided, generates a second legend for data categories and relabels the x-axis accordingly. Can be a subset of the data keys.
threshold_values (Union[list[float], float], optional) – List of values to plot horizontal lines at. Can be provided as a list or a single float.
threshold_kwds (Union[list[dict], dict], optional) – List of plotting keywords for the horizontal lines. Can be a list or single dictionary. These will be passed to plt.axhline(). Common keywords include “linestyle”, “linewidth”, and “label”. If “label” is passed, automatically plots the data set legend with the labels.
legend_font_size (float, optional) – The font size to use for the legend. Defaults to 10.0 + the number of categories.
legend_loc (str, optional) – The location parameter to pass to
Axes.legend(loc=). Defaults to “center left”.legend_bbox_to_anchor (Tuple[float, float], otptional) – The bounding box to anchor the legend to. Defaults to (1, 0.5).
ax (Axes, optional) – A matplotlib axes object to plot the figure on. Defaults to None, in which case the function creates and returns a new axes. The figure height is 6 inches and the figure width is 3 inches times the number of categories.
- Returns:
A
matplotlibaxes with a bar plot of the given data.- Return type:
Axes
- votekit.plots.profiles.profile_bar_plot.profile_ballot_lengths_plot(profile: RankProfile, *, profile_label: str = 'Profile', ballot_lengths_kwds: dict[str, Any] | None = None, normalize: bool = False, profile_color: str = '#0099cd', bar_width: float | None = None, lengths_ordering: list[str] | None = None, x_axis_name: str | None = None, y_axis_name: str | None = None, title: str | None = None, show_profile_legend: bool = False, lengths_legend: dict[str, str] | None = None, threshold_values: list[float] | float | None = None, threshold_kwds: list[dict] | dict | None = None, legend_font_size: float | None = None, ax: matplotlib.axes.Axes | None = None) matplotlib.axes.Axes[source]
Plots ballot lengths in profile. Wrapper for
profile_bar_plot.- Parameters:
profile (RankProfile) – Profile to plot statistics for.
profile_label (str, optional) – Label for profile. Defaults to “Profile”.
ballot_lengths_kwds (dict[str, Any], optional) – Keyword arguments to pass to
ballot_lengths. Defaults to None, in which case default values forballot_lengthsare used.normalize (bool, optional) – Whether or not to normalize data. Defaults to False.
profile_color (str, optional) – Color to plot. Defaults to the first color from
COLOR_LISTfromutilsmodule.bar_width (float, optional) – Width of bars. Defaults to None which computes the bar width as 0.7 divided by the number of data sets. Must be in the interval \((0,1]\).
lengths_ordering (list[str], optional) – Ordering of x-labels. Defaults to increasing order of lengths.
x_axis_name (str, optional) – Name of x-axis. Defaults to None, which does not plot a name.
y_axis_name (str, optional) – Name of y-axis. Defaults to None, which does not plot a name.
title (str, optional) – Title for the figure. Defaults to None, which does not plot a title.
show_profile_legend (bool, optional) – Whether or not to plot the profile legend. Defaults to False. Is automatically shown if any threshold lines have the keyword “label” passed through
threshold_kwds.lengths_legend (dict[str, str], optional) – Dictionary mapping lengths to alternate label. Defaults to None. If provided, generates a second legend.
threshold_values (Union[list[float], float], optional) – List of values to plot horizontal lines at. Can be provided as a list or a single float.
threshold_kwds (Union[list[dict], dict], optional) – List of plotting keywords for the horizontal lines. Can be a list or single dictionary. These will be passed to plt.axhline(). Common keywords include “linestyle”, “linewidth”, and “label”. If “label” is passed, automatically plots the data set legend with the labels.
legend_font_size (float, optional) – The font size to use for the legend. Defaults to 10.0 + the number of categories.
legend_loc (str, optional) – The location parameter to pass to
Axes.legend(loc=). Defaults to “center left”.legend_bbox_to_anchor (Tuple[float, float], optional) – The bounding box to anchor the legend to. Defaults to (1, 0.5).
ax (Axes, optional) – A matplotlib axes object to plot the figure on. Defaults to None, in which case the function creates and returns a new axes. The figure height is 6 inches and the figure width is 3 inches times the number of categories.
- Returns:
A
matplotlibaxes with a bar plot of the given data.- Return type:
Axes
- votekit.plots.profiles.profile_bar_plot.profile_bar_plot(profile: RankProfile | ScoreProfile, stat_function: Callable[[RankProfile | ScoreProfile], dict[str, float]], *, profile_label: str = 'Profile', normalize: bool = False, profile_color: str = '#0099cd', bar_width: float | None = None, category_ordering: list[str] | None = None, x_axis_name: str | None = None, y_axis_name: str | None = None, title: str | None = None, show_profile_legend: bool = False, categories_legend: dict[str, str] | None = None, threshold_values: list[float] | float | None = None, threshold_kwds: list[dict] | dict | None = None, legend_font_size: float | None = None, ax: matplotlib.axes.Axes | None = None) matplotlib.axes.Axes[source]
Plots bar plot of single profile. Wrapper for
multi_profile_bar_plot.- Parameters:
profile (RankProfile) – Profile to plot statistics for.
stat_function (Callable[[RankProfile], dict[str, float]]) – Which stat to use for the bar plot. Must be a callable that takes a profile and returns a dict with str keys and float values.
profile_label (str, optional) – Label for profile. Defaults to “Profile”.
normalize (bool, optional) – Whether or not to normalize data. Defaults to False.
profile_color (str, optional) – Color to plot. Defaults to the first color from
COLOR_LISTfromutilsmodule.bar_width (float, optional) – Width of bars. Defaults to None which computes the bar width as 0.7 divided by the number of data sets. Must be in the interval \((0,1]\).
category_ordering (list[str], optional) – Ordering of x-labels. Defaults to order retrieved from data dictionary.
x_axis_name (str, optional) – Name of x-axis. Defaults to None, which does not plot a name.
y_axis_name (str, optional) – Name of y-axis. Defaults to None, which does not plot a name.
title (str, optional) – Title for the figure. Defaults to None, which does not plot a title.
show_profile_legend (bool, optional) – Whether or not to plot the profile legend. Defaults to False. Is automatically shown if any threshold lines have the keyword “label” passed through
threshold_kwds.categories_legend (dict[str, str], optional) – Dictionary mapping data categories to description. Defaults to None. If provided, generates a second legend for data categories.
threshold_values (Union[list[float], float], optional) – List of values to plot horizontal lines at. Can be provided as a list or a single float.
threshold_kwds (Union[list[dict], dict], optional) – List of plotting keywords for the horizontal lines. Can be a list or single dictionary. These will be passed to plt.axhline(). Common keywords include “linestyle”, “linewidth”, and “label”. If “label” is passed, automatically plots the data set legend with the labels.
legend_font_size (float, optional) – The font size to use for the legend. Defaults to 10.0 + the number of categories.
legend_loc (str, optional) – The location parameter to pass to
Axes.legend(loc=). Defaults to “center left”.legend_bbox_to_anchor (Tuple[float, float], otptional) – The bounding box to anchor the legend to. Defaults to (1, 0.5).
ax (Axes, optional) – A matplotlib axes object to plot the figure on. Defaults to None, in which case the function creates and returns a new axes. The figure height is 6 inches and the figure width is 3 inches times the number of categories.
- Returns:
A
matplotlibaxes with a bar plot of the given data.- Return type:
Axes
- votekit.plots.profiles.profile_bar_plot.profile_borda_plot(profile: RankProfile, *, profile_label: str = 'Profile', borda_kwds: dict[str, Any] | None = None, normalize: bool = False, profile_color: str = '#0099cd', bar_width: float | None = None, candidate_ordering: list[str] | None = None, x_axis_name: str | None = None, y_axis_name: str | None = None, title: str | None = None, show_profile_legend: bool = False, candidate_legend: dict[str, str] | None = None, relabel_candidates_with_int: bool = False, threshold_values: list[float] | float | None = None, threshold_kwds: list[dict] | dict | None = None, legend_font_size: float | None = None, ax: matplotlib.axes.Axes | None = None) matplotlib.axes.Axes[source]
Plots borda points of candidates in profile. Wrapper for
profile_bar_plot.- Parameters:
profile (RankProfile) – Profile to plot statistics for.
profile_label (str, optional) – Label for profile. Defaults to “Profile”.
borda_kwds (dict[str, Any], optional) – Keyword arguments to pass to
borda_scores. Defaults to None, in which case default values forborda_scoresare used.normalize (bool, optional) – Whether or not to normalize data. Defaults to False.
profile_color (str, optional) – Color to plot. Defaults to the first color from
COLOR_LISTfromutilsmodule.bar_width (float, optional) – Width of bars. Defaults to None which computes the bar width as 0.7 divided by the number of data sets. Must be in the interval \((0,1]\).
candidate_ordering (list[str], optional) – Ordering of x-labels. Defaults to decreasing order of Borda scores.
x_axis_name (str, optional) – Name of x-axis. Defaults to None, which does not plot a name.
y_axis_name (str, optional) – Name of y-axis. Defaults to None, which does not plot a name.
title (str, optional) – Title for the figure. Defaults to None, which does not plot a title.
show_profile_legend (bool, optional) – Whether or not to plot the profile legend. Defaults to False. Is automatically shown if any threshold lines have the keyword “label” passed through
threshold_kwds.candidate_legend (dict[str, str], optional) – Dictionary mapping candidates to alternate label. Defaults to None. If provided, generates a second legend.
relabel_candidates_with_int (bool, optional) – Relabel the candidates with integer labels. Defaults to False. If
candidate_legendis passed, those labels supercede.threshold_values (Union[list[float], float], optional) – List of values to plot horizontal lines at. Can be provided as a list or a single float.
threshold_kwds (Union[list[dict], dict], optional) – List of plotting keywords for the horizontal lines. Can be a list or single dictionary. These will be passed to plt.axhline(). Common keywords include “linestyle”, “linewidth”, and “label”. If “label” is passed, automatically plots the data set legend with the labels.
legend_font_size (float, optional) – The font size to use for the legend. Defaults to 10.0 + the number of categories.
legend_loc (str, optional) – The location parameter to pass to
Axes.legend(loc=). Defaults to “center left”.legend_bbox_to_anchor (Tuple[float, float], otptional) – The bounding box to anchor the legend to. Defaults to (1, 0.5).
ax (Axes, optional) – A matplotlib axes object to plot the figure on. Defaults to None, in which case the function creates and returns a new axes. The figure height is 6 inches and the figure width is 3 inches times the number of categories.
- Returns:
A
matplotlibaxes with a bar plot of the given data.- Return type:
Axes
- votekit.plots.profiles.profile_bar_plot.profile_fpv_plot(profile: RankProfile, *, profile_label: str = 'Profile', fpv_kwds: dict[str, Any] | None = None, normalize: bool = False, profile_color: str = '#0099cd', bar_width: float | None = None, candidate_ordering: list[str] | None = None, x_axis_name: str | None = None, y_axis_name: str | None = None, title: str | None = None, show_profile_legend: bool = False, candidate_legend: dict[str, str] | None = None, relabel_candidates_with_int: bool = False, threshold_values: list[float] | float | None = None, threshold_kwds: list[dict] | dict | None = None, legend_font_size: float | None = None, ax: matplotlib.axes.Axes | None = None) matplotlib.axes.Axes[source]
Plots first place votes of candidates in profile. Wrapper for
profile_bar_plot.- Parameters:
profile (RankProfile) – Profile to plot statistics for.
profile_label (str, optional) – Label for profile. Defaults to “Profile”.
fpv_kwds (dict[str, Any], optional) – Keyword arguments to pass to
first_place_votes. Defaults to None, in which case default values forfirst_place_votesare used.normalize (bool, optional) – Whether or not to normalize data. Defaults to False.
profile_color (str, optional) – Color to plot. Defaults to the first color from
COLOR_LISTfromutilsmodule.bar_width (float, optional) – Width of bars. Defaults to None which computes the bar width as 0.7 divided by the number of data sets. Must be in the interval \((0,1]\).
candidate_ordering (list[str], optional) – Ordering of x-labels. Defaults to decreasing order of first place votes.
x_axis_name (str, optional) – Name of x-axis. Defaults to None, which does not plot a name.
y_axis_name (str, optional) – Name of y-axis. Defaults to None, which does not plot a name.
title (str, optional) – Title for the figure. Defaults to None, which does not plot a title.
show_profile_legend (bool, optional) – Whether or not to plot the profile legend. Defaults to False. Is automatically shown if any threshold lines have the keyword “label” passed through
threshold_kwds.candidate_legend (dict[str, str], optional) – Dictionary mapping candidates to alternate label. Defaults to None. If provided, generates a second legend.
relabel_candidates_with_int (bool, optional) – Relabel the candidates with integer labels. Defaults to False. If
candidate_legendis passed, those labels supercede.threshold_values (Union[list[float], float], optional) – List of values to plot horizontal lines at. Can be provided as a list or a single float.
threshold_kwds (Union[list[dict], dict], optional) – List of plotting keywords for the horizontal lines. Can be a list or single dictionary. These will be passed to plt.axhline(). Common keywords include “linestyle”, “linewidth”, and “label”. If “label” is passed, automatically plots the data set legend with the labels.
legend_font_size (float, optional) – The font size to use for the legend. Defaults to 10.0 + the number of categories.
legend_loc (str, optional) – The location parameter to pass to
Axes.legend(loc=). Defaults to “center left”.legend_bbox_to_anchor (Tuple[float, float], otptional) – The bounding box to anchor the legend to. Defaults to (1, 0.5).
ax (Axes, optional) – A matplotlib axes object to plot the figure on. Defaults to None, in which case the function creates and returns a new axes. The figure height is 6 inches and the figure width is 3 inches times the number of categories.
- Returns:
A
matplotlibaxes with a bar plot of the given data.- Return type:
Axes
- votekit.plots.profiles.profile_bar_plot.profile_mentions_plot(profile: RankProfile, *, profile_label: str = 'Profile', mentions_kwds: dict[str, Any] | None = None, normalize: bool = False, profile_color: str = '#0099cd', bar_width: float | None = None, candidate_ordering: list[str] | None = None, x_axis_name: str | None = None, y_axis_name: str | None = None, title: str | None = None, show_profile_legend: bool = False, candidate_legend: dict[str, str] | None = None, relabel_candidates_with_int: bool = False, threshold_values: list[float] | float | None = None, threshold_kwds: list[dict] | dict | None = None, legend_font_size: float | None = None, ax: matplotlib.axes.Axes | None = None) matplotlib.axes.Axes[source]
Plots mentions of candidates in profile. Wrapper for
profile_bar_plot.- Parameters:
profile (RankProfile) – Profile to plot statistics for.
profile_label (str, optional) – Label for profile. Defaults to “Profile”.
mentions_kwds (dict[str, Any], optional) – Keyword arguments to pass to
mentions. Defaults to None, in which case default values formentionsare used.normalize (bool, optional) – Whether or not to normalize data. Defaults to False.
profile_color (str, optional) – Color to plot. Defaults to the first color from
COLOR_LISTfromutilsmodule.bar_width (float, optional) – Width of bars. Defaults to None which computes the bar width as 0.7 divided by the number of data sets. Must be in the interval \((0,1]\).
candidate_ordering (list[str], optional) – Ordering of x-labels. Defaults to decreasing order of mentions.
x_axis_name (str, optional) – Name of x-axis. Defaults to None, which does not plot a name.
y_axis_name (str, optional) – Name of y-axis. Defaults to None, which does not plot a name.
title (str, optional) – Title for the figure. Defaults to None, which does not plot a title.
show_profile_legend (bool, optional) – Whether or not to plot the profile legend. Defaults to False. Is automatically shown if any threshold lines have the keyword “label” passed through
threshold_kwds.candidate_legend (dict[str, str], optional) – Dictionary mapping candidates to alternate label. Defaults to None. If provided, generates a second legend.
relabel_candidates_with_int (bool, optional) – Relabel the candidates with integer labels. Defaults to False. If
candidate_legendis passed, those labels supercede.threshold_values (Union[list[float], float], optional) – List of values to plot horizontal lines at. Can be provided as a list or a single float.
threshold_kwds (Union[list[dict], dict], optional) – List of plotting keywords for the horizontal lines. Can be a list or single dictionary. These will be passed to plt.axhline(). Common keywords include “linestyle”, “linewidth”, and “label”. If “label” is passed, automatically plots the data set legend with the labels.
legend_font_size (float, optional) – The font size to use for the legend. Defaults to 10.0 + the number of categories.
legend_loc (str, optional) – The location parameter to pass to
Axes.legend(loc=). Defaults to “center left”.legend_bbox_to_anchor (Tuple[float, float], otptional) – The bounding box to anchor the legend to. Defaults to (1, 0.5).
ax (Axes, optional) – A matplotlib axes object to plot the figure on. Defaults to None, in which case the function creates and returns a new axes. The figure height is 6 inches and the figure width is 3 inches times the number of categories.
- Returns:
A
matplotlibaxes with a bar plot of the given data.- Return type:
Axes
- votekit.plots.profiles.multi_profile_bar_plot.multi_profile_ballot_lengths_plot(profile_dict: dict[str, RankProfile], ballot_lengths_kwds: dict[str, Any] | None = None, normalize: bool = False, profile_colors: dict[str, str] | None = None, bar_width: float | None = None, lengths_ordering: list[str] | None = None, x_axis_name: str | None = None, y_axis_name: str | None = None, title: str | None = None, show_profile_legend: bool = False, lengths_legend: dict[str, str] | None = None, threshold_values: list[float] | float | None = None, threshold_kwds: list[dict] | dict | None = None, legend_font_size: float | None = None, ax: matplotlib.axes.Axes | None = None) matplotlib.axes.Axes[source]
Plot the ballot lengths for a collection of profiles. Wrapper for
multi_profile_bar_plot.- Parameters:
profile_dict (dict[str, RankProfile]) – Keys are profile labels and values are profiles to plot statistics for.
ballot_lengths_kwds (dict[str, Any], optional) – Keyword arguments to pass to
ballot_lengths. Defaults to None, in which case default values forballot_lengthsare used.normalize (bool, optional) – Whether or not to normalize data. Defaults to False.
profile_colors (dict[str, str], optional) – Dictionary mapping profile labels to colors. Defaults to None, in which case we use a subset of
COLOR_LISTfromutilsmodule. Dictionary keys can be a subset of the profiles.bar_width (float, optional) – Width of bars. Defaults to None which computes the bar width as 0.7 divided by the number of data sets. Must be in the interval \((0,1]\).
lengths_ordering (list[str], optional) – Ordering of x-labels. Defaults to order retrieved from score dictionary.
x_axis_name (str, optional) – Name of x-axis. Defaults to None, which does not plot a name.
y_axis_name (str, optional) – Name of y-axis. Defaults to None, which does not plot a name.
title (str, optional) – Title for the figure. Defaults to None, which does not plot a title.
show_profile_legend (bool, optional) – Whether or not to plot the profile legend. Defaults to False. Is automatically shown if any threshold lines have the keyword “label” passed through
threshold_kwds.lengths_legend (dict[str, str], optional) – Dictionary mapping lengths to relableing. Defaults to None. If provided, generates a second legend for data categories.
threshold_values (Union[list[float], float], optional) – List of values to plot horizontal lines at. Can be provided as a list or a single float.
threshold_kwds (Union[list[dict], dict], optional) – List of plotting keywords for the horizontal lines. Can be a list or single dictionary. These will be passed to plt.axhline(). Common keywords include “linestyle”, “linewidth”, and “label”. If “label” is passed, automatically plots the data set legend with the labels.
legend_font_size (float, optional) – The font size to use for the legend. Defaults to 10.0 + the number of categories.
legend_loc (str, optional) – The location parameter to pass to
Axes.legend(loc=). Defaults to “center left”.legend_bbox_to_anchor (Tuple[float, float], otptional) – The bounding box to anchor the legend to. Defaults to (1, 0.5).
ax (Axes, optional) – A matplotlib axes object to plot the figure on. Defaults to None, in which case the function creates and returns a new axes. The figure height is 6 inches and the figure width is 3 inches times the number of categories.
- Returns:
A
matplotlibaxes with a bar plot of the given data.- Return type:
Axes
- votekit.plots.profiles.multi_profile_bar_plot.multi_profile_bar_plot(profile_dict: dict[str, RankProfile | ScoreProfile], stat_function: Callable[[RankProfile | ScoreProfile], dict[str, float]], normalize: bool = False, profile_colors: dict[str, str] | None = None, bar_width: float | None = None, category_ordering: list[str] | None = None, x_axis_name: str | None = None, y_axis_name: str | None = None, title: str | None = None, show_profile_legend: bool = False, categories_legend: dict[str, str] | None = None, threshold_values: list[float] | float | None = None, threshold_kwds: list[dict] | dict | None = None, legend_font_size: float | None = None, ax: matplotlib.axes.Axes | None = None) matplotlib.axes.Axes[source]
Plot a multi bar plot over a set of preference profiles and some statistic about the profile, like ballot length, first place votes for candidate, etc.
- Parameters:
profile_dict (dict[str, RankProfile | ScoreProfile]) – Keys are profile labels and values are profiles to plot statistics for.
stat_function (Callable[[RankProfile | ScoreProfile], dict[str, float]]) – Which stat to use for the bar plot. Must be a callable that takes a profile and returns a dict with str keys and float values.
normalize (bool, optional) – Whether or not to normalize data. Defaults to False.
profile_colors (dict[str, str], optional) – Dictionary mapping profile labels to colors. Defaults to None, in which case we use a subset of
COLOR_LISTfromutilsmodule. Dictionary keys can be a subset of the profiles.bar_width (float, optional) – Width of bars. Defaults to None which computes the bar width as 0.7 divided by the number of data sets. Must be in the interval \((0,1]\).
category_ordering (list[str], optional) – Ordering of x-labels. Defaults to order retrieved from data dictionary.
x_axis_name (str, optional) – Name of x-axis. Defaults to None, which does not plot a name.
y_axis_name (str, optional) – Name of y-axis. Defaults to None, which does not plot a name.
title (str, optional) – Title for the figure. Defaults to None, which does not plot a title.
show_profile_legend (bool, optional) – Whether or not to plot the profile legend. Defaults to False. Is automatically shown if any threshold lines have the keyword “label” passed through
threshold_kwds.categories_legend (dict[str, str], optional) – Dictionary mapping data categories to description. Defaults to None. If provided, generates a second legend for data categories.
threshold_values (Union[list[float], float], optional) – List of values to plot horizontal lines at. Can be provided as a list or a single float.
threshold_kwds (Union[list[dict], dict], optional) – List of plotting keywords for the horizontal lines. Can be a list or single dictionary. These will be passed to plt.axhline(). Common keywords include “linestyle”, “linewidth”, and “label”. If “label” is passed, automatically plots the data set legend with the labels.
legend_font_size (float, optional) – The font size to use for the legend. Defaults to 10.0 + the number of categories.
legend_loc (str, optional) – The location parameter to pass to
Axes.legend(loc=). Defaults to “center left”.legend_bbox_to_anchor (Tuple[float, float], otptional) – The bounding box to anchor the legend to. Defaults to (1, 0.5).
ax (Axes, optional) – A matplotlib axes object to plot the figure on. Defaults to None, in which case the function creates and returns a new axes. The figure height is 6 inches and the figure width is 3 inches times the number of categories.
- Returns:
A
matplotlibaxes with a bar plot of the given data.- Return type:
Axes
- votekit.plots.profiles.multi_profile_bar_plot.multi_profile_borda_plot(profile_dict: dict[str, RankProfile], borda_kwds: dict[str, Any] | None = None, normalize: bool = False, profile_colors: dict[str, str] | None = None, bar_width: float | None = None, candidate_ordering: list[str] | None = None, x_axis_name: str | None = None, y_axis_name: str | None = None, title: str | None = None, show_profile_legend: bool = False, candidate_legend: dict[str, str] | None = None, relabel_candidates_with_int: bool = False, threshold_values: list[float] | float | None = None, threshold_kwds: list[dict] | dict | None = None, legend_font_size: float | None = None, ax: matplotlib.axes.Axes | None = None) matplotlib.axes.Axes[source]
Plot the borda scores for a collection of profiles. Wrapper for
multi_profile_bar_plot.- Parameters:
profile_dict (dict[str, RankProfile]) – Keys are profile labels and values are profiles to plot statistics for.
borda_kwds (dict[str, Any], optional) – Keyword arguments to pass to
borda_scores. Defaults to None, in which case default values forborda_scoresare used.normalize (bool, optional) – Whether or not to normalize data. Defaults to False.
profile_colors (dict[str, str], optional) – Dictionary mapping profile labels to colors. Defaults to None, in which case we use a subset of
COLOR_LISTfromutilsmodule. Dictionary keys can be a subset of the profiles.bar_width (float, optional) – Width of bars. Defaults to None which computes the bar width as 0.7 divided by the number of data sets. Must be in the interval \((0,1]\).
candidate_ordering (list[str], optional) – Ordering of x-labels. Defaults to decreasing borda scores from the first profile.
x_axis_name (str, optional) – Name of x-axis. Defaults to None, which does not plot a name.
y_axis_name (str, optional) – Name of y-axis. Defaults to None, which does not plot a name.
title (str, optional) – Title for the figure. Defaults to None, which does not plot a title.
show_profile_legend (bool, optional) – Whether or not to plot the profile legend. Defaults to False. Is automatically shown if any threshold lines have the keyword “label” passed through
threshold_kwds.candidate_legend (dict[str, str], optional) – Dictionary mapping candidates to relableing. Defaults to None. If provided, generates a second legend for data categories.
relabel_candidates_with_int (bool, optional) – Relabel the candidates with integer labels. Defaults to False. If
candidate_legendis passed, those labels supercede.threshold_values (Union[list[float], float], optional) – List of values to plot horizontal lines at. Can be provided as a list or a single float.
threshold_kwds (Union[list[dict], dict], optional) – List of plotting keywords for the horizontal lines. Can be a list or single dictionary. These will be passed to plt.axhline(). Common keywords include “linestyle”, “linewidth”, and “label”. If “label” is passed, automatically plots the data set legend with the labels.
legend_font_size (float, optional) – The font size to use for the legend. Defaults to 10.0 + the number of categories.
legend_loc (str, optional) – The location parameter to pass to
Axes.legend(loc=). Defaults to “center left”.legend_bbox_to_anchor (Tuple[float, float], otptional) – The bounding box to anchor the legend to. Defaults to (1, 0.5).
ax (Axes, optional) – A matplotlib axes object to plot the figure on. Defaults to None, in which case the function creates and returns a new axes. The figure height is 6 inches and the figure width is 3 inches times the number of categories.
- Returns:
A
matplotlibaxes with a bar plot of the given data.- Return type:
Axes
- votekit.plots.profiles.multi_profile_bar_plot.multi_profile_fpv_plot(profile_dict: dict[str, RankProfile], fpv_kwds: dict[str, Any] | None = None, normalize: bool = False, profile_colors: dict[str, str] | None = None, bar_width: float | None = None, candidate_ordering: list[str] | None = None, x_axis_name: str | None = None, y_axis_name: str | None = None, title: str | None = None, show_profile_legend: bool = False, candidate_legend: dict[str, str] | None = None, relabel_candidates_with_int: bool = False, threshold_values: list[float] | float | None = None, threshold_kwds: list[dict] | dict | None = None, legend_font_size: float | None = None, ax: matplotlib.axes.Axes | None = None) matplotlib.axes.Axes[source]
Plot the first place votes for a collection of profiles. Wrapper for
multi_profile_bar_plot.- Parameters:
profile_dict (dict[str, RankProfile]) – Keys are profile labels and values are profiles to plot statistics for.
fpv_kwds (dict[str, Any], optional) – Keyword arguments to pass to
first_place_votes. Defaults to None, in which case default values forfirst_place_votesare used.normalize (bool, optional) – Whether or not to normalize data. Defaults to False.
profile_colors (dict[str, str], optional) – Dictionary mapping profile labels to colors. Defaults to None, in which case we use a subset of
COLOR_LISTfromutilsmodule. Dictionary keys can be a subset of the profiles.bar_width (float, optional) – Width of bars. Defaults to None which computes the bar width as 0.7 divided by the number of data sets. Must be in the interval \((0,1]\).
candidate_ordering (list[str], optional) – Ordering of x-labels. Defaults to order retrieved from score dictionary.
x_axis_name (str, optional) – Name of x-axis. Defaults to None, which does not plot a name.
y_axis_name (str, optional) – Name of y-axis. Defaults to None, which does not plot a name.
title (str, optional) – Title for the figure. Defaults to None, which does not plot a title.
show_profile_legend (bool, optional) – Whether or not to plot the profile legend. Defaults to False. Is automatically shown if any threshold lines have the keyword “label” passed through
threshold_kwds.candidate_legend (dict[str, str], optional) – Dictionary mapping candidates to relableing. Defaults to None. If provided, generates a second legend for data categories.
relabel_candidates_with_int (bool, optional) – Relabel the candidates with integer labels. Defaults to False. If
candidate_legendis passed, those labels supercede.threshold_values (Union[list[float], float], optional) – List of values to plot horizontal lines at. Can be provided as a list or a single float.
threshold_kwds (Union[list[dict], dict], optional) – List of plotting keywords for the horizontal lines. Can be a list or single dictionary. These will be passed to plt.axhline(). Common keywords include “linestyle”, “linewidth”, and “label”. If “label” is passed, automatically plots the data set legend with the labels.
legend_font_size (float, optional) – The font size to use for the legend. Defaults to 10.0 + the number of categories.
legend_loc (str, optional) – The location parameter to pass to
Axes.legend(loc=). Defaults to “center left”.legend_bbox_to_anchor (Tuple[float, float], otptional) – The bounding box to anchor the legend to. Defaults to (1, 0.5).
ax (Axes, optional) – A matplotlib axes object to plot the figure on. Defaults to None, in which case the function creates and returns a new axes. The figure height is 6 inches and the figure width is 3 inches times the number of categories.
- Returns:
A
matplotlibaxes with a bar plot of the given data.- Return type:
Axes
- votekit.plots.profiles.multi_profile_bar_plot.multi_profile_mentions_plot(profile_dict: dict[str, RankProfile], mentions_kwds: dict[str, Any] | None = None, normalize: bool = False, profile_colors: dict[str, str] | None = None, bar_width: float | None = None, candidate_ordering: list[str] | None = None, x_axis_name: str | None = None, y_axis_name: str | None = None, title: str | None = None, show_profile_legend: bool = False, candidate_legend: dict[str, str] | None = None, relabel_candidates_with_int: bool = False, threshold_values: list[float] | float | None = None, threshold_kwds: list[dict] | dict | None = None, legend_font_size: float | None = None, ax: matplotlib.axes.Axes | None = None) matplotlib.axes.Axes[source]
Plot the mentions for a collection of profiles. Wrapper for
multi_profile_bar_plot.- Parameters:
profile_dict (dict[str, RankProfile]) – Keys are profile labels and values are profiles to plot statistics for.
mentions_kwds (dict[str, Any], optional) – Keyword arguments to pass to
mentions. Defaults to None, in which case default values formentionsare used.normalize (bool, optional) – Whether or not to normalize data. Defaults to False.
profile_colors (dict[str, str], optional) – Dictionary mapping profile labels to colors. Defaults to None, in which case we use a subset of
COLOR_LISTfromutilsmodule. Dictionary keys can be a subset of the profiles.bar_width (float, optional) – Width of bars. Defaults to None which computes the bar width as 0.7 divided by the number of data sets. Must be in the interval \((0,1]\).
candidate_ordering (list[str], optional) – Ordering of x-labels. Defaults to order retrieved from score dictionary.
x_axis_name (str, optional) – Name of x-axis. Defaults to None, which does not plot a name.
y_axis_name (str, optional) – Name of y-axis. Defaults to None, which does not plot a name.
title (str, optional) – Title for the figure. Defaults to None, which does not plot a title.
show_profile_legend (bool, optional) – Whether or not to plot the profile legend. Defaults to False. Is automatically shown if any threshold lines have the keyword “label” passed through
threshold_kwds.candidate_legend (dict[str, str], optional) – Dictionary mapping candidates to relableing. Defaults to None. If provided, generates a second legend for data categories.
relabel_candidates_with_int (bool, optional) – Relabel the candidates with integer labels. Defaults to False. If
candidate_legendis passed, those labels supercede.threshold_values (Union[list[float], float], optional) – List of values to plot horizontal lines at. Can be provided as a list or a single float.
threshold_kwds (Union[list[dict], dict], optional) – List of plotting keywords for the horizontal lines. Can be a list or single dictionary. These will be passed to plt.axhline(). Common keywords include “linestyle”, “linewidth”, and “label”. If “label” is passed, automatically plots the data set legend with the labels.
legend_font_size (float, optional) – The font size to use for the legend. Defaults to 10.0 + the number of categories.
legend_loc (str, optional) – The location parameter to pass to
Axes.legend(loc=). Defaults to “center left”.legend_bbox_to_anchor (Tuple[float, float], otptional) – The bounding box to anchor the legend to. Defaults to (1, 0.5).
ax (Axes, optional) – A matplotlib axes object to plot the figure on. Defaults to None, in which case the function creates and returns a new axes. The figure height is 6 inches and the figure width is 3 inches times the number of categories.
- Returns:
A
matplotlibaxes with a bar plot of the given data.- Return type:
Axes
Cast Vote Records
- votekit.cvr_loaders.load_csv(path_or_url: str, rank_cols: list[int], *, weight_col: int | None = None, id_col: int | None = None, candidates: list[str] | None = None, delimiter: str = ',', header_row: int | None = None, print_profile: bool = True) RankProfile[source]
Given a file path or url, loads ranked cast vote record (cvr) with ranks as columns and voters as rows.
- Parameters:
path_or_url (str) – Path or url to cvr file.
rank_cols (list[int]) – List of column indices that contain rankings. Column indexing starts from 0, in order from top to bottom rank.
weight_col (Optional[int]) – The column position for ballot weights. Defaults to None, which implies each row has weight 1. Cannot be provided if
id_colis also provided.id_col (Optional[int]) – Index for the column with voter ids. Defaults to None. Cannot be provided if
weight_colis also provided.candidates (Optional[list[str]]) – List of candidate names. Defaults to None, in which case names are inferred from the CVR.
delimiter (Optional[str]) – The character that separates entries. Defaults to a comma.
header_row (Optional[int]) – The row containing the column names, below which the data begins. Defaults to None, in which case row 0 is considered to be the first ballot.
print_profile (bool) – Whether or not to print the loaded profile. Defaults to True. Useful for debugging.
- Raises:
FileNotFoundError – CSV cannot be found. Raised by
pandas.read_csv.URLError – Invalid url. Raised by
pandas.read_csv.HTTPError – URL is valid but other failure occurs. Raised by
pandas.read_csv.ParserError – Pandas fails to read the csv. Raised by
pandas.read_csv.UnicodeDecodeError – Bad encoding. Raised by
pandas.read_csv.ValueError – Candidates provided but they do not exist in the CSV.
ValueError – Candidates provided but extra candidates are found in the CSV.
ValueError – Only one of weight_col or id_col can be provided.
ValueError – weight_col or id_col are not distinct from rank_cols.
ValueError – weight_col, id_col, and each entry of rank_cols must be non-negative and within the number of columns of the csv.
ValueError – If weight_col is provided, weights must be non-empty and convertible to float.
ValueError – Header must be non-negative.
- Returns:
A
RankProfilethat represents all the ballots in the csv.- Return type:
- votekit.cvr_loaders.load_ranking_csv(path_or_url: str | PathLike | Path, rank_cols: list[int], *, weight_col: int | None = None, id_col: int | None = None, candidates: list[str] | None = None, delimiter: str = ',', header_row: int | None = None, print_profile: bool = True) RankProfile[source]
Given a file path or url, loads ranked cast vote record (cvr) with ranks as columns and voters as rows.
- Parameters:
path_or_url (Union[str, os.PathLike, pathlib.Path]) – Path or url to cvr file.
rank_cols (list[int]) – List of column indices that contain rankings. Column indexing starts from 0, in order from top to bottom rank.
weight_col (Optional[int]) – The column position for ballot weights. Defaults to None, which implies each row has weight 1. Cannot be provided if
id_colis also provided.id_col (Optional[int]) – Index for the column with voter ids. Defaults to None. Cannot be provided if
weight_colis also provided.candidates (Optional[list[str]]) – List of candidate names. Defaults to None, in which case names are inferred from the CVR.
delimiter (Optional[str]) – The character that separates entries. Defaults to a comma.
header_row (Optional[int]) – The row containing the column names, below which the data begins. Defaults to None, in which case row 0 is considered to be the first ballot.
print_profile (bool) – Whether or not to print the loaded profile. Defaults to True. Useful for debugging.
- Raises:
FileNotFoundError – CSV cannot be found. Raised by
pandas.read_csv.URLError – Invalid url. Raised by
pandas.read_csv.HTTPError – URL is valid but other failure occurs. Raised by
pandas.read_csv.ParserError – Pandas fails to read the csv. Raised by
pandas.read_csv.UnicodeDecodeError – Bad encoding. Raised by
pandas.read_csv.ValueError – Candidates provided but they do not exist in the CSV.
ValueError – Candidates provided but extra candidates are found in the CSV.
ValueError – Only one of weight_col or id_col can be provided.
ValueError – weight_col or id_col are not distinct from rank_cols.
ValueError – weight_col, id_col, and each entry of rank_cols must be non-negative and within the number of columns of the csv.
ValueError – If weight_col is provided, weights must be non-empty and convertible to float.
ValueError – Header must be non-negative.
- Returns:
A
RankProfilethat represents all the ballots in the csv.- Return type:
- votekit.cvr_loaders.load_scottish(fpath: str | PathLike | Path) tuple[RankProfile, int, list[str], dict[str, str], str][source]
Given a file path, loads cast vote record from format used for Scottish election data in (this repo)[https://github.com/mggg/scot-elex].
- Parameters:
fpath (Union[str, os.PathLike, pathlib.Path]) – Path to Scottish election csv file. Can be a url.
- Raises:
FileNotFoundError – If fpath is invalid.
EmptyDataError – If dataset is empty.
DataError – If there is missing or incorrect metadata or candidate data.
- Returns:
A tuple
(RankProfile, seats, cand_list, cand_to_party, ward)representing the election, the number of seats in the election, the candidate names, a dictionary mapping candidates to their party, and the ward. The candidate names are also stored in the PreferenceProfile object.- Return type:
tuple
- votekit.cleaning.clean_rank_profile(profile: RankProfile, clean_ranking_func: Callable[[tuple], tuple], remove_empty_ballots: bool = True, remove_zero_weight_ballots: bool = True, retain_original_candidate_list: bool = True) CleanedRankProfile[source]
Allows user-defined cleaning rules for RankProfile. Input function that applies modification to ranking portion of the df, not weight or voterset.
- Parameters:
profile (RankProfile) – A RankProfile to clean.
clean_ranking_func (Callable[[tuple], tuple]) – Function that takes the ranking portion of a row of the profile df and returns an altered ranking.
remove_empty_ballots (bool, optional) – Whether or not to remove ballots that have no ranking and no scores as a result of the cleaning. Defaults to True.
remove_zero_weight_ballots (bool, optional) – Whether or not to remove ballots that have no weight as a result of the cleaning. Defaults to True.
retain_original_candidate_list (bool, optional) – Whether or not to use the candidate list from the original profile in the new profile. If False, uses only candidates who receive votes. Defaults to True.
- Returns:
A cleaned
RankProfile.- Return type:
- Raises:
ProfileError – Profile must only contain ranked ballots.
- votekit.cleaning.clean_score_profile(profile: ScoreProfile, clean_score_func: Callable[[tuple], tuple], remove_empty_ballots: bool = True, remove_zero_weight_ballots: bool = True, retain_original_candidate_list: bool = True) CleanedScoreProfile[source]
Allows user-defined cleaning rules for ScoreProfile. Cleaning function can only be applied to the score section of the dataframe, not the weight or voter set.
- Parameters:
profile (ScoreProfile) – A ScoreProfile to clean.
clean_score_func (Callable[[tuple], tuple]) – Function that takes the score portion of a row of the profile df and returns an altered score.
remove_empty_ballots (bool, optional) – Whether or not to remove ballots that have no no scores as a result of the cleaning. Defaults to True.
remove_zero_weight_ballots (bool, optional) – Whether or not to remove ballots that have no weight as a result of the cleaning. Defaults to True.
retain_original_candidate_list (bool, optional) – Whether or not to use the candidate list from the original profile in the new profile. If False, uses only candidates who receive votes. Defaults to True.
- Returns:
A cleaned
ScoreProfile.- Return type:
- Raises:
ProfileError – Profile must only contain ranked ballots.
- votekit.cleaning.condense_rank_ballot(ballot: RankBallot) RankBallot[source]
Given a ballot, removes any empty ranking positions and moves up any lower ranked candidates.
- Parameters:
ballot (RankBallot) – Ballot to condense.
- Returns:
Condensed ballot.
- Return type:
- votekit.cleaning.condense_rank_profile(profile: RankProfile, remove_empty_ballots: bool = True, remove_zero_weight_ballots: bool = True, retain_original_candidate_list: bool = True) CleanedRankProfile[source]
Given a ranked profile, removes any empty frozensets from the rankings and condenses the resulting ranking. If a ranking only has trailing empty positions, the condensed ranking is considered equivalent. For example, (A,B,{},{}) is mapped to (A,B) but considered unaltered since the ranking did not change.
Wrapper for clean_rank_profile that does some extra processing to ensure condensed ranking equivalence is handled correctly.
- Parameters:
profile (RankProfile) – Profile to remove repeated candidates from.
remove_empty_ballots (bool, optional) – Whether or not to remove ballots that have no ranking or scores as a result of cleaning. Defaults to True.
remove_zero_weight_ballots (bool, optional) – Whether or not to remove ballots that have no weight as a result of cleaning. Defaults to True.
retain_original_candidate_list (bool, optional) – Whether or not to use the candidate list from the original profile in the new profile. If False, uses only candidates who receive votes. Defaults to True.
- Returns:
A cleaned
RankProfile.- Return type:
- votekit.cleaning.remove_and_condense_rank_profile(removed: str | list, profile: RankProfile, remove_empty_ballots: bool = True, remove_zero_weight_ballots: bool = True, retain_original_candidate_list: bool = False) CleanedRankProfile[source]
Given a ranked profile, remove the given candidate(s) and condense the resulting rankings. If a ranking only has trailing empty positions, the condensed ranking is considered equivalent. For example, (A,B,{},{}) is mapped to (A,B) but considered unaltered since the ranking did not change.
This function is intended to save computational time in election methods, where removing and condensing happen frequently. Researches interested in the difference between removing and condensing should use
remove_candandcondense_profilein series.Wrapper for clean_rank_profile that does some extra processing to ensure the candidate list is handled correctly, and that ballot equivalence is checked.
- Parameters:
removed (Union[str, list]) – Candidate or list of candidates to be removed.
profile (RankProfile) – Profile to remove repeated candidates from.
remove_empty_ballots (bool, optional) – Whether or not to remove ballots that have no ranking or scores as a result of cleaning. Defaults to True.
remove_zero_weight_ballots (bool, optional) – Whether or not to remove ballots that have no weight as a result of cleaning. Defaults to True.
retain_original_candidate_list (bool, optional) – Whether or not to use the candidate list from the orginal profile in the new profile. If False, takes the original candidate list and removes the candidate(s) given in
removed, but preserves all others. Defaults to False.
- Returns:
A cleaned
RankProfile.- Return type:
- votekit.cleaning.remove_cand_rank_ballot(removed: str | list, ballot: RankBallot) RankBallot[source]
Removes specified candidate(s) from ballot. Does not condense the resulting ballot.
- Parameters:
removed (Union[str, list]) – Candidate or list of candidates to be removed.
ballot (RankBallot) – Ballot to remove candidates from.
- Returns:
Ballot with candidate(s) removed.
- Return type:
- votekit.cleaning.remove_cand_rank_profile(removed: str | list, profile: RankProfile, remove_empty_ballots: bool = True, remove_zero_weight_ballots: bool = True, retain_original_candidate_list: bool = False) CleanedRankProfile[source]
Given a ranked profile, remove the given candidate(s) from the ballots. Does not condense the resulting ballots.
Wrapper for clean_rank_profile that does some extra processing to ensure the candidate list is handled correctly.
- Parameters:
removed (Union[str, list]) – Candidate or list of candidates to be removed.
profile (RankProfile) – Profile to remove candidates from.
remove_empty_ballots (bool, optional) – Whether or not to remove ballots that have no ranking or scores as a result of cleaning. Defaults to True.
remove_zero_weight_ballots (bool, optional) – Whether or not to remove ballots that have no weight as a result of cleaning. Defaults to True.
retain_original_candidate_list (bool, optional) – Whether or not to use the candidate list from the orginal profile in the new profile. If False, takes the original candidate list and removes the candidate(s) given in
removed, but preserves all others. Defaults to False.
- Returns:
A cleaned
RankProfile.- Return type:
- Raises:
ProfileError – Profile must only contain ranked ballots.
- votekit.cleaning.remove_cand_score_ballot(removed: str | list, ballot: ScoreBallot) ScoreBallot[source]
Removes specified candidate(s) from ballot.
- Parameters:
removed (Union[str, list]) – Candidate or list of candidates to be removed.
ballot (ScoreBallot) – Ballot to remove candidates from.
- Returns:
Ballot with candidate(s) removed.
- Return type:
- votekit.cleaning.remove_cand_score_profile(removed: str | list, profile: ScoreProfile, remove_empty_ballots: bool = True, remove_zero_weight_ballots: bool = True, retain_original_candidate_list: bool = False) CleanedScoreProfile[source]
Given a score profile, remove the given candidate(s) from the ballots.
Wrapper for clean_score_profile that does some extra processing to ensure the candidate list is handled correctly.
Not as fast as removing the candidate columns directly, but tracks more information about which ballots were adjusted.
- Parameters:
removed (Union[str, list]) – Candidate or list of candidates to be removed.
profile (ScoreProfile) – Profile to remove candidates from.
remove_empty_ballots (bool, optional) – Whether or not to remove ballots that have no ranking or scores as a result of cleaning. Defaults to True.
remove_zero_weight_ballots (bool, optional) – Whether or not to remove ballots that have no weight as a result of cleaning. Defaults to True.
retain_original_candidate_list (bool, optional) – Whether or not to use the candidate list from the orginal profile in the new profile. If False, takes the original candidate list and removes the candidate(s) given in
removed, but preserves all others. Defaults to False.
- Returns:
A cleaned
ScoreProfile.- Return type:
- Raises:
ProfileError – Profile must only contain score ballots.
- votekit.cleaning.remove_repeat_cands_rank_ballot(ballot: RankBallot) RankBallot[source]
Given a ballot, if a candidate appears multiple times on a ballot, keep the first instance, and remove any further instances. Does not condense the ballot. Only works on ranking ballots, not score ballots.
- Parameters:
ballot (RankBallot) – Ballot to remove repeated candidates from.
- Returns:
Ballot with duplicate candidate(s) removed.
- Return type:
- Raises:
TypeError – Ballot must only have rankings, not scores.
TypeError – Ballot must have rankings.
- votekit.cleaning.remove_repeat_cands_rank_profile(profile: RankProfile, remove_empty_ballots: bool = True, remove_zero_weight_ballots: bool = True, retain_original_candidate_list: bool = True) CleanedRankProfile[source]
Given a profile, if a candidate appears multiple times on a ballot, keep the first instance and remove any further instances. Does not condense any empty rankings as as result. Only works on ranking ballots, not score ballots.
Wrapper for clean_rank_profile.
- Parameters:
profile (RankProfile) – Profile to remove repeated candidates from.
remove_empty_ballots (bool, optional) – Whether or not to remove ballots that have no ranking or scores as a result of cleaning. Defaults to True.
remove_zero_weight_ballots (bool, optional) – Whether or not to remove ballots that have no weight as a result of cleaning. Defaults to True.
retain_original_candidate_list (bool, optional) – Whether or not to use the candidate list from the original profile in the new profile. If False, uses only candidates who receive votes. Defaults to True.
- Returns:
A cleaned
RankProfile.- Return type:
- Raises:
ProfileError – Profile must only contain ranked ballots.
Matrices
- votekit.matrices.heatmap.matrix_heatmap(matrix: ndarray, *, ax: matplotlib.axes.Axes | None = None, show_cell_values: bool = True, n_decimals_to_display: int = 2, row_labels: List[str] | None = None, row_label_rotation: float | None = None, row_legend: dict[str, str] | None = None, column_labels: List[str] | None = None, column_label_rotation: float | None = None, column_legend: dict[str, str] | None = None, cell_color_map: str | matplotlib.colors.Colormap | None = None, cell_font_size: int | None = None, cell_spacing: float = 0.5, cell_divider_color: str = 'white', show_colorbar: bool = False, legend_font_size: float = 10.0, legend_location: str = 'center left', legend_bbox_to_anchor: Tuple[float, float] = (1.03, 0.5)) matplotlib.axes.Axes[source]
Basic function for plotting a matrix as a heatmap.
- Parameters:
matrix (np.ndarray) – A 2D numpy array containing the data to be plotted.
ax (matplotlib.axes.Axes, optional) – The matplotlib axis to plot on. Defaults to None, in which case an axis is created.
show_cell_values (bool) – Whether to show the values of the cells in the heatmap. These values are shown in the center of each cell and are dynamically formatted to be human-readable. Defaults to True.
n_decimals_to_display (int) – The number of decimal places to display for the values in the heatmap. Defaults to 2.
row_labels (Optional(List[str])) – A list of strings containing the labels for the rows of the heatmap. Defaults to None.
row_label_rotation (Optional(float)) – The rotation to apply to the row labels. Defaults to None.
row_legend (Optional(Dict[str, str])) – A dictionary mapping row labels to legend descriptions. Defaults to None.
column_labels (Optional(List[str])) – A list of strings containing the labels for the columns of the heatmap. Defaults to None.
column_label_rotation (Optional(float)) – The rotation to apply to the column labels. Defaults to None.
column_legend (Optional(Dict[str, str])) – A dictionary mapping column labels to legend descriptions. Defaults to None.
cell_color_map (Optional(Union[str, matplotlib.colors.Colormap])) – The color map to use for the heatmap. Defaults to PRGn if the matrix contains negative values and Greens otherwise.
cell_font_size (Optional(int)) – The font size to use for the cell values. Defaults to None, which will then use dynamic font size based on the number of cells and the figure size.
cell_spacing (float) – The spacing between the cells in the heatmap. Defaults to 0.5.
cell_divider_color (str) – The color to use for the cell dividers for spacing cells. Defaults to “white”.
show_colorbar (bool) – Whether to show the colorbar for the heatmap. Defaults to False.
legend_font_size (float) – The font size to use for the legend. Defaults to 10.0.
legend_location (str) – The location to place the legend. Defaults to “center left”.
legend_bbox_to_anchor (Tuple[float, float]) – The bounding box to anchor the legend to. Defaults to (1.03, 0.5).
- Returns:
The matplotlib axis containing the heatmap.
- Return type:
matplotlib.axes.Axes
- votekit.matrices.candidate.boost.boost_matrix(pref_profile: RankProfile, candidates: list[str]) ndarray[source]
Takes a profile and converts to a matrix where the i,j entry shows P(mention i | mention j) - P(mention i). Thus, the i,j entry shows the boost given to i by j. Computations use ballot weight. Non-symmetric matrix. Undefined entries are denoted with numpy.nan values.
- Parameters:
pref_profile (RankProfile) – Profile.
candidates (list[str]) – List of candidates to use. Indexing of this list matches indexing of output array.
- Returns:
Numpy array of boosts.
- Return type:
np.ndarray
- votekit.matrices.candidate.boost.boost_prob(i: str, j: str, pref_profile: RankProfile) Tuple[float, float][source]
Takes candidates i,j and a preference profile and computes the conditional P(mention i | mention j) and P(mention i). If candidate j is never mentioned, or if the profile has 0 total ballot weight, it returns numpy.nan for the respective probability.
- Parameters:
i (str) – Candidate.
j (str) – Candidate.
pref_profile (RankProfile) – Profile.
- Returns:
P(mention i | mention j), P(mention i)
- Return type:
tuple[float, float]
- votekit.matrices.candidate.candidate_distance.candidate_distance(i: str, j: str, ballot: RankBallot) float[source]
Takes candidates i,j and returns distance r(j)-r(i) in ranking. Returns numpy.nan if a candidate is not on ballot. Note that this is non-symmetric, and that a positive value indicates that i is ranked higher than j.
- Parameters:
i (str) – Candidate.
j (str) – Candidate.
ballot (RankBallot) – RankBallot.
- Returns:
Distance r(j)-r(i) in ranking.
- Return type:
float
- votekit.matrices.candidate.candidate_distance.candidate_distance_matrix(pref_profile: RankProfile, candidates: list[str]) ndarray[source]
Takes a preference profile and converts to a matrix where the i,j entry shows the average distance between i and j when i >= j on the same ballot. Computations use ballot weight. Non-symmetric. Uses numpy.nan for undefined entries.
- Parameters:
pref_profile (RankProfile) – Profile.
candidates (list[str]) – List of candidates to use. Indexing of this list matches indexing of output array.
- Returns:
Numpy array of average distances.
- Return type:
np.ndarray
- votekit.matrices.candidate.comentions.comention(cands: str | list[str], ballot: RankBallot)[source]
Takes cands and returns true if they all appear on the ballot in the ranking.
- Parameters:
cands (Union[str, list[str]]) – Candidate name or list of candidate names.
ballot (RankBallot) – RankBallot.
- Returns:
True if all candidates appear in ballot.
- Return type:
bool
- votekit.matrices.candidate.comentions.comention_above(i: str, j: str, ballot: RankBallot) bool[source]
Takes candidates i,j and returns True if i >= j in the ranking. Requires that the ballot has a ranking.
- Parameters:
i (str) – Candidate name.
j (str) – Candidate name.
ballot (RankBallot) – RankBallot.
- Returns:
True if both i and j appear in ballot and i >= j.
- Return type:
bool
- votekit.matrices.candidate.comentions.comentions_matrix(pref_profile: RankProfile, candidates: list[str], symmetric: bool = False) ndarray[source]
Takes a preference profile and converts to a matrix where the i,j entry shows the number of times candidates i,j were mentioned on the same ballot with i >= j. There is an option to make it symmetric so that the i,j entry is just the number of times candidates i and j were mentioned on the same ballot.
- Parameters:
pref_profile (RankProfile) – Profile.
candidates (list[str]) – List of candidates to use. Indexing of this list matches indexing of output array.
symmetric (bool, optional) – Whether or not to make the matrix symmetric. Defaults to False in which case the i,j entry is comentions where i >= j. True means the i,j entry is comentions of i,j.
- Returns:
Numpy array of comentions.
- Return type:
np.ndarray
Misc.
- votekit.elections.transfers.fractional_transfer(winner: str, fpv: float, ballots: tuple[RankBallot] | list[RankBallot], threshold: int) tuple[RankBallot, ...][source]
Calculates fractional transfer from winner, then removes winner from the list of ballots.
- Parameters:
winner (str) – Candidate to transfer votes from.
fpv (float) – Number of first place votes for winning candidate.
ballots (Union[tuple[RankBallot], list[RankBallot]]) – List of Ballot objects.
threshold (int) – Value required to be elected, used to calculate transfer value.
- Returns:
Modified ballots with transferred weights and the winning candidate removed.
- Return type:
tuple[Ballot,…]
- votekit.elections.transfers.random_transfer(winner: str, fpv: float, ballots: tuple[RankBallot] | list[RankBallot], threshold: int) tuple[RankBallot, ...][source]
Cambridge-style transfer where transfer ballots are selected randomly. All ballots must have integer weights.
- Parameters:
winner (str) – Candidate to transfer votes from.
fpv (float) – Number of first place votes for winning candidate.
ballots (Union[tuple[RankBallot], list[RankBallot]]) – List of Ballot objects.
threshold (int) – Value required to be elected, used to calculate transfer value.
- Returns:
Modified ballots with transferred weights and the winning candidate removed.
- Return type:
tuple[RankBallot,…]
- votekit.utils.add_missing_cands(profile: RankProfile) RankProfile[source]
Add any candidates from profile.candidates that are not listed on a ballot as tied in last place.
- Parameters:
profile (RankProfile) – Input profile.
- Returns:
RankProfile
- votekit.utils.ballot_lengths(profile: RankProfile) dict[int, float][source]
Compute the frequency of ballot lengths in the profile. Includes all lengths from 1 to
max_ranking_lengthas keys. Ballots must have rankings.- Parameters:
profile (RankProfile) – Profile to compute ballot lengths.
- Returns:
Dictionary of ballot length frequency.
- Return type:
dict[int, float]
- Raises:
TypeError – All ballots must have rankings.
- votekit.utils.ballots_by_first_cand(profile: RankProfile) dict[str, list[RankBallot]][source]
Partitions the profile by first place candidate. Assumes there are no ties within first place positions of ballots.
- Parameters:
profile (RankProfile) – Profile to partititon.
- Returns:
A dictionary whose keys are candidates and values are lists of ballots that have that candidate first.
- Return type:
dict[str, list[RankBallot]]
- votekit.utils.borda_scores(profile: RankProfile, borda_max: int | None = None, tie_convention: Literal['high', 'average', 'low'] = 'low') dict[str, float][source]
Calculates Borda scores for candidates_cast in a
RankProfile. The Borda vector is \((n,n-1,\dots,1)\) where \(n\) is the ``borda_max`.- Parameters:
profile (RankProfile) –
RankProfileof ballots.borda_max (int, optional) – The maximum value of the Borda vector. Defaults to the length of the longest allowable ballot in the profile.
tie_convention (Literal["high", "average", "low"], optional) – How to award points for tied rankings. Defaults to “low”, where any candidates tied receive the lowest possible points for their position, eg three people tied for 3rd would each receive the points for 5th. “high” awards the highest possible points, so in the previous example, they would each receive the points for 3rd. “average” averages the points, so they would each receive the points for 4th place.
- Returns:
Dictionary mapping candidates to Borda scores.
- Return type:
dict[str, float]
- votekit.utils.build_df_from_ballot_samples(ballots_freq_dict: dict[tuple[int, ...], int], candidates: Sequence[str])[source]
Helper function which creates a pandas df to instantiate a RankProfile :param ballots_freq_dict: dictionary mapping ballots to
sampled frequency. The keys should be in candidate id form
- Parameters:
candidates – list of candidates in the profile
- Returns:
pandas df
- votekit.utils.elect_cands_from_set_ranking(ranking: Sequence[frozenset[str] | set[str]], m: int, profile: RankProfile | None = None, tiebreak: str | None = None) tuple[tuple[frozenset[str], ...], tuple[frozenset[str], ...], tuple[frozenset[str], tuple[frozenset[str], ...]] | None][source]
Given a ranking, elect the top m candidates in the ranking. If a tie set overlaps the desired number of seats, it breaks the tie with the provided method or raises a ValueError if tiebreak is set to None. Returns a tuple of elected candidates, remaining candidates, and a tuple whose first entry is a tie set and whose second entry is the resolution of the tie.
- Parameters:
ranking (tuple[frozenset[str],...]) – A list-of-set ranking of candidates.
m (int) – Number of seats to elect.
profile (RankProfile, optional) – Profile used to break ties in first-place votes or Borda setting. Defaults to None, which implies a random tiebreak.
tiebreak (str, optional) – Method of tiebreak, currently supports ‘random’, ‘borda’, ‘first_place’. Defaults to None, which does not break ties.
- Returns:
- tuple[tuple[frozenset[str]]], list[tuple[frozenset[str]],
Optional[tuple[frozenset[str], tuple[frozenset[str], …]]]: A list-of-sets of elected candidates, a list-of-sets of remaining candidates, and a tuple whose first entry is a tie set and whose second entry is the resolution of the tie. If no ties were broken, the tuple returns None.
- votekit.utils.expand_tied_ballot(ballot: RankBallot) list[RankBallot][source]
Fix tie(s) in a ballot by returning all possible permutations of the tie(s), and divide the weight of the original ballot equally among the new ballots.
- Parameters:
ballot (RankBallot) – Ballot to expand tie sets on.
- Returns:
All possible permutations of the tie(s).
- Return type:
list[v]
- votekit.utils.first_place_votes(profile: RankProfile, tie_convention: Literal['high', 'average', 'low'] = 'average') dict[str, float][source]
Computes first place votes for all candidates_cast in a
RankProfile.- Parameters:
profile (RankProfile) – The profile to compute first place votes for.
tie_convention (Literal["high", "average", "low"], optional) – How to award points for tied first place votes. Defaults to “average”, where if n candidates are tied for first, each receives 1/n points. “high” would award them each one point, and “low” 0.
- Returns:
Dictionary mapping candidates to number of first place votes.
- Return type:
dict[str, float]
- votekit.utils.index_to_lexicographic_ballot(ballot_index: int, n_candidates: int, max_length: int, total_valid_ballots_method, always_use_total_valid_ballots_method: bool = True) list[int][source]
Convert an index to one ballot with candidates taken from the list range(n_candidates), and where the ballot has length at most max_length. The ordering of the ballots is lexicographic, i.e., the first ballot is the lexicographically smallest ballot and continues in that order:
(0,), (0,1), (0,1,2), … (0,2), (0,2,1), … (n-1, n-2, …, n-l)
where n is the number of candidates and l is the maximum ballot length.
- Parameters:
ballot_index (int) – The index to convert.
n_candidates (int) – The number of candidates.
max_length (int) – The maximum allowed ballot rank.
total_valid_ballots_method – ((n_candidates, max_length) -> integer) a method which returns the total number of allowed ballots.
always_use_total_valid_ballots_method (bool) – a flag indicating whether the given total valid ballots method should be used when computing b_n. If total_valid_ballots_method is using a cache then this should be True for maximum runtime efficiency.
- Returns:
A list representing the ballot corresponding to index.
- Return type:
list[int]
- votekit.utils.mentions(profile: RankProfile) dict[str, float][source]
Calculates total mentions for all candidates in a
RankProfile.- Parameters:
profile (RankProfile) – RankProfile of ballots.
- Returns:
Dictionary mapping candidates to mention totals (values).
- Return type:
dict[str, float]
- votekit.utils.resolve_profile_ties(profile: RankProfile) RankProfile[source]
Takes in a PeferenceProfile with potential ties in ballots. Replaces ballots with ties with fractionally weighted ballots corresponding to all permutations of the tied ranking.
- Parameters:
profile (RankProfile) – Input profile with potentially tied rankings.
- Returns:
A RankProfile with resolved ties.
- Return type:
- votekit.utils.score_dict_from_score_vector(profile: RankProfile, score_vector: Sequence[float], tie_convention: Literal['high', 'average', 'low'] = 'low') dict[str, float][source]
Score the candidates based on a score vector. For example, the vector (1,0,…) would return the first place votes for each candidate. Vectors should be non-increasing and non-negative. Vector should be as long as
max_ranking_lengthin the profile. If it is shorter, we add 0s. Candidates who are not mentioned in any ranking do not appear in the dictionary.- Parameters:
profile (RankProfile) – Profile to score.
score_vector (Sequence[float]) – Score vector. Should be non-increasing and non-negative. Vector should be as long as
max_ranking_lengthin the profile. If it is shorter, we add 0s.tie_convention (Literal["high", "average", "low"], optional) – How to award points for tied rankings. Defaults to “low”, where any candidates tied receive the lowest possible points for their position, eg three people tied for 3rd would each receive the points for 5th. “high” awards the highest possible points, so in the previous example, they would each receive the points for 3rd. “average” averages the points, so they would each receive the points for 4th place.
- Returns:
Dictionary mapping candidates to scores.
- Return type:
dict[str, float]
- votekit.utils.score_dict_to_ranking(score_dict: dict[str, float], sort_high_low: bool = True) tuple[frozenset[str], ...][source]
Sorts candidates into a tuple of frozensets ranking based on a scoring dictionary.
- Parameters:
score_dict (dict[str, float]) – Dictionary between candidates and their score.
sort_high_low (bool, optional) – How to sort candidates based on scores. True sorts from high to low. Defaults to True.
- Returns:
Candidate rankings in a list-of-sets form.
- Return type:
tuple[frozenset[str],…]
- votekit.utils.score_profile_from_ballot_scores(profile: ScoreProfile) dict[str, float][source]
Score the candidates based on the
scoresparameter of the ballots. All ballots must have ascoresparameter; note that ascoresdictionary with no non-zero scores will raise the same error.- Parameters:
profile (ScoreProfile) – Profile to score.
- Returns:
Dictionary mapping candidates to scores.
- Return type:
dict[str, float]
- votekit.utils.tiebreak_set(r_set: frozenset[str], profile: RankProfile | None = None, tiebreak: str = 'random', scoring_tie_convention: Literal['high', 'average', 'low'] = 'low', backup_tiebreak_convention: str | None = None) tuple[frozenset[str], ...][source]
Break a single set of candidates into multiple sets each with a single candidate according to a tiebreak rule. Rule 1: random. Rule 2: first-place votes; break the tie based on first-place votes in the profile. Rule 3: borda; break the tie based on Borda points in the profile. Rule 4: lex/lexicographic/alph/alphabetical; break the tie alphabetically.
- Parameters:
r_set (frozenset[str]) – Set of candidates on which to break tie.
profile (RankProfile, optional) – Profile used to break ties in first-place votes or Borda setting. Defaults to None, which implies a random tiebreak.
tiebreak (str) – Tiebreak method to use. Options are “random”, “first_place”, and “borda”. Defaults to “random”.
scoring_tie_convention (Literal["high", "average", "low"]) – How to award points for tied rankings. Defaults to “low”, where any candidates tied receive the lowest possible points for their position, eg three people tied for 3rd would each receive the points for 5th. “high” awards the highest possible points, so in the previous example, they would each receive the points for 3rd. “average” averages the points, so they would each receive the points for 4th place.
backup_tiebreak_convention (str, optional) – If the initial tiebreak does not resolve all ties, this convention is used to break any remaining ties. Options are “random” and “lex/lexicographic/alph/alphabetical”. Defaults to None which sets the backup to “lex” if the initial tiebreak is alphabetical, and “random” otherwise.
- Returns:
tiebroken ranking
- Return type:
tuple[frozenset[str],…]
- votekit.utils.tiebroken_ranking(ranking: tuple[frozenset[str], ...], profile: RankProfile | None = None, tiebreak: str = 'random') tuple[tuple[frozenset[str], ...], dict[frozenset[str], tuple[frozenset[str], ...]]][source]
Breaks ties in a list-of-sets ranking according to a given scheme.
- Parameters:
ranking (list[set[str]]) – A list-of-set ranking of candidates.
profile (RankProfile, optional) – Profile used to break ties in first-place votes or Borda setting. Defaults to None, which implies a random tiebreak.
tiebreak (str, optional) – Method of tiebreak, currently supports ‘random’, ‘borda’, ‘first_place’. Defaults to random.
- Returns:
The first entry of the tuple is a list-of-set ranking of candidates (broken down to one candidate sets). The second entry is a dictionary that maps tied sets to their resolution.
- Return type:
tuple[tuple[frozenset[str], …], dict[frozenset[str], tuple[frozenset[str],…]]]
- votekit.utils.validate_score_vector(score_vector: Sequence[float])[source]
Validator function for score vectors. Vectors should be non-increasing and non-negative.
- Parameters:
score_vector (Sequence[float]) – Score vector.
- Raises:
ValueError – If any score is negative.
ValueError – If score vector is increasing at any point.
- votekit.metrics.distances.compute_ranking_distance_on_ballot_graph(ranking1: Sequence[int], ranking2: Sequence[int], n_candidates: int)[source]
Computes the distance between two rankings on a ballot graph.
- Parameters:
ranking1 (Sequence[int]) – The first ranking as a sequence of candidate indices.
ranking2 (Sequence[int]) – The second ranking as a sequence of candidate indices.
n_candidates (int) – The number of candidates in the rankings.
- Returns:
The computed distance between the two rankings.
- Return type:
float
- votekit.metrics.distances.earth_mover_dist(pp1: RankProfile, pp2: RankProfile) float[source]
Computes the Earth Mover’s Distance (EMD) between two preference profiles. Assumes both elections share the same candidates.
- Parameters:
pp1 (RankProfile) – RankProfile for first profile.
pp2 (RankProfile) – RankProfile for second profile.
- Returns:
Earth Mover’s Distance between two profiles.
- Return type:
float
- votekit.metrics.distances.emd_via_scipy_linear_program(source_distribution: ndarray, target_distribution: ndarray, cost_matrix: ndarray) float[source]
Compute the Earth Mover’s Distance (EMD) between two discrete distributions using a linear programming formulation of the optimal transport problem.
- Classical Formulation:
minimize ⟨cost_matrix, transport_plan⟩ subject to:
transport_plan @ 1 = source_distribution transport_plan.T @ 1 = target_distribution transport_plan >= 0
- Linear Program:
Suppose that ‘a’ is the source distribution, ‘b’ is the target distribution, ‘C’ is the cost matrix, and ‘X’ is the transport plan. Let ‘x’ be the row-major vectorization of ‘X’ and let ‘c’ be the vectorization of ‘C’.
Then let ‘A’ be the constraint matrix formed by the Kronecker products of identity matrices and the ones vector, so
A = [I_n ⊗ 1_m^T, 1_n^T ⊗ I_m]
where ‘I_n’ is the identity matrix of size ‘n’ (number of sources) and ‘I_m’ is the identity matrix of size ‘m’ (number of targets). The linear program can be expressed as:
minimize c^T x
- subject to:
Ax = y
where ‘y’ is the concatenation of the source and target distributions ‘y = [a, b]^T’.
- Parameters:
source_distribution (np.ndarray) – Mass distribution of the source (length n).
target_distribution (np.ndarray) – Mass distribution of the target (length m).
cost_matrix (np.ndarray) – n×m matrix of transportation costs.
- Returns:
The computed Earth Mover’s Distance (minimum transport cost).
- Return type:
float
- votekit.metrics.distances.lp_dist(pp1: RankProfile, pp2: RankProfile, p_value: int | str | None = 1) int[source]
Computes the \(L_p\) distance between two profiles. Use ‘inf’ for infinity norm. Assumes both elections share the same candidates.
- Parameters:
pp1 (RankProfile) – RankProfile for first profile.
pp2 (RankProfile) – RankProfile for second profile.
p_value (Union[int, str], optional) – \(L_p\) distance parameter. Use “inf” for \(\infty\).
- Returns:
\(L_p\) distance between two profiles.
- Return type:
int
- votekit.metrics.distances.profiles_to_ndarrys(profiles: list[RankProfile])[source]
Converts a list of preference profiles into an ndarray. The columns represent each profile, rows are the cast ballots, and each element represents the frequency a ballot type occurs for a
RankProfile. Each column will sum to one since weights are standardized. This is useful for computing election \(L_p\) distances between profiles.- Parameters:
profiles (list[RankProfile]) – A list of PreferenceProfiles.
- Returns:
computed matrix of ballot frequencies.
- Return type:
numpy.ndarray