PROJET AUTOBLOG


blog'o'm0le

source: blog'o'm0le

⇐ retour index

Mise à jour

Mise à jour de la base de données, veuillez patienter...

Nono's Songs : Slim Smith & The Uniques - My Conversation

jeudi 24 octobre 2013 à 11:36

Les Nono's Songs n'ont pas de but particulier si ce n'est de publier des musiques que j'apprécie.

Je ne donne aucune appréciation, je poste que des musiques, trouvées au détour du Net, ou d'un son/bruit que j'ai pu entendre quelques part ou avec quelqu'un. Ce n'est en aucun cas un signe de "nouveauté" ou un effet de mode quelconque.

Voici le non clip de Slim Smith & The Uniques qui nous propose My Conversation


Autopsie d'une dataviz [3] : une carte en anamorphose avec champs de sélection

dimanche 20 octobre 2013 à 16:35

Retour complet sur la création d'une carte par anamorphose, bien utile pour accentuer les valeurs extrêmes de données.

carte_anamorphose

Ça faisait un moment que je voulais faire un long article sur la relation entre abstention et vote FN aux élections présidentielles. Loin de moi l'idée de prouver une relation de cause à effet. On ne le répétera jamais assez : corrélation n'est pas causalité.

Je trouvais simplement assez étrange que l'on fasse des caisses à longueur de temps sur les électeurs FN, et qu'on ne produise à côté de ça que de courtes références sur les abstentionnistes, qui sont pourtant bien plus nombreux dans le scrutin présidentiel.

Une carte me paraissait être une illustration très appropriée pour comparer les deux, et surtout des foyers d'abstentionnistes ou d'électeurs FN étalés dans le temps ou non.

A la recherche du meilleur type de cartes

Quand on se lance dans de la cartographie de données très basique, on est souvent tenté par les cartes choroplèthes, comme celle que vous trouverez ci-dessous :

Le gros avantage de ce type de cartes est qu'il est très facilement compréhensible par le lecteur.

Quel que soit le paramètre considéré (qualité de l'air, production de poireaux ou vote écologiste), on devine aisément que les zones les plus foncées sont celles où le paramètre est le plus élevé.

Le vrai problème pour moi était d'ordre technique : je ne savais pas comment faire pour rassembler des jeux de données différents sur une même carte (par type d'électeurs et par année), bien que j'aie pu tomber sur l'un ou l'autre exemple avec des cases à cocher/décocher.

Mais rien qui m'inspire plus que ça, jusqu'à ce que...

Les cartogrammes passent par là...

J'ai fini par tomber un peu par hasard sur des cartogrammes.

Pour résumer grossièrement, un des algorithmes les plus rencontrés pour créer ce type de cartes consiste à appliquer une force sur des polygones, calculée notamment à partir de l'aire "absolue" du polygone et d'une valeur rattachée.

Avec cet algo, les zones géographiques ne se contentent plus d'être colorées, elles sont concrètement déformées par les valeurs que l'on souhaite comparer. Les zones les plus "hautes" sont très enflées, tandis que les plus "basses" sont comme aspirées.

Première piste

J'ai voulu essayer de créer un cartogramme avec les voix de l'abstention et avec celles du FN sur plusieurs présidentielles, et commencé à chercher des outils qui me permettent de le faire.

La première méthode que j'ai testée consistait à :

Plusieurs difficultés sont vite manifestées, dont :

J'ai gardé l'idée d'un cartogramme avec ces deux types de données dans un coin avant de voir le travail diablement efficace d'Etienne Côme avec la France du Bon Coin.

Dans ses sources, il cite un exemple états-unien qui a la particularité d'utiliser un double champ de sélection (un pour les années, un pour le type de données). Tiens tiens :-)...

La recette

Pour arriver à ce résultat qui permet d'animer une carte anamorphosée par différentes données contenues dans un même .csv (miam miam !), il faut utiliser quatre librairies JS :

En réalité, on peut gruger la partie TopoJSON en utilisant mapshaper. Cet outil permet en deux temps trois mouvements de convertir des fichiers .shp ou .geojson en .topojson et, cerise sur le gâteau, d'appliquer une simplification comme dans l'illustration suivante :

simplification_poly_

 Ensuite, il faut que le fichier .csv soit correctement paramétré pour que le passage par les champs de sélection se fasse sans heurt.

