<jupyter_start><jupyter_text>Table of Contents1&nbsp;&nbsp;Data2&nbsp;&nbsp;Plotting Standards2.1&nbsp;&nbsp;Bar Plot2.2&nbsp;&nbsp;Semi Pie Plot2.3&nbsp;&nbsp;Pie Plot2.4&nbsp;&nbsp;Comparative Line Plot **plot**This notebook provides examples for most functions found in the plotting modules of [pltviz](https://github.com/andrewtavis/pltviz/tree/main/pltviz).The setting is a hypothetical election in Germany for the Bundestag (German national parliament).This notebook can also be opened in [Google Colab](https://colab.research.google.com/github/andrewtavis/pltviz/blob/main/examples/plot.ipynb).<jupyter_code># pip install pltviz
import pandas as pd

import pltviz
from pltviz import utils
from poli_sci_kit import utils as psk_utils
from poli_sci_kit import appointment

import matplotlib.pyplot as plt
from matplotlib.lines import Line2D # for legend handles
import seaborn as sns
sns.set(style="darkgrid")
sns.set(rc={'figure.figsize':(15,5)})

from IPython.core.display import display, HTML
display(HTML("<style>.container { width:99% !important; }</style>"))<jupyter_output><empty_output><jupyter_text>Data We're using German political parties for this example. The following are their abbreviations and colors:<jupyter_code>parties = ['CDU/CSU', 'FDP', 'Greens', 'Die Linke', 'SPD', 'AfD']
party_colors = ['#000000', '#ffed00', '#64a12d', '#be3075', '#eb001f', '#009ee0']
sns.palplot(sns.color_palette(party_colors))<jupyter_output><empty_output><jupyter_text>Assume that Germany had an election that lead to the following Bundestag allocations:<jupyter_code>allocations = [26, 9, 37, 12, 23, 5]<jupyter_output><empty_output><jupyter_text>Plotting Standards  Bar Plot Combines techniques from pandas and seaborn.<jupyter_code>ax = pltviz.bar(
    counts=allocations,
    labels=parties,
    colors=party_colors,
    horizontal=False,
    stacked=False,
    label_bars=True,
)

# Initialize empty handles and labels
handles, labels = pltviz.legend.gen_elements()

# Add a majority line
ax.axhline(int(sum(allocations) / 2) + 1, ls="--", color="black")
handles.insert(0, Line2D([0], [0], linestyle="--", color="black"))
labels.insert(0, "Majority: {} seats".format(int(sum(allocations) / 2) + 1))

ax.legend(
    handles=handles,
    labels=labels,
    title="Bundestag: {} seats".format(sum(allocations)),
    bbox_to_anchor=(0.3, 0.9),
    title_fontsize=20,
    fontsize=15,
    ncol=2,
    loc="best",
    frameon=True,
    facecolor="#ffffff",
    framealpha=1,
)

ax.set_ylabel("Seats", fontsize=15)
ax.set_xlabel("Party", fontsize=15)

plt.show()<jupyter_output><empty_output><jupyter_text>Now say we want to make government factions and plot them:<jupyter_code>factions = [[3, 5, 1, 0], [4, 2]]
factioned_allocations = psk_utils.gen_faction_groups(
    original_list=allocations, factions_indexes=factions
)
factioned_allocations<jupyter_output><empty_output><jupyter_text>We need flat and ordered versions of the above for the labels:<jupyter_code>flat_allocations= [item for sublist in factioned_allocations for item in sublist]
flat_allocations
flat_factions = [item for sublist in factions for item in sublist]

parties_by_faction = [parties[i] for i in flat_factions]
parties_by_faction
colors_by_faction = [party_colors[i] for i in flat_factions]
sns.palplot(sns.color_palette(colors_by_faction))
faction_labels = ['Opposition', 'Government']<jupyter_output><empty_output><jupyter_text>Let's combine all of the above for a horizontal stacked bar plot, which is as simple as changing the corresponding boolean arguments:<jupyter_code>ax = pltviz.bar(
    counts=factioned_allocations,
    labels=parties_by_faction,
    faction_labels=faction_labels,
    colors=colors_by_faction,
    horizontal=True,
    stacked=True,
    label_bars=True,
    axis=None,
)

handles, labels = pltviz.legend.gen_elements(
    counts=allocations,
    labels=parties,
    colors=party_colors,
    size=12,
    marker="o",
    padding_indexes=[3],
    order=[2, 4, 0, 1, 5, 3],
)

# Add a majority line
ax.axvline(int(sum(flat_allocations) / 2) + 1, ls="--", color="black")
handles.insert(0, Line2D([0], [0], linestyle="--", color="black"))
labels.insert(0, "Majority: {}".format(int(sum(flat_allocations) / 2) + 1))

# Reset shifted ticks
ax.set_yticks([0.25, 1.25])
ax.set_yticklabels(faction_labels, fontsize=15)

leg = ax.legend(
    handles=handles,
    labels=labels,
    title="Seats per Faction: {} total".format(sum(flat_allocations)),
    bbox_to_anchor=(1, 1),
    title_fontsize=20,
    fontsize=15,
    ncol=2,
    loc="best",
    frameon=True,
    facecolor="#ffffff",
    framealpha=1,
)

ax.set_ylabel("Faction", fontsize=20)
ax.set_xlabel("Seats Allocated", fontsize=20)

