Démographie du Finistère

dimanche 26 décembre 2010, par jps29

Comme je travaille sur la période de l’entre-deux-guerres, et plus précisément du Front populaire, je m’intéresse à la démographie finistérienne. Pour appréhender les tendances sur le long terme, rien de mieux que de collecter l’ensemble des données, commune par commune, de 1800 à nos jours, par le biais des recensements.

Ce petit texte pour donner le déroulé des détails techniques de collecte et de traitement de l’information.

J’ai bricolé, ne sachant pas comment travailler avec des outils aussi puissants que cURL pour récupérer des données en automatisant les requêtes.

Pour accéder aux données, il est nécessaire de passer par

http://cassini.ehess.fr/cassini/fr/html/requetePopulation.php

J’ai entré la date de chaque recensement et indiqué une fourchette de population de 1 à 300000 pour avoir toutes les communes.

PNG - 61.5 ko
La recherche sur le site Cassini.

En cliquant sur "Télécharger", j’ai ainsi récupéré un fichier csv que j’ai pu travailler. Là où cela devient fastidieux, c’est qu’il faut le faire pour chaque recensement. Quelqu’un de plus doué en informatique pourrait faire ici un script pour récupérer automatiquement tous les résultats d’un coup en faisant une boucle.

Ce travail dépasse mes compétences et m’aurait obligé à passer plus de temps à concevoir le script qu’à récupérer "à la main les données".

Le recensement 2008 étant disponible, je l’ai récupéré pour le département sur le site de l’INSEE. C’est un fichier excel que j’ai intégré à la base de données, en le transformant au préalable en fichier .csv tout en ne conservant que les colonnes qui m’intéressaient, par une inclusion dans la table population et en lui attribuant un code id comme identifiant unique.

Pour citer l’INSEE : « Les populations légales millésimées 2008 entrent en vigueur le 1er janvier 2011. Elles ont été calculées conformément aux concepts définis dans le décret n° 2003-485 du 5 juin 2003. Leur date de référence statistique est le 1er janvier 2008. »

Une fois les données récupérées, je les ai intégré dans une base de données sqlite. Sqlite a l’avantage d’être léger et la base de données tient dans un seul fichier.

J’avais commencé à coller les différents résultats dans un tableur et j’aurai continué s’il n’y avait eu un obstacle majeur. La liste des communes évolue avec le temps, certaines disparaissent, d’autres se créent. Il est donc très long d’ajuster les lignes pour avoir une commune et une seule par ligne.

J’ai donc injecté les données de chaque recensement dans la table "population" qui a la structure suivante :

CREATE TABLE population (id INTEGER,insee INTEGER,ville TEXT,annee INTEGER,nb INTEGER)

J’ai ainsi 9243 données qui se présentent ainsi :

9238        29302        Quimerch                                1962                1125
9239        29302        Pont-de-Buis-lès-Quimerch        1968                3999
9240        29302        Pont-de-Buis-lès-Quimerch        1975                3916
9241        29302        Pont-de-Buis-lès-Quimerch        1982                3710
9242        29302        Pont-de-Buis-lès-Quimerch        1990                3373
9243        29302        Pont-de-Buis-lès-Quimerch        1999                3385

Le code INSEE est le même pour les commune qui n’existent plus et pour celles qui les remplacent. Une difficulté supplémentaire à résoudre. Il est donc nécessaire de donner des codes ayant la même logique : un code à 5 chiffres dont les deux premiers sont l’identifiant du département. Je suis parti de 29500 pour être sur de ne pas interférer avec les autres codes INSEE.

Code choisiCommune
Beuzec-Conq 29500
Ergué-Armel 29501
Kerfeunteun 29502
Kernével 29503
Lambézellec 29504
Lanriec 29505
Larret 29506
Logonna-Quimerch 29507
Penhars 29508
Ploaré 29509
Plouguer 29510
Ploujean 29511
Pouldavid 29512
Quimerch 29513
Rumengol 29514
Saint-Marc 29515
Saint-Pierre-Quilbignon 29516
Tréboul 29517

Une autre difficulté à résoudre aussi : le changement de nom des communes. Elles sont quelques unes dans ce cas pour le Finistère. En soi ce n’est pas gênant mais quand on lance des requêtes sur une table de données à partir du nom des communes, par exemple, le résultat n’est pas correcte. Donc, j’ai choisi arbitrairement un des deux noms, en général, le nom actuel. La liste qui suit :

Ancien nom Nom actuel Date changement

Etape suivante : il faut maintenant regrouper les communes. Jean-Yves, un collègues informaticien m’a concocté une recette SQL qui permet de le faire. Qu’il ait ici toute ma reconnaissance. Voici la requête qu’il a créé et que j’ai adapté à mes besoins, . Elle est sans doute perfectible mais m’a servi à économiser des heures de travail :

