Skip to main content

Political elections, appointment, analysis and visualization in Python

Project description

    rtd ci codecov pyversions pypi pypistatus license coc codestyle colab

    Political elections, appointment, analysis and visualization in Python

    poli-sci-kit is a Python package for political science appointment and election analysis. The goal is to provide a comprehensive tool for all methods needed to analyze and simulate election results. See the documentation for a full outline of the package including algorithms and visualization techniques.

    Contents

    Installation

    poli-sci-kit can be downloaded from PyPI via pip or sourced directly from this repository:

    pip install poli-sci-kit
    
    git clone https://github.com/andrewtavis/poli-sci-kit.git
    cd poli-sci-kit
    python setup.py install
    
    import poli_sci_kit
    

    Appointment

    appointment.methods includes functions to allocate parliamentary seats based on population or vote shares. Included methods are:

    Largest Remainder: Hare, Droop, Hagenbach–Bischoff (incl Hamilton, Vinton, Hare–Niemeyer)

    Highest Averages: Jefferson, Webster, Huntington-Hill

    Arguments to allow allocation thresholds, minimum allocations per group, tie break conditions, and other election features are also provided. Along with deriving results for visualization and reporting, these functions allow the user to analyze outcomes given systematic or situational changes. The appointment.metrics module further provides diagnostics to analyze the results of elections, apportionments, and other political science scenarios.

    A basic example of political appointment using poli-sci-kit is:

    from poli_sci_kit import appointment
    
    vote_counts = [2700, 900, 3300, 1300, 2150, 500]
    seats_to_allocate = 50
    
    # Huntington-Hill is the method used to allocate House of Representatives seats to US states
    ha_allocations = appointment.methods.highest_averages(
        averaging_style="Huntington-Hill",
        shares=vote_counts,
        total_alloc=seats_to_allocate,
        alloc_threshold=None,
        min_alloc=1,
        tie_break="majority",
        majority_bonus=False,
        modifier=None,
    )
    
    ha_allocations
    # [26, 9, 37, 12, 23, 5]
    

    We can then compute various metrics to derive disproportionality:

    # The Gallagher method is a measure of absolute difference similar to summing square residuals
    disproportionality = appointment.metrics.dispr_index(
        shares=vote_counts,
        allocations=ha_allocations,
        metric_type='Gallagher'
    )
    
    disproportionality
    # 0.01002
    

    We can also check that the allocations pass the quota condition:

    passes_qc = appointment.checks.quota_condition(
        shares=vote_counts,
        seats=ha_allocations
    )
    
    passes_qc
    # True
    

    Allocation consistency can further be checked using dataframes of shares and seats given electoral settings. See appointment.checks and the documentation for explanations of method checks.

    Plotting

    poli-sci-kit provides Python only implementations of common electoral plots.

    Visualizing the above results:

    import matplotlib.pyplot as plt
    import poli_sci_kit
    
    # German political parties
    parties = ['CDU/CSU', 'FDP', 'Greens', 'Die Linke', 'SPD', 'AfD']
    party_colors = ['#000000', '#ffed00', '#64a12d', '#be3075', '#eb001f', '#009ee0']
    

    Parliament Plots

    poli_sci_kit provides implementations of both rectangular and semicircle parliament plots:

    fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2)
    
    ax1 = poli_sci_kit.plot.parliament(
        allocations=seat_allocations,
        labels=parties,
        colors=party_colors,
        style="rectangle",
        num_rows=4,
        marker_size=300,
        speaker=True,
        axis=ax1,
    )
    
    ax2 = poli_sci_kit.plot.parliament(
        allocations=seat_allocations,
        labels=parties,
        colors=party_colors,
        style="semicircle",
        num_rows=4,
        marker_size=175,
        speaker=False,
        axis=ax2,
    )
    
    plt.show()
    

    Disproportionality Bar Plot

    A novel addition to social science analysis is the disproportionality bar plot, which graphically depicts the disproportionality between expected and realized results. Bar widths are the proportion of shares (ex: votes received), and heights are the difference or relative difference between shares and allocations (ex: parliament seats received).

    An example follows:

    import pltviz
    
    ax = poli_sci_kit.plot.dispr_bar(
        shares=votes,
        allocations=ha_allocations,
        labels=parties,
        colors=party_colors,
        total_shares=None,
        total_alloc=None,
        percent=True,
        axis=None,
    )
    
    handles, labels = pltviz.plot.legend.gen_elements(
        counts=[round(v / sum(votes), 4) for v in votes],
        labels=parties,
        colors=party_colors,
        size=11,
        marker="o",
        padding_indexes=None,
        order=None,
    )
    
    ax.legend(
        handles=handles,
        labels=labels,
        title="Vote Percents (bar widths)",
        title_fontsize=15,
        fontsize=11,
        ncol=2,
        loc="upper left",
        bbox_to_anchor=(0, 1),
        frameon=True,
        facecolor="#FFFFFF",
        framealpha=1,
    )
    
    ax.axes.set_title('Seat to Vote Share Disproportionality', fontsize=30)
    ax.set_xlabel('Parties', fontsize=20)
    ax.set_ylabel('Percent Shift', fontsize=20)
    
    plt.show()
    

    Examples

    Examples in poli-sci-kit use publicly available Wikidata statistics sourced via the Python package wikirepo. Current examples include:

    • US HoR (Open in Colab)

      • Allocates seats to a version of the US House of Representatives that includes all US territories and Washington DC given census data, with this further being used to derive relative vote strengths of state citizens in the US presidential election
    • Global Parliament (Open in Colab)

      • Analyzes the allocation of seats in a hypothetical global parliament given the prevalence of certain countries and organizations, the distribution of seats based on Freedom House indexes, as well as disproportionality metrics

    To-Do

    Please see the contribution guidelines if you are interested in contributing to this project. Work that is in progress or could be implemented includes:

    • Adding the Adams method to appointment.methods.highest_averages (see issue)

    • Deriving further needed arguments to assure that all current and historic appointment systems can be simulated using poli-sci-kit (see issue)

    • Potentially indexing preset versions of appointment.methods that coincide with the systems used by governments around the world

      • This would allow quick comparisons of actual systems with variations
    • Adding methods such as quadratic voting to poli-sci-kit to allow for preference based simulations

    • Creating, improving and sharing examples

    • Improving tests for greater code coverage

    References

    Full list of references

    Project details


    Download files

    Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

    Source Distributions

    No source distribution files available for this release.See tutorial on generating distribution archives.

    Built Distribution

    poli_sci_kit-1.1.0-py3-none-any.whl (27.9 kB view details)

    Uploaded Python 3

    File details

    Details for the file poli_sci_kit-1.1.0-py3-none-any.whl.

    File metadata

    • Download URL: poli_sci_kit-1.1.0-py3-none-any.whl
    • Upload date:
    • Size: 27.9 kB
    • Tags: Python 3
    • Uploaded using Trusted Publishing? No
    • Uploaded via: twine/4.0.2 CPython/3.10.13

    File hashes

    Hashes for poli_sci_kit-1.1.0-py3-none-any.whl
    Algorithm Hash digest
    SHA256 e48023436a68e05e2a909f3c64417ab57355ec2709e658971f99df73a0764481
    MD5 c569ae1d52af619fff2bf2652b2fb23c
    BLAKE2b-256 7224367230f200c281fb3335eaa6618fc43fb1070a70d4f096938df3b9d2309d

    See more details on using hashes here.

    Supported by

    AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page