#008 Mapa punktów (dot map)

Mapa punktów

Podstawą wszystkich analiz geoprzestrzennych jest opanowanie umiejętności prezentacji wyników na mapie.

W pierwszym kroku należy nauczyć się rysowania mapy w tle. Następnie mając już dostępne tło (czyli naszą mapę dla konkretnego obszaru), można wykorzystać je na wiele sposobów do wizualizacji naszych analiz.

Przykładowe możliwości jakie mamy to:

  • Mapa punktów (ang. dot map) – zaznaczenie punktów lokalizacyjnych na mapie:
Mapa punktów dot map
  • Mapa bąbelkowa (ang. bubble map) – naniesienie wykresu bąbelkowego na mapę:
Mapa bąbelkowa (ang. bubble map)
  • Mapa kształtów (ang. choreoplath) –  naniesienie kształtów regionów czy państw, by móc zaprezentować kartogram (np. różne kolory per województwo):
Mapa kształtów (ang. choreoplath)
  • Mapa powiązań (ang. connection map) – pokazanie połączenia punktów, aby pokazać zależności (np. loty samolotów):
Mapa powiązań (ang. connection map)
  • Mapa przepływów (ang. flow map) – pokazanie kierunków i wielkości przepływu procesów (np. tonaż kontenerów przetransportowanych statkami):
Mapa przepływów (ang. flow map)

Biblioteka folium

Ostatnio, gdy dostałem zadanie zwizualizowania na mapie klientów znalazłem bibliotekę folium, którą chciałem Wam zaprezentować.

Folium wykorzystuje mapowania biblioteki Leaflet.js i bardzo ułatwia proces wizualizacji danych w python. Zaraz sami zobaczycie jakie to proste!

import pandas as pd
import folium

A teraz wyświetlmy mapę na domyślnych parametrach podając współrzędne geograficzne – długość i szerokość centrum Wrocławia:

folium.Map(location=[51.110705, 17.032396])

Gdybyśmy chcieli mapę zapisać, aby np. wysłać komuś mailem, to wystarczy powyższy obiekt przypisać pod zmienną i zapisać podając ścieżkę pliku html:

my_map = folium.Map(location=[51.110705, 17.032396])
my_map.save('wroclaw.html')

Domyślne mapa ustawiona jest z parametrem tiles=OpenStreetMap, który odpowiada za wygląd mapy. Natomiast bardzo prosto można wygląd zmodyfikować zmieniając parametr tiles na taki, który będzie Wam odpowiadał. Przykładowo można wybrać: Stamen Watercolor, Stamen Terrain, Stamen Toner czy CartoDB dark_matter.

folium examples

To teraz zobaczcie jak najprościej dodać znacznik:

my_map = folium.Map(
    location=[51.110005, 17.032396],
    zoom_start=16,
)
tooltip = 'Hej! Naciśnij mnie jeśli chcesz zobaczyć co tutaj jest :)'

folium.Marker([51.110690, 17.032912], 
              popup='<b>Najlepsza nalewka wiśniowa w mieście</b>', 
              tooltip=tooltip).add_to(my_map)
folium.Marker([51.110002, 17.033425], 
              popup='<b>Najlepsze żarcie na samym rynku</b>', 
              tooltip=tooltip).add_to(my_map)
folium.Marker([51.110187, 17.027787], 
              popup='<b>Najlepsze tanie szoty</b>', 
              tooltip=tooltip).add_to(my_map)

my_map
Out[33]:

Oczywiście możecie zmieniać wygląd punktów:

my_map = folium.Map(
    location=[51.110005, 17.032396],
    zoom_start=16,
)
tooltip = 'Hej! Naciśnij mnie jeśli chcesz zobaczyć co tutaj jest :)'

folium.Marker([51.110690, 17.032912], 
              popup='<b>Najlepsza nalewka wiśniowa w mieście</b>', 
              icon=folium.Icon(color='red', icon='thumbs-up')).add_to(my_map)
folium.Marker([51.110002, 17.033425], 
              popup='<b>Najlepsze żarcie na samym rynku</b>', 
              icon=folium.Icon(color='green', icon='cutlery')).add_to(my_map)
folium.Marker([51.110187, 17.027787], 
              popup='<b>Najlepsze tanie szoty</b>', 
              icon=folium.Icon(icon='glass')).add_to(my_map)

my_map

Więcej ikon znajdziecie na przykład tutaj.

Pamiętajcie, że możecie nanosić dowolne punkty na podstawie danych z DataFrame. Gdybyście mieli w DataFrame ściągnięte dane z oznaczeniem placówek Santandera z 2017 roku to można je nanieść na mapkę z informacją o godzinach otwarcia 🙂 Poniżej przykład jak można to zrobić:

df = pd.read_csv('../data/geo_branches.csv', sep=";")

my_map = folium.Map(
    location=[51.110005, 17.032396],
    zoom_start=14,
)

for ind in df.index:     
    tooltip_txt = df['nazwa'][ind] + '<br>godziny otwarcia:' + df['godziny'][ind]
        
    folium.Marker([float(df['len'][ind]), float(df['lat'][ind])], 
                  icon=folium.Icon(color='red'),
                  tooltip= tooltip_txt).add_to(my_map)

my_map

Interaktywne grupowanie

Zobaczcie jeszcze jedną ciekawostkę. Za pomocą kilku linii kodu można stworzyć mapę zawierającą interaktywne znaczniki, które automatycznie grupują liczbę punktów na mapie. Grupowane są znaczniki z lokalizacjami jeśli są wystarczająco blisko siebie.

from folium.plugins import MarkerCluster

locations = list(zip(df['len'], df['lat']))

m = folium.Map(
    location=[np.mean(df['len']), np.mean(df['lat'])],
    zoom_start=6
)

marker_cluster = MarkerCluster(
    locations=locations
  , popups=df['nazwa']
)

marker_cluster.add_to(m)

m