Git Product home page Git Product logo

poli-sci-kit's Introduction

    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

    poli-sci-kit's People

    Contributors

    andrewtavis avatar dependabot[bot] avatar gnegrelli avatar imgbotapp avatar

    Stargazers

     avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

    Watchers

     avatar  avatar

    poli-sci-kit's Issues

    Add equations to appointment.methods docstrings

    Equations should be added to the doc strings of largest_remainder and highest_average in poli_sci_kit.appointment.methods. They would then be rendered in the documentation for greater clarity.

    Most of these equations can be found on the Wikipedia pages for the respective methods. They should be placed in the options section of the quota_style and averaging_style parameters respectively.

    Add equations to appointment.metrics docstrings

    This issue is for adding LaTeX equations to the docstrings of all functions found in poli_sci_kit.appointment.metrics. The style should be similar to those found in poli_sci_kit.appointment.methods.

    The following is an explanation for how to write LaTeX in docstrings:

    1. In conf.py of the documentation you need the extension sphinx.ext.imgmath, which allows equations to be rendered to pngs (this has been added to poli-sci-kit's conf.py)
    2. If you want to add an equation, then as seen in the docstrings for appointment.methods you add the following:
    .. math::
        LaTeX you want rendered
    
    1. The docstring also needs to be converted to an r-sting (this is now the case for largest_remainder and highest_averages)
    2. You also need to use &= instead of = in equations

    This LaTeX editor could be used to test equations and then add them to the docstrings (remembering &= instead of =). I would be more than happy to help if one of the equations doesn't make sense, or if getting the LaTeX to work is a bit confusing :)

    Thanks for your interest in contributing!

    Create concise requirement and env files

    This issue is for creating concise versions of requirements.txt and environment.yml for poli-sci-kit. It would be great if these files were created by hand with specific version numbers or generated in a way so that sub-dependencies don't always need to be updated.

    As of now both files are being created with the following commands in the package's conda virtual environment:

    pip list --format=freeze > requirements.txt  
    conda env export --no-builds | grep -v "^prefix: " > environment.yml

    poli-sci-kit and other obviously unneeded packages are then removed from these files before being uploaded.

    Any insights or help would be much appreciated!

    Negative value on `seats_per_row`

    While testing some allocation cases for #20, I came across the following error.

    ValueError: Number of samples, -1, must be non-negative.
    

    Digging deeper, I noticed that one of the values in the seats_per_row was negative.

    Test case that replicates the error:

    parliament(allocations=[2, 2, 8], num_rows=4)

    New appointment arguments

    Please use this issue to suggest new arguments for poli-sci-kit.appointment.methods functions if you know of a style of appointment variable that is not yet implemented. These new arguments can then be converted into good first issues that would include the necessary codes for implementation and testing.

    Thanks for your interest in contributing!

    Recommend Projects

    • React photo React

      A declarative, efficient, and flexible JavaScript library for building user interfaces.

    • Vue.js photo Vue.js

      🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

    • Typescript photo Typescript

      TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

    • TensorFlow photo TensorFlow

      An Open Source Machine Learning Framework for Everyone

    • Django photo Django

      The Web framework for perfectionists with deadlines.

    • D3 photo D3

      Bring data to life with SVG, Canvas and HTML. 📊📈🎉

    Recommend Topics

    • javascript

      JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

    • web

      Some thing interesting about web. New door for the world.

    • server

      A server is a program made to process requests and deliver data to clients.

    • Machine learning

      Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

    • Game

      Some thing interesting about game, make everyone happy.

    Recommend Org

    • Facebook photo Facebook

      We are working to build community through open source technology. NB: members must have two-factor auth.

    • Microsoft photo Microsoft

      Open source projects and samples from Microsoft.

    • Google photo Google

      Google ❤️ Open Source for everyone.

    • D3 photo D3

      Data-Driven Documents codes.