"
],
"text/plain": [
" iso_gemeinde name_gemeinde AGE_GROUP POP_TOTAL POP_MALE POP_FEMALE \\\n",
"0 30101 Krems an der Donau 5_9 950 486 464 \n",
"1 30101 Krems an der Donau 10_14 971 484 487 \n",
"2 30101 Krems an der Donau 15_19 1184 591 593 \n",
"\n",
" YEAR iso_bezirk alter_durchschnitt \n",
"0 2015 301 7.0 \n",
"1 2015 301 12.0 \n",
"2 2015 301 17.0 "
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"bev = bev.drop(['NUTS1', 'NUTS2', 'NUTS3'], axis=1)\n",
"bev = bev.rename(columns={'LAU2_CODE':'iso_gemeinde', 'LAU2_NAME':'name_gemeinde'})\n",
"bev['iso_gemeinde'] = bev.iso_gemeinde.astype('str')\n",
"bev['iso_bezirk'] = bev.iso_gemeinde.str[0:3]\n",
"bev['alter_durchschnitt'] = bev.AGE_GROUP.str.split('_', expand=True).replace('', np.nan).astype('float').mean(axis=1)\n",
"bev[:3]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Erzeugen einer Liste aller Gemeinden und Bezirke (jeweils ISO code), für die Daten vorhanden sind. "
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"iso_gemeinde = bev.iso_gemeinde.unique().astype('str').tolist()\n",
"iso_bezirk = bev.iso_bezirk.unique().astype('str').tolist()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## GeoJSON Daten\n",
"\n",
"Daten zur graphischen Darstellung von Bezirken und Gemeinden finden sich [hier](http://www.strategieanalysen.at/wahlen/geojson/). Konkret verwende ich aus [dieser Datei](http://www.strategieanalysen.at/wahlen/geojson/json_94.7z) die Dateien `gemeinden.json` und `bezirke.json`."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"FILE_GEOJSON_GEMEINDE = 'gemeinden.json'\n",
"FILE_GEOJSON_BEZIRK = 'bezirke.json'"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"geo_json_data_gemeinde = json.load(open(FILE_GEOJSON_GEMEINDE, encoding='latin-1'))\n",
"geo_json_data_bezirk = json.load(open(FILE_GEOJSON_BEZIRK, encoding='latin-1'))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Die GeoJSON Files enthalten Informationen zu allen Gemeinden und Bezirken in Österreich. Da ich mich hier nur Niederösterreich interessiere, erstelle ich neue Geojson Files, die nur diese Information enthalten.\n",
"\n",
"Zuerst wird der Eintrag `type` kopiert, dann die Einträge `features` auf Niederösterreich eingeschränkt."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"'FeatureCollection'"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"geo_json_data_gemeinde['type']"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"geo_gemeinde = dict()\n",
"geo_bezirk = dict()\n",
"geo_gemeinde['type'] = geo_json_data_gemeinde['type']\n",
"geo_bezirk['type'] = geo_json_data_bezirk['type']"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"{'iso': '80214', 'iso_alt': None, 'name': 'Gaissau'}"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"geo_json_data_gemeinde['features'][1]['properties']"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"geo_gemeinde['features'] = [data for data in geo_json_data_gemeinde['features'] \n",
" if data['properties']['iso'] in iso_gemeinde]\n",
"geo_bezirk['features'] = [data for data in geo_json_data_bezirk['features'] \n",
" if data['properties']['iso'] in iso_bezirk]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Um in unserem DataFrame `bev` auch den Namen des Bezirks zu haben, wird zuerst, basierend auf der Information in `geo_bezirk` ein Mapping zwischen Iso-Code und Bezirksname erstellt. Dieses wird dann auf den Iso-Code des Bezirks in `bev` angewendet."
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"{'301': 'Krems an der Donau (Stadt)',\n",
" '302': 'St.Poelten (Stadt)',\n",
" '303': 'Waidhofen an der Ybbs (Stadt)',\n",
" '304': 'Wiener Neustadt (Stadt)',\n",
" '305': 'Amstetten',\n",
" '306': 'Baden',\n",
" '307': 'Bruck an der Leitha',\n",
" '308': 'Gaenserndorf',\n",
" '309': 'Gmuend',\n",
" '310': 'Hollabrunn',\n",
" '311': 'Horn',\n",
" '312': 'Korneuburg',\n",
" '313': 'Krems (Land)',\n",
" '314': 'Lilienfeld',\n",
" '315': 'Melk',\n",
" '316': 'Mistelbach',\n",
" '317': 'Moedling',\n",
" '318': 'Neunkirchen',\n",
" '319': 'Sankt Poelten (Land)',\n",
" '320': 'Scheibbs',\n",
" '321': 'Tulln',\n",
" '322': 'Waidhofen an der Thaya',\n",
" '323': 'Wiener Neustadt (Land)',\n",
" '324': 'Wien-Umgebung',\n",
" '325': 'Zwettl'}"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"map_iso_bezirk = {data['properties']['iso']: data['properties']['name'] for data in geo_bezirk['features']}\n",
"map_iso_bezirk"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"
\n",
" \n",
"
\n",
"
\n",
"
iso_gemeinde
\n",
"
name_gemeinde
\n",
"
AGE_GROUP
\n",
"
POP_TOTAL
\n",
"
POP_MALE
\n",
"
POP_FEMALE
\n",
"
YEAR
\n",
"
iso_bezirk
\n",
"
alter_durchschnitt
\n",
"
name_bezirk
\n",
"
\n",
" \n",
" \n",
"
\n",
"
0
\n",
"
30101
\n",
"
Krems an der Donau
\n",
"
5_9
\n",
"
950
\n",
"
486
\n",
"
464
\n",
"
2015
\n",
"
301
\n",
"
7.0
\n",
"
Krems an der Donau (Stadt)
\n",
"
\n",
"
\n",
"
1
\n",
"
30101
\n",
"
Krems an der Donau
\n",
"
10_14
\n",
"
971
\n",
"
484
\n",
"
487
\n",
"
2015
\n",
"
301
\n",
"
12.0
\n",
"
Krems an der Donau (Stadt)
\n",
"
\n",
"
\n",
"
2
\n",
"
30101
\n",
"
Krems an der Donau
\n",
"
15_19
\n",
"
1184
\n",
"
591
\n",
"
593
\n",
"
2015
\n",
"
301
\n",
"
17.0
\n",
"
Krems an der Donau (Stadt)
\n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" iso_gemeinde name_gemeinde AGE_GROUP POP_TOTAL POP_MALE POP_FEMALE \\\n",
"0 30101 Krems an der Donau 5_9 950 486 464 \n",
"1 30101 Krems an der Donau 10_14 971 484 487 \n",
"2 30101 Krems an der Donau 15_19 1184 591 593 \n",
"\n",
" YEAR iso_bezirk alter_durchschnitt name_bezirk \n",
"0 2015 301 7.0 Krems an der Donau (Stadt) \n",
"1 2015 301 12.0 Krems an der Donau (Stadt) \n",
"2 2015 301 17.0 Krems an der Donau (Stadt) "
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"bev['name_bezirk'] = bev.iso_bezirk.map(map_iso_bezirk)\n",
"bev[:3]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Karten erstellen\n",
"\n",
"Dank `folium` ist das recht einfach. Zuerst wird eine Karte erstellt, hier muss man die Koordinaten und den Zoomlevel angeben. Dann wird die Bezirksinformation aus dem GeoJSON File hinzugefügt. Und dann noch die Gemeindeinformation, wobei dort noch eine Formatierung (Farbe, Strichbreite, ..) angegeben wird. Zum Schluss zeige die Karte im Notebook an. Die Karte ist interaktiv, sprich man kann darin zoomen, verschieben, ..."
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"
"
],
"text/plain": [
""
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"m = folium.Map(location=[48.2,15.8], zoom_start=8)\n",
"folium.GeoJson(geo_bezirk).add_to(m)\n",
"folium.GeoJson(\n",
" geo_gemeinde,\n",
" style_function=lambda feature:{\n",
" 'fillColor': 'red',\n",
" 'color' : 'black',\n",
" 'weight' : 2,\n",
" 'dashArray' : '5, 5'\n",
" }\n",
").add_to(m)\n",
"m"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Daten hinzufügen\n",
"\n",
"## Einwohner pro Bezirk\n",
"\n",
"Nun sollen Daten zu den Karten hinzugefügt werden. Als erstes Beispiel sollen die Bezirke basierend auf der Einwohneranzahl eingefärbt werden. Auch das ist mit `folium` recht einfach. Zuerst erzeuge ich einen Datenframe mit der entsprechenden Information pro Bezirk. Mit dem Befehl `choropleth` lassen sich die Daten dann mit der Karte verbinden. Am Schluss speichere ich die Karte noch in einer extra html-Datei für meinen Blog."
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"
"
],
"text/plain": [
" iso_bezirk name_bezirk POP_MALE POP_FEMALE FEMALE_RATIO\n",
"23 324 Wien-Umgebung 57638 61053 105.924911\n",
"0 301 Krems an der Donau (Stadt) 11644 12367 106.209206\n",
"16 317 Moedling 56153 60725 108.142040"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df[-3:]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Man sieht also, dass in Zwettl auf 100 Männer nur 99.5 Frauen kommen, während das in Mödling 108 sind. Auf einer Landkarte sieht das wie folgt aus."
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"C:\\Users\\uniqu\\Anaconda3\\lib\\site-packages\\ipykernel\\__main__.py:6: FutureWarning: 'threshold_scale' default behavior has changed. Now you get a linear scale between the 'min' and the 'max' of your data. To get former behavior, use folium.utilities.split_six.\n"
]
},
{
"data": {
"text/html": [
"
"
],
"text/plain": [
""
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"m = folium.Map(location=[48.2, 15.8], zoom_start=8)\n",
"m.choropleth(geo_str=geo_bezirk,\n",
" data=df,\n",
" columns=['iso_bezirk', 'FEMALE_RATIO'],\n",
" key_on='feature.properties.iso',\n",
" fill_color='YlOrRd', fill_opacity=0.7, line_opacity=0.3)\n",
"m.save('02.html')\n",
"m"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Durchschnittliches Alter\n",
"\n",
"In welcher Gemeinde ist das durchschnittliche Alter am höchsten, wo leben die durchschnittlich jüngsten Leute?"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"
\n",
" \n",
"
\n",
"
\n",
"
iso_gemeinde
\n",
"
name_gemeinde
\n",
"
AGE_GROUP
\n",
"
POP_TOTAL
\n",
"
POP_MALE
\n",
"
POP_FEMALE
\n",
"
YEAR
\n",
"
iso_bezirk
\n",
"
alter_durchschnitt
\n",
"
name_bezirk
\n",
"
\n",
" \n",
" \n",
"
\n",
"
0
\n",
"
30101
\n",
"
Krems an der Donau
\n",
"
5_9
\n",
"
950
\n",
"
486
\n",
"
464
\n",
"
2015
\n",
"
301
\n",
"
7.0
\n",
"
Krems an der Donau (Stadt)
\n",
"
\n",
"
\n",
"
1
\n",
"
30101
\n",
"
Krems an der Donau
\n",
"
10_14
\n",
"
971
\n",
"
484
\n",
"
487
\n",
"
2015
\n",
"
301
\n",
"
12.0
\n",
"
Krems an der Donau (Stadt)
\n",
"
\n",
"
\n",
"
2
\n",
"
30101
\n",
"
Krems an der Donau
\n",
"
15_19
\n",
"
1184
\n",
"
591
\n",
"
593
\n",
"
2015
\n",
"
301
\n",
"
17.0
\n",
"
Krems an der Donau (Stadt)
\n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" iso_gemeinde name_gemeinde AGE_GROUP POP_TOTAL POP_MALE POP_FEMALE \\\n",
"0 30101 Krems an der Donau 5_9 950 486 464 \n",
"1 30101 Krems an der Donau 10_14 971 484 487 \n",
"2 30101 Krems an der Donau 15_19 1184 591 593 \n",
"\n",
" YEAR iso_bezirk alter_durchschnitt name_bezirk \n",
"0 2015 301 7.0 Krems an der Donau (Stadt) \n",
"1 2015 301 12.0 Krems an der Donau (Stadt) \n",
"2 2015 301 17.0 Krems an der Donau (Stadt) "
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"bev[:3]"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"