Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Greedy Visualisations (+ Address MES Feedback) #23

Merged
merged 16 commits into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 48 additions & 1 deletion docs-source/source/usage/outcomevisualisation.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,51 @@
Outcome Visualisation
=====================

To be done.
For reference, see the module :py:mod:`~pabutools.visualisation`.

We provide the visualisation for the outcomes of :py:func:`~pabutools.rules.greedywelfare.greedy_utilitarian_welfare` and :py:func:`~pabutools.rules.mes.method_of_equal_shares`. This explains in depth the outcome of the election based on the chosen rule. This includes which projects were selected or rejected, summary statistics about the election, and rule specific information such as effective vote count in :py:func:`~pabutools.rules.mes.method_of_equal_shares`. The chart libraries we use are ZingChart and Google Developer Charts, and the visualisations are saved as HTML files.

Note that selecting the visualisation option will increase the runtime of the election, however without this option, the runtime will remain the same.

Greedy Utilitarian Welfare
--------------------------

The visualisation for the Greedy Utilitarian Welfare currently works only on additive utility functions.

We provide a way to visualise the results using the class :py:class:`~pabutools.visualisation.GreedyWelfareVisualiser`. Note the analytics flag in the function :py:func:`~pabutools.rules.greedywelfare.greedy_utilitarian_welfare` must be set to True to generate the visualisation.

.. code-block:: python

from pabutools.visualisation import GreedyWelfareVisualiser
from pabutools.rules.greedywelfare import greedy_utilitarian_welfare
from pabutools import election
from pabutools.election import Cost_Sat

instance, profile = election.parse_pabulib("./{path_to_election_file}.pb")
outcome = greedy_utilitarian_welfare(instance, profile, sat_class=Cost_Sat, analytics=True)

visualiser = GreedyWelfareVisualiser(profile, instance, outcome.details)
visualiser.render("./{path_to_output_file}/")

The visualisation will be saved in the specified path as a standalone HTML file called round_analysis.html.

Note that the visualisation is only available for additive utility functions.

Method of Equal Shares
----------------------

We provide a way to visualise the results using the class :py:class:`~pabutools.visualisation.MESVisualiser`. Note the analytics flag in the function :py:func:`~pabutools.rules.mes.method_of_equal_shares` must be set to True to generate the visualisation. The visualisations for MES consist of two pages: one for the summary of the election, containing the allocation of the budget, information about all the elected projects, and summary statistics about the election as a whole. The second page contains the details of the election, giving statistics about each round of the election, including the selected project, and how each round impacts the effective vote count of others. This captures the essence of the method of equal shares, where the effective vote count of each project is updated after each round.

.. code-block:: python

from pabutools.visualisation import MESVisualiser
from pabutools.rules.mes import method_of_equal_shares
from pabutools import election

instance, profile = election.parse_pabulib("./{path_to_election_file}.pb")
outcome = method_of_equal_shares(instance, profile, analytics=True)

visualiser = MESVisualiser(profile, instance, outcome.details)
visualiser.render("./{path_to_output_file}/")

The visualisations will be saved with the filenames summary.html and round_analysis.html respectively in the specified path. These work as standalone HTML files, and must be stored in the same directory to ensure the links between different pages work correctly.
94 changes: 61 additions & 33 deletions docs/_modules/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<!DOCTYPE html>


<html lang="en" data-theme="light">
<html lang="en" data-content_root="../" data-theme="light">

<head>
<meta charset="utf-8" />
Expand All @@ -17,27 +17,28 @@
</script>

<!-- Loaded before other Sphinx assets -->
<link href="../_static/styles/theme.css?digest=e353d410970836974a52" rel="stylesheet" />
<link href="../_static/styles/bootstrap.css?digest=e353d410970836974a52" rel="stylesheet" />
<link href="../_static/styles/pydata-sphinx-theme.css?digest=e353d410970836974a52" rel="stylesheet" />
<link href="../_static/styles/theme.css?digest=8d27b9dea8ad943066ae" rel="stylesheet" />
<link href="../_static/styles/bootstrap.css?digest=8d27b9dea8ad943066ae" rel="stylesheet" />
<link href="../_static/styles/pydata-sphinx-theme.css?digest=8d27b9dea8ad943066ae" rel="stylesheet" />