CREATE VIEW VillesCodeInsee AS select distinct(A.ville) as ville, (select max(c.insee)  from population c where c.ville=A.ville) as INSEE,(select B.nb from population B where b.ville=A.ville and B.[annee]=1800) as '1800',
(select B.nb from population B where b.ville=A.ville and B.[annee]=1806) as '1806',
(select B.nb from population B where b.ville=A.ville and B.[annee]=1821) as '1821',
(select B.nb from population B where b.ville=A.ville and B.[annee]=1831) as '1831',
(select B.nb from population B where b.ville=A.ville and B.[annee]=1836) as '1836',
(select B.nb from population B where b.ville=A.ville and B.[annee]=1841) as '1841',
(select B.nb from population B where b.ville=A.ville and B.[annee]=1846) as '1846',
(select B.nb from population B where b.ville=A.ville and B.[annee]=1851) as '1851',
(select B.nb from population B where b.ville=A.ville and B.[annee]=1856) as '1856',
(select B.nb from population B where b.ville=A.ville and B.[annee]=1861) as '1861',
(select B.nb from population B where b.ville=A.ville and B.[annee]=1872) as '1872',
(select B.nb from population B where b.ville=A.ville and B.[annee]=1876) as '1876',
(select B.nb from population B where b.ville=A.ville and B.[annee]=1881) as '1881',
(select B.nb from population B where b.ville=A.ville and B.[annee]=1886) as '1886',
(select B.nb from population B where b.ville=A.ville and B.[annee]=1891) as '1891',
(select B.nb from population B where b.ville=A.ville and B.[annee]=1896) as '1896',
(select B.nb from population B where b.ville=A.ville and B.[annee]=1901) as '1901',
(select B.nb from population B where b.ville=A.ville and B.[annee]=1906) as '1906',
(select B.nb from population B where b.ville=A.ville and B.[annee]=1911) as '1911',
(select B.nb from population B where b.ville=A.ville and B.[annee]=1921) as '1921',
(select B.nb from population B where b.ville=A.ville and B.[annee]=1926) as '1926',
(select B.nb from population B where b.ville=A.ville and B.[annee]=1931) as '1931',
(select B.nb from population B where b.ville=A.ville and B.[annee]=1936) as '1936',
(select B.nb from population B where b.ville=A.ville and B.[annee]=1946) as '1946',
(select B.nb from population B where b.ville=A.ville and B.[annee]=1954) as '1954',
(select B.nb from population B where b.ville=A.ville and B.[annee]=1962) as '1962',
(select B.nb from population B where b.ville=A.ville and B.[annee]=1968) as '1968',
(select B.nb from population B where b.ville=A.ville and B.[annee]=1975) as '1975',
(select B.nb from population B where b.ville=A.ville and B.[annee]=1982) as '1982',
(select B.nb from population B where b.ville=A.ville and B.[annee]=1990) as '1990',
(select B.nb from population B where b.ville=A.ville and B.[annee]=1999) as '1999',
(select B.nb from population B where b.ville=A.ville and B.[annee]=1999) as '2008'
from population A
order by 1

Il est nécessaire de créer des index (encore merci à Jean-Yves qui est venu de nouveau à mon secours) pour que la requête ne prenne pas plusieurs dizaines de minutes.

CREATE INDEX [ixannee] ON [population] ([annee]);
CREATE INDEX [ixville] ON [population] ([ville]);
CREATE INDEX [ixinsee] ON [population] ([INSEE]);
CREATE INDEX [ixannee2] ON [population] ([annee],[ville]);

Le résultat est le suivant :

VilleINSEEan_1800an_1806an_1821
Argol 29001 544 731 1013
Arzano 29002 3150 1757 1834
Audierne 29003 1017 965 1237
Bannalec 29004 4396 3165 4363
Baye 29005 400 347 -
Perguet 29006 529 565 579
Bénodet 29006 - - -
Berrien 29007 1693 1949 2039

Avec cette requête SQL, une vue (VIEW) a été créé dans la base sous forme d’une nouvelle table nommée "VillesCodeInsee". Il s’agit de récupérer les informations de cette table pour créer un graphique. C’est ce que le script permet de faire.

Le script :

library("ggplot2")
library("RSQLite")
 
setwd("/Users/JPS/Dropbox/")
# Se connecter à la base de données
connexion <- dbConnect(dbDriver("SQLite"), dbname="populationfinistere.sqlite")
# lister les tables de la base 
dbListTables(connexion) 
# Interroger la base
recensements <- dbGetQuery(connexion, "SELECT * FROM VillesInsee")
# Fermer la connection après usage
dbDisconnect(connexion)
# Indiquer le code INSEE de la commune recherchée. Il va faloir que je règle le sort des communes qui ont fusionné et qui ont le même code INSEE
numeroinsee <- 29080
identite.ville <- recensements[,1 :2]
# Fonction pour obtenir le nom de la commune à partir du code INSEE
nomville <- function(n)
	identite.ville <- recensements[,1 :2]
	resultat <- identite.ville$ville[identite.ville$INSEE==n]
	return(resultat)

