Für ein kleines Projekt sollte ich in den letzten Tagen ein Mitgliederwesen auf einer Landkarte visualisieren. Ziel war es zu sehen, in welchen Städten wie viele Mitglieder wohnen.
Die daraus entstehende Karte soll in eine bestehende WordPress Instanz eingebunden werden. Also müsste das ganze irgendwie im Browser laufen und am besten mit JavaScript oder PHP realisiert sein.
Ich habe mich dafür entschieden, das ganze mit dem Python Paket folium zu realisieren. Mit folium werden die Ergebnisse, in diesem Fall die Landkarte, in ein HTML Dokument exportiert. Innerhalb des HTML wird zum anzeigen der Landkarte Leaflet.js verwendet.
Als Datensatz stand mir eine CSV Datei zur Verfügung, wo für jedes Mitglied eine Zeile mit der Postleitzahl enthalten ist. Diese CSV Datei lese ich in einen pandas Dataframe ein.
1 | data = pd.read_csv("kjg-mitglieder.csv", sep=";") |
Anschließend braucht man für die Postleitzahlen die entsprechenden Geokoordinaten. Dafür verwende ich die Python Library geopy. Das ganze sieht wie folgt aus:
1 2 3 4 5 6 | geolocator = Nominatim(timeout=None) location_list = [] for i in range(data.__len__()): location = geolocator.geocode(data['plz'][i]) location_list.append((location.latitude, location.longitude)) |
Nun muss folium und ein Cluster für die Markierungen initialisiert werden. Anschließend kann mittels einer Schleife jede Markierung auf die Karte gesetzt werden.
1 2 3 4 5 6 7 8 9 | folium_map = folium.Map(location=[51.144, 9.902], zoom_start=6.5, tiles="CartoDB positron") marker_cluster = MarkerCluster().add_to(folium_map) for point in range(0, data.__len__()): folium.Marker(location_list[point]).add_to(marker_cluster) |
Zu guter Letzt noch der HTML export. Dieser ist relativ einfach.
1 | marker_cluster.save("kjg_dv_fulda_locations.html") |
Das ganze sieht dann fertig im Browser so aus:
Und hier nochmal das ganze Script. Alternativ findet ihr die aktuelle Version des Scripts in meinem GitHub Repository.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | import folium import pandas as pd from folium.plugins import MarkerCluster from geopy.geocoders import Nominatim data = pd.read_csv("kjg-mitglieder.csv", sep=";") geolocator = Nominatim(timeout=None) location_list = [] for i in range(data.__len__()): location = geolocator.geocode(data['plz'][i]) location_list.append((location.latitude, location.longitude)) folium_map = folium.Map(location=[51.144, 9.902], zoom_start=6.5, tiles="CartoDB positron") marker_cluster = MarkerCluster().add_to(folium_map) for point in range(0, data.__len__()): folium.Marker(location_list[point]).add_to(marker_cluster) marker_cluster.save("kjg_dv_fulda_locations.html") |
An dieser Stelle Danke an den Diözesanverband der KjG Fulda für die Daten. Habt ihr coole Datensätze mit denen ich mal testen soll was man so machen kann. Dann meldet euch einfach bei mir oder hinterlasst hier ein Kommentar =)
Maximilian meint
Hallo Christian,
vielen Dank für diesen Blog-Beitrag. Eine super und anschauliche Idee, um Standorte nach PLZen und deren Verteilung/Häufigkeit zu visualisieren.
Ich hatte bzw. habe ein ähnliches Projekt, habe dein beschriebenes Skript ausprobiert und auf meinen Datensatz (deutschlandweit) angewandt. Das hat auch soweit alles funktioniert, jedoch habe ich beim Aufrufen meines HTML exports bemerkt, dass beim Import der Daten ein Fehler aufgetreten ist.
Alle PLZen, die mit einer „0“ beginnen, wurden zu vierstelligen PLZen umgewandelt und dadurch falsch auf der Map dargestellt.
Ich habe bereits Änderungen, wie z.B. PLZ-Felder in der Excel-Tabelle als Sonderformat oder Text darstellen, vorgenommen, jedoch ohne Erfolg.
Wie kann ich dieses Problem beheben, damit beim Import die Nullen am Anfang nicht verloren gehen? Gibt es da einen einfachen Trick? Muss ich dazu was an meiner CSV-Datei ändern oder in dem Skript?
Vielen Dank im Voraus und ich freue mich über eine Antwort!
Viele Grüße
Maximilian