Abstimmungen: Karte

teaser_cantone

Ziel der Übung: Eine automatisch erzeugte Karte der Schweiz, die in Echtzeit die Ergebnisse von Abstimmungen zeigt, wobei die Kantone ihrem Entscheid entsprechend eingefärbt werden. Die Abstimmungsresultate werden auf admin.ch publiziert, das von mir verwendete Beispiel hier. Diese Daten habe ich mit Scraperwiki eingelesen. Der Python-Quellcode lautet:

#!/usr/bin/env python
import scraperwiki
import requests
import lxml.html
html = requests.get("http://www.admin.ch/ch/d/pore/va/20130922/det572.html").content
dom = lxml.html.fromstring(html)
i = 1
for entry in dom.cssselect('table tr'):
 if i > 1:
 if i < 28:
 post = {
 'kanton': entry.cssselect('td')[0].text_content(),
 'ja': entry.cssselect('td')[1].text_content().replace("`",""),
 }
 print post
 scraperwiki.sqlite.save(unique_keys=['kanton'], data=post)
 i = i+1

Seit einem Relaunch bietet Scraperwiki einen automatisierten Export der Daten im JSON-Format an. Die Funktion versteckt sich unter dem Menupunkt „Query with SQL“ . Die von mir erzeugte Datendatei enthält zwei Felder: Kanton und Ja-Stimmen-Anteil und ist hier zu finden. Die SQL-Abfrage dazu lautet:

select ja, kanton from swdata order by kanton limit 30

Für die Schweizerkarte im SVG-Format habe ich mich bei Wikimedia bedient. In einem Text-Editor habe ich die Farben entfernt und die IDs der einzelnen Kantone angepasst sowie die einzelnen Text- und Pathelemente in die gleiche Reihenfolge wie beim obengenannten JSON-File gebracht. Die so bearbeitete Version gibt’s hier.

Die Script habe ich mit der Java-Script Library D3 geschrieben. Ein sehr gutes, 20-teiliges Videotutorial zu D3 bietet youtube-user d3Vienno.

Der D3-Code ist extrem dicht und kurz:

d3.json('https://premium.scraperwiki.com/dexzd4i/5f6e1b937dbd42e/sql/?q=select%20%0A%09ja%2C%0A%09kanton%0Afrom%20swdata%0Aorder%20by%20kanton%0Alimit%2030%0A', function(data){
 var color = d3.scale.linear()
 .domain([20, 49.99, 50, 80])
 .range(["#143d00", "#cde6c1", "#ffcece", "#660000"]);

 d3.selectAll("path")
 .data(data)
 .attr("fill", function(d){ return color(d.ja)});
d3.selectAll("text")
 .data(data)
 .text(function(d){ return d.ja});
});

Zunächst wird das JSON-File importiert und als data-Array an eine Funktion weitergegeben. Dann wird eine Variabel „color“ definiert. Die Domain-Werte sind prozentuale Stimmanteile, es sind vier Werte, damit zwischen 49% und 51% auf der Karte klar zwischen hellrot und hellgrün unterscheidet werden kann. Die Range-Angaben sind die entsprechenden Farbcodes, wobei D3 den genauen Farbverlauf mittels der scale-Funktion automatisch regelt.

Dann folgen zwei Befehle, zunächst für die Kantonsflächen / Farbgebung, dann für die Angabe der Ja-Stimmen in Prozent. Der Quellcode des Scripts ist zu finden unter: http://jsfiddle.net/shufschmid/z28SL/3/

Autor: Samuel Hufschmid

Jounalist bei bz Basel, Papi, Organisator Swiss Kubb Open, mit Interesse an Datenjournalismus.

Kommentar verfassen