(pyvenv-workon 'pyramide)

L’idée est de reprendre la pyramide des âges et la moduler par:

  • Le % d’abstention par classe d’âge
  • Le % de vote LREM
  • Le % de vote Gauche
  • Le % de vote droite

Et en faire une jolie visualization.

"""
These data were downloaded from https://www.insee.fr/fr/statistiques/2381472#tableau-figure1
Key = age révolu (100 = 100 ans et plus)
Value = nombre de personnes dans la population française
"""
population = {
    0: 690942,
    1: 695063,
    2: 716123,
    3: 725576,
    4: 743039,
    5: 762367,
    6: 783332,
    7: 810097,
    8: 817631,
    9: 835242,
    10: 840895,
    11: 862319,
    12: 853243,
    13: 859175,
    14: 854278,
    15: 867238,
    16: 849665,
    17: 841314,
    18: 831528,
    19: 827807,
    20: 830697,
    21: 835200,
    22: 778873,
    23: 765236,
    24: 741535,
    25: 746399,
    26: 738131,
    27: 722662,
    28: 728320,
    29: 764166,
    30: 779572,
    31: 801165,
    32: 806948,
    33: 821127,
    34: 824250,
    35: 839830,
    36: 838306,
    37: 834328,
    38: 820145,
    39: 868806,
    40: 874869,
    41: 886274,
    42: 837272,
    43: 818115,
    44: 820176,
    45: 799456,
    46: 824241,
    47: 866161,
    48: 907462,
    49: 927759,
    50: 921723,
    51: 900060,
    52: 888235,
    53: 875245,
    54: 871895,
    55: 890989,
    56: 891608,
    57: 899644,
    58: 887307,
    59: 856255,
    60: 853667,
    61: 846060,
    62: 839655,
    63: 816587,
    64: 809514,
    65: 800032,
    66: 787325,
    67: 779454,
    68: 760616,
    69: 768507,
    70: 743139,
    71: 764252,
    72: 744985,
    73: 736777,
    74: 715221,
    75: 666821,
    76: 498019,
    77: 478997,
    78: 459971,
    79: 418516,
    80: 365621,
    81: 371202,
    82: 379585,
    83: 357369,
    84: 337938,
    85: 322009,
    86: 294853,
    87: 278596,
    88: 246130,
    89: 229535,
    90: 197481,
    91: 172622,
    92: 135469,
    93: 111515,
    94: 88537,
    95: 69657,
    96: 53102,
    97: 38627,
    98: 27946,
    99: 19134,
    100: 31037,
}
ages_limite = [24, 34, 49, 59, 69, 101]
participation = [.65, .66, .75, .78, .85, .89]
intentions = {
    "Mélenchon": [.13, .12, .10, .09, .07, .03],
    "Jadot": [.12, .09, .08, .06, .06, .04],
    "Macron": [.18, .19, .23, .22, .28, .33],
    "Pécresse": [.08, .09, .10, .13, .15, .28],
    "Le Pen": [.16, .19, .20, .20, .13, .08],
    "Zemmour": [.12, .14, .11, .14, .14, .13],
}
 
colors = {
    "Mélenchon": "#E85D75",
    "Jadot": "#B2C9AB",
    "Macron": "#748CAB",
    "Pécresse": "#748CAB",
    "Zemmour": "#080708",
    "Le Pen": "#292F36",
}
import bisect
import numpy as np
 
ages = list(population.keys())[18:]
 
def get_num_votes(population, ages_limite, intentions):
    num_votes = []
    for a in ages:
        idx = bisect.bisect_left(ages_limite, a)
        num_votes.append(int(population[a] * participation[idx] * intentions[idx]))
    return num_votes
 
participants = get_num_votes(population, ages_limite, participation)
votes = {name: get_num_votes(population, ages_limite, values) for name, values in  intentions.items()}
idx_median = {name: bisect.bisect_left(np.cumsum(values) / np.sum(values), 0.5) for name, values in votes.items()}
median = {name: ages[idx] for name, idx in idx_median.items()}
mean = {name: int(np.sum(np.array(ages) * values)/np.sum(values)) for name, values in votes.items()}
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
 
def add_title(ax, name, legend=""):
    ax.text(
        0.5,
        1.1,
        f"{name}",
        ha="center",
        va="bottom",
        fontname="Futura PT",
        fontsize=25,
        fontweight="bold",
    )
    ax.text(
        0.5,
        0.95,
        "Ce grqphique représente la distibution des âges des gens qui",
        ha="center",
        va="bottom",
        fontname="Futura PT",
        fontsize=10,
    )
    ax.axis("off")
 
def add_pyramide(ax, ages, num_votes, median_idx, color="blue"):
    ax.bar(
        ages,
        num_votes/np.sum(num_votes),
        width=1.0,
        align="edge",
        color=[color for _ in range(median_idx)] + ["black"] + [color for _ in range(len(ages)-median_idx-1)],
        ec="white",
    )
    #ax.invert_yaxis()
    ax.spines["left"].set_visible(False)
    ax.spines["right"].set_visible(False)
    ax.spines["top"].set_visible(False)

file:

fig = plt.figure(figsize=(12, 8))
gs = gridspec.GridSpec(2, 1, height_ratios = [.25,1], figure=fig)
 
ax = plt.subplot(gs[0, 0])
add_title(ax, "Candidat(e) des jeunes ?")
 
ax = plt.subplot(gs[1, 0])
pop = list(population.values())[18:]
ax.bar(
    ages,
    pop,
    width=1.0,
    align="edge",
    color="lightgray",
    ec="white",
)
num_votes = participants
ax.bar(
    ages,
    num_votes,
    width=1.0,
    align="edge",
    color="black",
    ec="white",
)
ax.invert_xaxis()
ax.spines["left"].set_visible(False)
ax.spines["right"].set_visible(False)
ax.spines["top"].set_visible(False)
 
gs.update(hspace=-0.1)
plt.savefig(filename, bbox_inches="tight")
filename

Regardons maintenant la différence entre les deux

idx_median = bisect.bisect_left(np.cumsum(pop) / np.sum(pop), 0.5)
ages[idx_median]
idx_median = bisect.bisect_left(np.cumsum(participants) / np.sum(participants), 0.5)
ages[idx_median]

TODO But would that change the election?

fig = plt.figure(figsize=(8, 8))
gs = gridspec.GridSpec(len(intentions)+1, 1, figure=fig)
 
sorted_names = [name for name, _ in sorted(median.items(), key=lambda item: item[1], reverse=True)]
ax = plt.subplot(gs[0, 0])
add_title(ax, "Candidat(e) des jeunes ?")
for i, name in enumerate(sorted_names):
    ax = plt.subplot(gs[i+1, 0])
    add_pyramide(ax, ages, votes[name], idx_median[name], "lightgray")
    ax.set_yticks([])
    ax.spines["bottom"].set_visible(False)
    if i != len(intentions)-1:
       ax.set_xticks([])
    else:
       ax.set_xticks([18, 30, 40, 50, 60, 70, 100])
 
gs.update(hspace=0.3)
plt.savefig(filename, bbox_inches="tight")
filename

Chaque fois que je vois passer des statistiques du vôte par âge, je me représente une population homogène. Alors qu’en fait la pyramide des âges introduit une déformation très importante dans la distribution des votes. Un changement de X% dans la catégorie des plus de 70 ans se traduit par une hausse de X points dans la population globale, alors que de y points si cette modification a lieu chez les 19-25 ans. Il devient alors plus intéressant pour un candidat en campagne d’aller grapiller des points chez les plus agés à cuase de cet effet démultiplicateur.

Est-il suffisant que tous les 19-25 ans aillent voter pour équilibrer ce multiplicateur? Je ne pense pas.

TODO Tracer la pyramide des âges des gens en âge de voter

TODO Tracer la distribution cumulative par âge

TODO Tracer la pyramide des personnes sûres de voter

On compare la pyramide des âges de la population en âge de voter avec la pyramide des âges des gens qui sont certains ou presque certains d’aller voter.

Il est courant de faire porter la responsabilité du poids électoral des personnes les plus âgées sur l’abstentionnisme des plus jeunes. Nous sommes cependant en droit de nous poser des questions lorsque l’on voit la pyramide des âges.

Il est heureusement assez simple de répondre à cette question: il suffit de comparer l’âge médian de l’électeur à l’âge médian dans la population en âge de voter.

TODO Superposer la cumlative sûrs de voter avec la cumulative des âges

TODO Tracer la pyramide des votes mélenchon, macron, lepen, jadot, pécresse, zemmour

Data

J