<link href="../_static/vendor/fontawesome/6.1.2/css/all.min.css?digest=e353d410970836974a52" rel="stylesheet" />
<link rel="preload" as="font" type="font/woff2" crossorigin href="../_static/vendor/fontawesome/6.1.2/webfonts/fa-solid-900.woff2" />
<link rel="preload" as="font" type="font/woff2" crossorigin href="../_static/vendor/fontawesome/6.1.2/webfonts/fa-brands-400.woff2" />
<link rel="preload" as="font" type="font/woff2" crossorigin href="../_static/vendor/fontawesome/6.1.2/webfonts/fa-regular-400.woff2" />
<link href="../_static/vendor/fontawesome/6.5.1/css/all.min.css?digest=8d27b9dea8ad943066ae" rel="stylesheet" />
<link rel="preload" as="font" type="font/woff2" crossorigin href="../_static/vendor/fontawesome/6.5.1/webfonts/fa-solid-900.woff2" />
<link rel="preload" as="font" type="font/woff2" crossorigin href="../_static/vendor/fontawesome/6.5.1/webfonts/fa-brands-400.woff2" />
<link rel="preload" as="font" type="font/woff2" crossorigin href="../_static/vendor/fontawesome/6.5.1/webfonts/fa-regular-400.woff2" />

<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=b76e3c8a" />
<link rel="stylesheet" href="../_static/styles/sphinx-book-theme.css?digest=14f4ca6b54d191a8c7657f6c759bf11a5fb86285" type="text/css" />
<link rel="stylesheet" type="text/css" href="../_static/styles/sphinx-book-theme.css?v=384b581d" />

<!-- Pre-loaded scripts that we'll load fully later -->
<link rel="preload" as="script" href="../_static/scripts/bootstrap.js?digest=e353d410970836974a52" />
<link rel="preload" as="script" href="../_static/scripts/pydata-sphinx-theme.js?digest=e353d410970836974a52" />
<link rel="preload" as="script" href="../_static/scripts/bootstrap.js?digest=8d27b9dea8ad943066ae" />
<link rel="preload" as="script" href="../_static/scripts/pydata-sphinx-theme.js?digest=8d27b9dea8ad943066ae" />
<script src="../_static/vendor/fontawesome/6.5.1/js/all.min.js?digest=8d27b9dea8ad943066ae"></script>

<script src="../_static/documentation_options.js?v=951a251d"></script>
<script src="../_static/documentation_options.js?v=2bf2fbde"></script>
<script src="../_static/doctools.js?v=888ff710"></script>
<script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
<script src="../_static/scripts/sphinx-book-theme.js?digest=5a5c038af52cf7bc1a1ec88eea08e6366ee68824"></script>
<script src="../_static/scripts/sphinx-book-theme.js?v=efea14e4"></script>
<script>DOCUMENTATION_OPTIONS.pagename = '_modules/index';</script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
Expand All @@ -50,7 +51,15 @@



<a class="skip-link" href="#main-content">Skip to main content</a>
<a id="pst-skip-link" class="skip-link" href="#main-content">Skip to main content</a>

<div id="pst-scroll-pixel-helper"></div>

<button type="button" class="btn rounded-pill" id="pst-back-to-top">
<i class="fa-solid fa-arrow-up"></i>
Back to top
</button>


<input type="checkbox"
class="sidebar-toggle"
Expand Down Expand Up @@ -85,12 +94,17 @@
</form></div>
</div>

<nav class="bd-header navbar navbar-expand-lg bd-navbar">
</nav>
<header class="bd-header navbar navbar-expand-lg bd-navbar">
</header>


<div class="bd-container">
<div class="bd-container__inner bd-page-width">





<div class="bd-sidebar-primary bd-sidebar">


Expand All @@ -104,6 +118,7 @@

<div class="sidebar-primary-items__start sidebar-primary__section">
<div class="sidebar-primary-item">



<a class="navbar-brand logo" href="../index.html">
Expand All @@ -112,10 +127,22 @@




<p class="title logo__title">Pabutools</p>

</a></div>
<div class="sidebar-primary-item"><nav class="bd-links" id="bd-docs-nav" aria-label="Main">
<div class="sidebar-primary-item">

<script>
document.write(`
<button class="btn navbar-btn search-button-field search-button__button" title="Search" aria-label="Search" data-bs-placement="bottom" data-bs-toggle="tooltip">
<i class="fa-solid fa-magnifying-glass"></i>
<span class="search-button__default-text">Search</span>
<span class="search-button__kbd-shortcut"><kbd class="kbd-shortcut__modifier">Ctrl</kbd>+<kbd class="kbd-shortcut__modifier">K</kbd></span>
</button>
`);
</script></div>
<div class="sidebar-primary-item"><nav class="bd-links bd-docs-nav" aria-label="Main">
<div class="bd-toc-item navbar-nav active">
<ul class="nav bd-sidenav">
<li class="toctree-l1"><a class="reference internal" href="../index.html">Pabutools</a></li>
Expand Down Expand Up @@ -221,20 +248,22 @@
</button>