Dans cet exemple, toutes les colonnes possèdent les trois premières lettre du paramètre suivies de l'année (par exemple ABS2002). Evidemment, rien n'empêche d'imaginer glisser plus de paramètres ou plus d'années, le principe sera strictement le même.

Attention tout de même !

Les plus observateur auront peut-être remarqué dans le lien précédent des id très différentes de nos codes départementaux. C'est une des joyeusetés à côté desquelles je suis passé à côté au début : bien distinguer les id des polygones d'une colonne "id".

Pour essayer d'être plus clair, observons cette capture d'écran des polygones départementaux piochés sur ce stock de données (cliquez pour agrandir) :

qgis_id

En réalité, les id qui nous intéressent sont dans la colonne tout à gauche (0 pour la Somme, 1 pour l'Eure, 2 pour la Seine-Maritime, etc...) et un id égal à 0 peut poser problème pour la suite.

Différentes techniques existent pour un peu modifier le fichier .topojson, perso j'ai un peu fait flamber jEdit pour corriger tout ça et modifier mon .csv en conséquence. Bref, ça prend un peu de temps, mais une fois que c'est fait le fichier peut être réutilisé à l'envie.

Et dernier point avant de rentrer dans le code : D3 interprète mal le double point en valeur de séparation pour un .csv, il vaut mieux de fait utiliser la virgule. Un remerciement spécial à Etienne Côme qui a repéré l'erreur ;-) !

Le code

Rentrons dans le vif du sujet avec le code en lui-même. Voici pour commencer les éléments du <body> qui vont permettre d'afficher la carte et de naviguer entre les données :

<form>
        <p>
          <label>Choisissez le facteur de déformation <select id="field"></select></label>
          <label>pendant la présidentielle de <select id="year"></select></label>
          <span id="status"></span>
        </p>
   </form>

      <div id="container">
      <svg id="map"></svg>
      </div>

Voici enfin le script qui paramètre tout ça :

<script>

      // cache le formulaire si l'explorateur ne fait pas du SVG
      if (!document.createElementNS) {
        document.getElementsByTagName("form")[0].style.display = "none";
      }

/* déclaration des premières variables, notamment celles des champs de sélection
les différentes "key" doivent correspondre aux colonnes du CSV 
(%d s'adaptera à la valeur de #year) */ 
      var percent = (function() {
            var fmt = d3.format(".2f");
            return function(n) { return fmt(n) + "%"; };
          })(),
            fields = [
            {name: "Aucun", id: "none"},
            {name: "Abstention", id: "abs", key: "ABS%d", format: percent},
             {name: "Vote FN", id: "fn", key: "FN%d", format: percent},
          ],
          years = [2012, 2007,2002,1995], 
           fieldsById = d3.nest()
            .key(function(d) { return d.id; })
            .rollup(function(d) { return d[0]; })
            .map(fields),
          field = fields[0],
          year = years[0],
          colorsFN = colorbrewer.Greys[8];
          var colorFN = d3.scale.quantize().range(colorsFN).domain([0,25]);

          colorsAbs = colorbrewer.Reds[8];
          var colorAbs = d3.scale.quantize().range(colorsAbs).domain([0,45]);

           var body = d3.select("body");

// paramètre la navigation dans le champ #field
         var fieldSelect = d3.select("#field")
        .on("change", function(e) {
          field = fields[this.selectedIndex];
          update();
        });

      fieldSelect.selectAll("option")
        .data(fields)
        .enter()
        .append("option")
          .attr("value", function(d) { return d.id; })
          .text(function(d) { return d.name; });

// paramètre de la même manière la nav' dans le champ #year

      var yearSelect = d3.select("#year")
        .on("change", function(e) {
          year = years[this.selectedIndex]; 
          update();
        });

      yearSelect.selectAll("option")
        .data(years)
        .enter()
        .append("option")
          .attr("value", function(y) { return y; })
          .text(function(y) { return y; })

// déclaration de la carte

       var map = d3.select("#map"),
          zoom = d3.behavior.zoom()
          .translate([-38, 32])
           .scale(.94)
           .scaleExtent([0.5, 10.0])
           .on("zoom", updateZoom),
          layer = map.append("g")
            .attr("id", "layer"),
          states = layer.append("g")
            .attr("id", "states")
            .selectAll("path");

      updateZoom();

      function updateZoom() {
        var scale = zoom.scale();
        layer.attr("transform",
          "translate(" + zoom.translate() + ") " +
          "scale(" + [scale, scale] + ")");
      }

// on passe à la déclaration de la projection et du cartogramme, notamment

      var projection = d3.geo.albers().origin([8.5, 45.7]).scale(2600).parallels([40, 52]),
       topology,
          geometries,
          rawData,
          dataById = {},
          carto = d3.cartogram()
            .projection(projection)
            .properties(function(d) {
              var c= dataById[d.id];

              return dataById[d.id];
            })
            .value(function(d) {
              return +d.properties[field.key.replace("%d",year)];
            });

// on charge les polygones et les données

d3.json("dpts_fr_topo.json", function(topo) {
        topology = topo;
        geometries = topology.objects.layer1.geometries;
      d3.csv("presidentielle_fn_abstention_final.csv", function(data) {
          rawData = data;	
          dataById = d3.nest()
            .key(function(d) { return d.id; })
	    .rollup(function(d) { return d[0]; })
            .map(data);
          init();
             });
});  

// on initialise la carte via les variables précédentes

   function init() {
        var features = carto.features(topology, geometries),
            path = d3.geo.path()
              .projection(projection);

        states = states.data(features)
          .enter()
          .append("path")
            .attr("class", "state")
           /* .attr("id", function(d) {
              return d.properties.id;
            }) */ 
            .attr("fill", "#fafafa")
            .attr("d", path);

       states.append("title");
update();
      }
// et on met à jour à chaque changement dans un champ de sélection

    function update() {
	if(field.key!=undefined){
        body.classed("updating", true);

          var key = field.key.replace("%d",year);
          var fmt = (typeof field.format === "function")
              ? field.format
              : d3.format(field.format || ","),
            value = function(d) {
            if(d.properties != undefined){
			      return +d.properties[key];
		        }else{ return NaN};
            };

            var values = states.data().map(value)
              .filter(function(n) {
                return !isNaN(n);
              })
              .sort(d3.ascending);

            lo = values[0],
            hi = values[values.length - 1];

        // normalise l'échelle en nombre positif
        var scale = d3.scale.linear()
          .domain([lo, hi])
          .range([1, 1000]);

        // dit au cartogramme d'utiliser les valeurs échelonnées
        carto.value(function(d) {
          return scale(value(d));
        });

        // génère les nouvelles caractéristiques, pré projetées
        var features = carto(topology, geometries).features;
        // met à jour les données
        states.data(features)
          .select("title")
            .text(function(d) {
              if(d.properties != undefined){
              return [d.properties.NAME, fmt(value(d))].join(": ");
              }
            });

        states.transition()
          .duration(750)
          .ease("linear")
          .attr("fill", function(d) {
		if(field.id=="fn"){
            	return colorFN(value(d))
		}else{
            	return colorAbs(value(d))
		}
          })
          .attr("d", carto.path);

        body.classed("updating", false);

	}else{
	        var features = carto.features(topology, geometries);
	        // met à jour les données
        	states.data(features)
            path = d3.geo.path()
              .projection(projection);
        states.transition()
          .duration(750)
          .ease("linear")
          .attr("fill","#fafafa")
          .attr("d", path);

	}
}

    </script>

 Pour aller plus loin

J'ai publié l'ensemble des fichiers utilisés pour cette carte sur gitHub

Nono's Vrac 99

jeudi 3 octobre 2013 à 15:10

Pfiioouuu, 99 Nono's Vracs ! Ça en fait des liens et des liens sélectionnés amoureusement pour vous :D

Lukas-Farlan-Photography-13

En attendant le 100ième (le temps de réfléchir à la suite), je vous laisse avec cette liste de lien du 01/09/2013 au 30/09/2013 :

Photo

---------

Les Nono's Vrac sont généré depuis mon petit hook de l'application shaarli, que j'utilise ici : shaarli.m0le.net

Comment l'abstention peut aider le FN

mercredi 2 octobre 2013 à 12:37

L'abstention peut nous éclairer sur le rejet de la politique en général, mais également sur un levier parfois plus pervers : l'augmentation des pourcentages alloués au Front National.

On ne compte plus les couvertures consensuelles ou les cris d'orfraie poussés par la banalisation irrésistible du Front National, et surtout sur son pouvoir d'attraction auprès d'une part de Français de plus en plus large.

Il y a incontestablement un électorat qui s'agrandit pour ce parti d'extrême droite, en particulier auprès des couches populaires. Malgré tout, on reste souvent très évasif sur l'effet que peut avoir l'abstention sur les résultats du Front National.

Loin de minimiser la place incontestable du FN et de ses thèmes dans le paysage médiatique et politique français depuis plusieurs années, elle peut néanmoins nous aider à relativiser sa progression.

Des parallèles inédites

Observons pour commencer le nombre d'abstentions et de voix FN pendant ces 24 dernières années d'élections présidentielles :

Plusieurs enseignements sont à retenir :

L'abstention ayant toujours été plus haute que les voix du Front National depuis 1988, leurs courbes respectives semblent maintenant suivre des progressions parallèles, situation inédite en 24 ans.

Profitons-en pour souligner que cela ne signifie en rien qu'il y relation de cause à effet entre abstention et vote FN, même si le phénomène a de quoi interpeller.

Si l'abstention était un parti comme un autre...

La carte et les territoires

Les chiffres précédents étaient ceux de la France entière. Prenons du recul en considérant maintenant l'évolution de l'abstention et du FN pendant la présidentielle dans les 96 départements de métropole.

Nous allons utiliser pour cela une carte par anamorphose. Sa particularité est de déformer les départements en fonction des données qui leur sont attachées.

Vous pouvez consulter le pourcentage d'électeurs inscrits correspondant en survolant chaque département.

Ceci est la carte. Elle n'aurait aucun intérêt si on ne parlait pas, au moins un peu, de ses différents territoires. Commençons par ceux qui s'abstiennent :

Penchons-nous maintenant sur les scores du FN :

On l'a vu, l'abstention et le FN dressent des géographies électorales qu'on ne saurait confondre. D'un côté deux grandes poches d'abstention, de l'autre une moitié du pays de plus en plus encline à voter FN.

En conclusion

Rien ne permet de prévoir quel sera le score du Front National en 2017, même si le parti va mettre le paquet pour tenter d'activer le plus de leviers d'influence d'ici là, lors des municipales et des européennes notamment.

A court comme à long terme, l'une des plus grandes craintes du gouvernement est une forte abstention des électeurs de gauche, qui a eu les conséquences que l'on connaît en 2002.

Aucune mesure qui pourrait au moins la faire baisser à court terme (reconnaissance du vote blanc, droit de vote des étrangers aux élections locales) n'a pour l'instant été prise, et le pari repose avant tout sur le retour ou non de la croissance en 2014.

De l'autre côté de l'échiquier politique, le grand flou entretenu par le premier parti d'opposition sur la stratégie à adopter par rapport au FN (s'en distinguer ou leur ouvrir les bras) risque de tourner au vinaigre pour lui.