# Construire le nom du fichier de sortie avec le nom de commune
fichier <- paste(nomville(numeroinsee),"-recensements.png",sep="")
png(file=fichier,width=800,height=400)
# Préparer le data.frame qui me sert pour construire la courbe
popu <- melt(recensements[recensements$INSEE==numeroinsee,-(1)])
head(popu)
recens <- c("1800","1806","1821","1831","1836","1841","1846","1851","1856","1861","1872","1876","1881","1886","1891","1896","1901","1906","1911","1921","1926","1931","1936","1946","1954","1962","1968","1975","1982","1990","1999","2008")
date <- c(1 :32)
# Générer le graphique
graphique <- ggplot(popu, aes(date,value[2 :33])) + 
	geom_line(col="red") + 
	scale_x_continuous("", breaks=1 :32, labels = (recens[1 :32])) + 
	geom_point() +
	labs(x="", y="") +
	opts(axis.text.x=theme_text(angle=67.5, hjust=1, col = "blue"), axis.text.y=theme_text(hjust=1, col = "blue")) +
	opts(title=nomville(numeroinsee))
graphique
dev.off()

Created by Pretty R at inside-R.org

Voici deux exemples de graphiques. Les courbes sont très dissemblables. Il faudra essayer, sur l’ensemble du département, de repérer des familles de courbes.Il serait intéressant de générer les courbes d’un même canton, cote à cote et automatiquement. A voir.

PNG - 38 ko
L’Hôpital-Camfrout
PNG - 39.8 ko
Laz

Maintenant je peux donc tracer les courbes de chacune des communes avec cependant un soucis (de taille) pas encore réglé : les communes qui ont fusionné ou qui se sont séparées et qui partagent le même code INSEE. Je vais être obligé d’attribuer un code factice à chaque commune disparue

Attaquons-nous ensuite aux boites à moustache.Je vais construire une série de boites à moustache, une par recensement. J’utilise également geom_gitter de ggplot qui permet d’afficher chaque commune par un point. J’ai réglé la transparence de ces points pour permettre la lecture des points et des boites à moustache.

Et c’est parti :

library("ggplot2")
library("gdata")
library("reshape")
library("gsubfn") # qui permet de remplacer des motifs dans une chaîne
library("RSQLite")
 
setwd("/Users/JPS/Dropbox/")
# Se connecter à la base de données
connexion <- dbConnect(dbDriver("SQLite"), dbname="populationfinistere.sqlite")
# lister les tables de la base
dbListTables(connexion)
# Interroger la base
recensements <- dbGetQuery(connexion, "SELECT * FROM VillesInsee")
# Fermer la connection après usage
dbDisconnect(connexion)
png(file = "BoxPlotRecensementsFinistere.png", width=900,height=600)
recensements <- recensements[,-(1  :2)]
debut <- 1
fin <- 32
 
ggplot(data=melt(as.data.frame(recensements[debut  :fin])), aes(gsub("annee","",variable), value)) +
	scale_y_log10() +  
	geom_boxplot(outlier.colour = "red", outlier.size = 2, alpha=.3, fill="red",colour="red") + 
	geom_jitter(outlier.colour = "blue", alpha=.1, outlier.size = 1/20) + 
	opts(axis.text.x=theme_text(angle=67.5, hjust=1, col = "blue"), axis.text.y=theme_text(hjust=1, col = "blue")) +
	labs(x="", y="") +
	geom_text(aes(1, 150000), label="Boite à moustache (boxplot) et nuage de points \nqui représente chaque commune pour chaque recensement.\nChaque commune est représentée par un point en grisé.", colour="black",size=4,hjust=0) +
	opts(legend.position = "none") +
	opts(title="Population du Finistère\n d’après les recensements")	
dev.off()

Created by Pretty R at inside-R.org

Voici le graphique :

PNG - 276.3 ko
Boite à moustache des recensements.

Il reste à interpréter le résultat.

Autre projet : faire une carte animée (un gif par exemple) qui montre de manière dynamique les évolutions de la population dans le département, sur une base communale. Mais auparavant, il faudra que je vérifie quand même la fiabilité des informations obtenues en les confrontant avec les chiffres de population conservés au archives départementales.

(A suivre ... )

Un message, un commentaire ?

modération a priori

Ce forum est modéré a priori : votre contribution n’apparaîtra qu’après avoir été validée par un administrateur du site.

Qui êtes-vous ?
Votre message