plt.show()<jupyter_output><empty_output><jupyter_text>Semi Pie Plot Uses matplotlib artists to create a semi circle pie plot.<jupyter_code>ax = pltviz.semipie(counts=allocations, colors=party_colors, donut_ratio=0.5)

handles, labels = pltviz.legend.gen_elements(
    counts=allocations,
    labels=parties,
    colors=party_colors,
)

ax.legend(
    handles=handles,
    labels=labels,
    title="Bundestag: {} seats".format(sum(allocations)),
    title_fontsize=20,
    fontsize=14,
    ncol=2,
    loc="center",
    bbox_to_anchor=(0.5, 0.17),
    frameon=False,
    facecolor="#ffffff",
    framealpha=1,
)

plt.show()<jupyter_output><empty_output><jupyter_text>Pie Plot Allows for seamless additions of factions as an outer ring that are further colored to depict coalitions.**Note:** the factions version is a work in progress. It needs the outer ring colors to not be an even spectrum such that there is a transition that's centered at the inner ring color boundary. The lines separating the spectrum elements also need to be removed.We'll use this to show axis plotting as well:<jupyter_code>fig, (ax1, ax2) = plt.subplots(
    nrows=1, ncols=2, sharey=False, sharex=False, figsize=(22, 9)
)

ax1 = pltviz.pie(
    counts=allocations,
    labels=parties,
    faction_labels=None,
    colors=party_colors,
    radius=1.25,
    outer_ring_density=400,
    donut_ratio=0.35,
    display_labels=True,
    display_counts=True,
    label_font_size=20,
    axis=ax1,
)

ax2 = pltviz.pie(
    counts=factioned_allocations,
    labels=parties_by_faction,
    faction_labels=["Opposition", "Government"],
    colors=colors_by_faction,
    radius=1,
    outer_ring_density=400,
    donut_ratio=0.35,
    display_labels=True,
    display_counts=True,
    label_font_size=20,
    axis=ax2,
)

handles = pltviz.legend.gen_handles(colors=colors_by_faction, size=12, marker="o")
labels = [
    "{}: {}".format(parties_by_faction[i], a)
    for i, a in enumerate(flat_allocations)
]

ax2.legend(
    handles=handles,
    labels=labels,
    title="Seats per Faction ({} total)".format(sum(flat_allocations)),
    ncol=2,
    loc="center",
    fontsize=12,
    title_fontsize=15,
    frameon=False,
    facecolor="#ffffff",
    framealpha=1,
)

plt.show()<jupyter_output><empty_output><jupyter_text>Comparative Line Plot Allows for easy comparisons of statistics across time or hypothetical situations.We'll generate a random vote allocation based on our original seat allocations, then assign new seats given a differing amount of total seats to be allocated. Afterwards we'll see how the makeup of the Bundestag would change given a differing number of total seats:<jupyter_code>votes = [2700, 900, 3300, 1300, 2150, 500]
seat_limits = list(range(50, 95+1, 5))
seat_limits[:5]<jupyter_output><empty_output><jupyter_text>We'll use the Huntington-Hill method of appointment, which is the method used in the United States to allocate seats in the House of Representatives to states:<jupyter_code>allocations_by_limit = pd.DataFrame()
allocations_by_limit["parties"] = parties
allocations_by_limit["votes"] = votes

for limit in seat_limits:
    allocations_by_limit.loc[:, "{}_seats".format(limit)] = pd.Series(
        appointment.methods.highest_average(
            averaging_style="Huntington-Hill",
            shares=votes,
            total_alloc=limit,
            min_alloc=1,
        ),
        index=range(len(allocations_by_limit)),
    )
allocations_by_limit
compare_cols = list(allocations_by_limit.columns.difference(['parties', 'votes']))
compare_cols[:5]
ax = pltviz.comp_line(
    df=allocations_by_limit,
    dependent_cols=compare_cols,
    indep_stats=seat_limits,
    colors=party_colors,
    stacked=False,
    percent=False,
)

handles = pltviz.legend.gen_handles(colors=party_colors, size=10, marker="o")
labels = [
    "{}: {}".format(
        allocations_by_limit.loc[i, "parties"], allocations_by_limit.loc[i, "votes"]
    )
    for i in allocations_by_limit.index
]

ax.legend(
    handles=handles,
    labels=labels,
    title="Votes per Group",
    bbox_to_anchor=(0, 1),
    ncol=2,
    loc="upper left",
    fontsize=10,
    title_fontsize=15,
    frameon=True,
    facecolor="#ffffff",
    framealpha=1,
)

ax.axes.set_title("Seats Allocated Given Total Seat Limit", fontsize=25)
ax.set_xlabel("Seat Limits", fontsize=15)
ax.set_ylabel("Allocations", fontsize=15)  # label based on percent_change

plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12062937062937062, 'fraction_numerical': 0.0236013986013986, 'mean_word_length': 5.147078576225655, 'pattern_counts': {'":': 0, '<': 47, '<?xml version=': 0, '>': 47, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '11', 'dir': 'jupyter-structured-clean-dedup', 'id': '481598', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 3367, 'n_tokens_neox': 3181, 'n_words': 707, 'path': 'examples/plot.ipynb', 'repo_name': 'andrewtavis/stdviz', 'size': '9152'}