Comme me le disait il y a quelques années un responsable du FN en Moselle, les électeurs frontistes préféreront toujours l'original à la copie.

Un remerciement et quelques précisions

Installer QGIS 2.0 sur Mint

mardi 1 octobre 2013 à 16:33

Quelques lignes de commande pour installer en deux coups de cuillère à pot la dernière version du logiciel de cartographie QGIS sur une distribution Mint.

qgis2_0
Image : Capture d'écran de QGIS Dufour

La toute dernière version de QGIS, nom de code "Dufour", est depuis peu disponible. Pour l'instant, les packages trouvables sur le gestionnaire de logiciels de Mint sont liés à l'avant-dernière version, QGIS Lisboa.

Manque de pot, cette dernière plante chez moi : problème de chargement de la librairie python-qgis, redoutable et sans appel.

Du coup, je partage avec vous ces quelques lignes pour directement télécharger la version "instable", autrement dit Dufour :-) :

sudo apt-get install python-software-properties

sudo add-apt-repository ppa:ubuntugis/ubuntugis-unstable

sudo apt-get update

sudo apt-get install qgis python-qgis qgis-plugin-grass

Source

Error happened! 0 - Call to a member function query() on null In: /var/www/ecirtam.net/autoblogs/autoblogs/autoblog.php:200 http://www.ecirtam.net/autoblogs/autoblogs/blogm0lenet_bfc8f87e735c06165eb14a755febbc78e0faa7f6/?20 #0 /var/www/ecirtam.net/autoblogs/autoblogs/autoblog.php(414): VroumVroum_Config->setDisabled() #1 /var/www/ecirtam.net/autoblogs/autoblogs/autoblog.php(999): VroumVroum_Blog->update() #2 /var/www/ecirtam.net/autoblogs/autoblogs/blogm0lenet_bfc8f87e735c06165eb14a755febbc78e0faa7f6/index.php(1): require_once('...') #3 {main}