Quality criteria API

Yee diagrams

Create and plot Yee diagrams outlining single-winner voting system quality.

Yee diagrams distribute some candidates in a 2D issue space and then evaluate a selected voting system on a grid over that space. In each cell of the grid, an election is simulated with voter preferences proportional to the distances of the grid cell to the candidate positions. Use diagram() to produce this.

A good voting system’s Yee diagram should closely approximate a Voronoi diagram over the candidates. (A Voronoi diagram would assign each point of space to the closest candidate.) 1 This can be produced by calling voronoi().

The Yee diagram here is represented by a 2D list as a rectangular lattice covering the 0-1 in both dimensions.

1

Warren D. Smith. “Yee Pictures”, Range Voting, 2007. https://rangevoting.org/IEVS/Pictures.html

votelib.crit.yee.bounded_sampler(samp)

Bound a vote sampler to the Yee diagram bounding box.

Return type

BoundedSampler

votelib.crit.yee.circular_candidates(n, r=0.25, center=(0.5, 0.5))

Generate Yee diagram candidate issue space positions in a circle.

Parameters
  • n (int) – Number of candidates. The candidates will be evenly spaced along the circumference of the circle.

  • r (float) – Radius of the circle.

  • center (Tuple[float, float]) – Center of the circle coordinates.

Return type

Dict[Union[str, CandidateObject], Tuple[float, float]]

votelib.crit.yee.diagram(evaluator, candidates, shape=(200, 200), n_votes=1000, random_state=None, **kwargs)

Produce a Yee diagram for the evaluator.

Any superfluous keyword arguments are passed on to the vote generation sampler using sampler().

Parameters
  • evaluator (Selector) – The voting system evaluator for which to construct a Yee diagram.

  • candidates (Dict[Union[str, CandidateObject], Tuple[float, float]]) – Candidate positions in the 2D issue space. The coordinates should both be between 0 and 1.

  • shape (Tuple[int, int]) – Number of cells along each dimension of the issue space. Enlarging this gives more detail but increases computing time.

  • n_votes (int) – Number of voters to consider in each simulated election. Lowering this will speed up the computation but may give unstable results.

  • random_state (Optional[int]) – Seed for the vote generator.

Return type

List[List[Union[str, CandidateObject]]]

votelib.crit.yee.plot(results, candidates, cmap='tab10', ax=None)

Plot the Yee diagram.

Requires Matplotlib. Plots the Yee diagram cells and candidate positions on the current/chosen axes and adds a legend. You normally need to follow up on this with the show() call to show the figure.

Parameters
  • results (List[List[Union[str, CandidateObject]]]) – The Yee diagram to plot.

  • candidates (Dict[Union[str, CandidateObject], Tuple[float, float]]) – Candidate positions in the 2D issue space. The coordinates should both be between 0 and 1.

  • cmap (str) – Colormap to use for plotting. The default is sufficient for up to 10 candidates unambiguously. References the Matplotlib colormap register.

  • ax – Axes to plot on.

Return type

None

votelib.crit.yee.random_candidates(n, cand_sampler=None)

Generate Yee diagram candidate issue space positions randomly.

Parameters
  • n (int) – Number of candidates.

  • cand_sampler (Optional[Sampler]) – A sampler to generate the candidate positions. The default (None) is to sample from a uniform 2D distribution, i.e. all points of the diagram are equally probable.

Return type

Dict[Union[str, CandidateObject], Tuple[float, …]]

votelib.crit.yee.sampler(x, y, sigma=(0.25, 0.25))

Create a vote generation sampler for a given Yee issue space point.

Gives a Gaussian sampler centered on the x-y point with a standard deviation given by sigma.

Return type

BoundedSampler

votelib.crit.yee.voronoi(candidates, shape=(200, 200))

Produce a Voronoi Yee diagram for the given candidates.

This gives the ideal Yee diagram that good voting systems should be close to.

Parameters
  • candidates (Dict[Union[str, CandidateObject], Tuple[float, float]]) – Candidate positions in the 2D issue space. The coordinates should both be between 0 and 1.

  • shape (Tuple[int, int]) – Number of cells along each dimension of the issue space. Enlarging this gives more detail but increases computing time.

Return type

List[List[Union[str, CandidateObject]]]

votelib.crit.yee.voronoi_conformity(results, candidates)

Calculate the percentage of how a Yee diagram matches a Voronoi diagram.

Parameters
  • results (List[List[Union[str, CandidateObject]]]) – A Yee diagram of winning candidates.

  • candidates (Dict[Union[str, CandidateObject], Tuple[float, float]]) – Candidate positions in the 2D issue space. The coordinates should both be between 0 and 1.

Return type

float

votelib.crit.yee.voronoi_matches(results, candidates)

Give a 2D boolean mask how a Yee diagram matches a Voronoi diagram.

Parameters
  • results (List[List[Union[str, CandidateObject]]]) – A Yee diagram of winning candidates.

  • candidates (Dict[Union[str, CandidateObject], Tuple[float, float]]) – Candidate positions in the 2D issue space. The coordinates should both be between 0 and 1.