<script>
document.write(`
<button class="theme-switch-button btn btn-sm btn-outline-primary navbar-btn rounded-circle" title="light/dark" aria-label="light/dark" data-bs-placement="bottom" data-bs-toggle="tooltip">
<span class="theme-switch" data-mode="light"><i class="fa-solid fa-sun"></i></span>
<span class="theme-switch" data-mode="dark"><i class="fa-solid fa-moon"></i></span>
<span class="theme-switch" data-mode="auto"><i class="fa-solid fa-circle-half-stroke"></i></span>
<button class="btn btn-sm navbar-btn theme-switch-button" title="light/dark" aria-label="light/dark" data-bs-placement="bottom" data-bs-toggle="tooltip">
<span class="theme-switch nav-link" data-mode="light"><i class="fa-solid fa-sun fa-lg"></i></span>
<span class="theme-switch nav-link" data-mode="dark"><i class="fa-solid fa-moon fa-lg"></i></span>
<span class="theme-switch nav-link" data-mode="auto"><i class="fa-solid fa-circle-half-stroke fa-lg"></i></span>
</button>
`);
</script>


<script>
document.write(`
<button class="btn btn-sm navbar-btn search-button search-button__button" title="Search" aria-label="Search" data-bs-placement="bottom" data-bs-toggle="tooltip">
<i class="fa-solid fa-magnifying-glass"></i>
<i class="fa-solid fa-magnifying-glass fa-lg"></i>
</button>
`);
</script>
Expand All @@ -261,7 +290,7 @@ <h1></h1>


<div id="searchbox"></div>
<article class="bd-article" role="main">
<article class="bd-article">

<h1>All modules for which code is available</h1>
<ul><li><a href="pabutools/analysis/category.html">pabutools.analysis.category</a></li>
Expand Down Expand Up @@ -291,7 +320,7 @@ <h1>All modules for which code is available</h1>
<li><a href="pabutools/rules/budgetallocation.html">pabutools.rules.budgetallocation</a></li>
<li><a href="pabutools/rules/composition.html">pabutools.rules.composition</a></li>
<li><a href="pabutools/rules/exhaustion.html">pabutools.rules.exhaustion</a></li>
<li><a href="pabutools/rules/greedywelfare.html">pabutools.rules.greedywelfare</a></li>
<li><a href="pabutools/rules/greedywelfare/greedywelfare_rule.html">pabutools.rules.greedywelfare.greedywelfare_rule</a></li>
<li><a href="pabutools/rules/maxwelfare.html">pabutools.rules.maxwelfare</a></li>
<li><a href="pabutools/rules/mes/mes_details.html">pabutools.rules.mes.mes_details</a></li>
<li><a href="pabutools/rules/mes/mes_rule.html">pabutools.rules.mes.mes_rule</a></li>
Expand All @@ -305,22 +334,20 @@ <h1>All modules for which code is available</h1>



<footer class="bd-footer-article">


<footer class="prev-next-footer">

<div class="footer-article-items footer-article__inner">

<div class="footer-article-item"><!-- Previous / next buttons -->
<div class="prev-next-area">
</div></div>

</div>

</footer>

</div>



<div class="bd-sidebar-secondary bd-toc"></div>


</div>
<footer class="bd-footer-content">
Expand All @@ -337,6 +364,7 @@ <h1>All modules for which code is available</h1>

<div class="footer-item">


<p class="copyright">

© Copyright 2023, Simon Rey, Grzegorz Pierczyński, Markus Utke and Piotr Skowron.
Expand All @@ -363,8 +391,8 @@ <h1>All modules for which code is available</h1>
</div>

<!-- Scripts loaded after <body> so the DOM is not blocked -->
<script src="../_static/scripts/bootstrap.js?digest=e353d410970836974a52"></script>
<script src="../_static/scripts/pydata-sphinx-theme.js?digest=e353d410970836974a52"></script>
<script src="../_static/scripts/bootstrap.js?digest=8d27b9dea8ad943066ae"></script>
<script src="../_static/scripts/pydata-sphinx-theme.js?digest=8d27b9dea8ad943066ae"></script>

<footer class="bd-footer">
</footer>
Expand Down
Loading
Loading