Return type

List[List[bool]]

Election result proportionality measurements

Measure proportionality of election results.

These functions evaluate how proportionally the seats are allocated to parties according to their votes received. For a review of such indicators, see 2 or 3.

The functions only accept votes in simple format. To evaluate disproportionality for elections using other vote types, you must use an appropriate converter first; however, using the index for those election systems might not be meaningful.

The seat counts must be in a dictionary format as returned by votelib’s distributors.

2

“polrep: Calculate Political Representation Scores”, Didier Ruedin. https://rdrr.io/rforge/polrep/

3(1,2,3,4,5,6,7)

“Measures of disproportionality”, Kalogirou. http://www2.stat-athens.aueb.gr/~jpan/diatrives/Kalogirou/chapter5.pdf

votelib.crit.proportionality.d_hondt(votes, results)

Compute the D’Hondt index of disproportionality. 3

This is the index of disproportionality minimized by the D’Hondt highest averages evaluator. It uses the maximum ratio of seats to votes across parties.

Parameters
  • votes (Dict[Union[str, CandidateObject], Number]) – Numbers of votes for each candidate.

  • results (Dict[Union[str, CandidateObject], Number]) – Seat counts awarded to each candidate.

Return type

float

votelib.crit.proportionality.gallagher(votes, results)

Compute the Gallagher index of election result disproportionality.

The Gallagher (LSq) index 4 expresses the mismatch between the fraction of votes received and seats allocated for each candidate or party. The index ranges from zero (no disproportionality) to 1 (total disproportionality). Compared to the Loosemore–Hanby index, it highlights large deviations rather than small ones.

Parameters
  • votes (Dict[Union[str, CandidateObject], Number]) – Numbers of votes for each candidate.

  • results (Dict[Union[str, CandidateObject], Number]) – Seat counts awarded to each candidate.

4

“Gallagher index”, Wikipedia. https://en.wikipedia.org/wiki/Gallagher_index

Return type

float

votelib.crit.proportionality.lijphart(votes, results)

Compute the Lijphart’s index of disproportionality. 3

Lijphart’s index takes the single largest difference between vote and seat fractions.

Parameters
  • votes (Dict[Union[str, CandidateObject], Number]) – Numbers of votes for each candidate.

  • results (Dict[Union[str, CandidateObject], Number]) – Seat counts awarded to each candidate.

Return type

float

votelib.crit.proportionality.loosemore_hanby(votes, results)

Compute the Loosemore–Hanby index of election result disproportionality.

The Loosemore–Hanby (LH) index 5 expresses the mismatch between the fraction of votes received and seats allocated for each candidate or party. The index ranges from zero (no disproportionality) to 1 (total disproportionality). Compared to the Gallagher index, it does not diminish the effect of smaller deviations.

Parameters
  • votes (Dict[Union[str, CandidateObject], Number]) – Numbers of votes for each candidate.

  • results (Dict[Union[str, CandidateObject], Number]) – Seat counts awarded to each candidate.

5

“Loosemore–Hanby index”, Wikipedia. https://en.wikipedia.org/wiki/Loosemore%E2%80%93Hanby_index

Return type

float

votelib.crit.proportionality.rae(votes, results)

Compute Rae’s index of disproportionality. 3

Rae’s index is the earliest known disproportionality measure. It is known to underestimate disproportionality in the presence of small parties.

Parameters
  • votes (Dict[Union[str, CandidateObject], Number]) – Numbers of votes for each candidate.

  • results (Dict[Union[str, CandidateObject], Number]) – Seat counts awarded to each candidate.

Return type

float

votelib.crit.proportionality.regression(votes, results)

Compute the regression index of disproportionality. 3

This is obtained by performing linear regression to predict seat fractions from vote fractions. If the index is one, the allocation is perfectly proportional; values below one signal preference of the system for smaller parties, while values above one signal preference for larger parties.

Parameters
  • votes (Dict[Union[str, CandidateObject], Number]) – Numbers of votes for each candidate.

  • results (Dict[Union[str, CandidateObject], Number]) – Seat counts awarded to each candidate.

Return type

float

votelib.crit.proportionality.rose(votes, results)

Compute the Rose disproportionality index (inverse LH). 3

This is an inverted version of the Loosemore-Hanby index which ranges from 1 (no disproportionality) to 0 (total disproportionality).

Parameters
  • votes (Dict[Union[str, CandidateObject], Number]) – Numbers of votes for each candidate.

  • results (Dict[Union[str, CandidateObject], Number]) – Seat counts awarded to each candidate.

Return type

float

votelib.crit.proportionality.sainte_lague(votes, results)

Compute the Sainte-Laguë index of disproportionality. 3

Sainte-Laguë index takes fractional differences.

Parameters
  • votes (Dict[Union[str, CandidateObject], Number]) – Numbers of votes for each candidate.

  • results (Dict[Union[str, CandidateObject], Number]) – Seat counts awarded to each candidate.

Return type

float