Для визуализации интерактивных карт рассмотрим библиотеку - Folium.

Folium — это мощная библиотека визуализации данных в Python, которая была создана в первую очередь для того, чтобы помочь людям визуализировать гео-пространственные данные.

Folium - это библиотека с открытым исходным кодом, созданная на основе возможностей Datawrangling экосистемы.

С помощью Folium можно создать карту любого местоположения в мире, если вы знаете его значения широты и долготы.

Также можете создать карту и наложить маркеры, а также кластеры маркеров поверх карты для крутых и очень интересных визуализаций.

Folium - это библиотека Python, которая помогает создавать несколько типов карт Leaflet. Тот факт, что результаты Folium интерактивны, делает эту библиотеку очень полезной для создания информационных панелей.

На официальной странице документации Folium:

Folium builds on the data wrangling strengths of the Python ecosystem and the mapping strengths of the Leaflet.js library. Manipulate your data in Python, then visualize it in on a Leaflet map via Folium.

Folium опирается на сильные стороны экосистемы Python и возможности сопоставления библиотеки Leaflet.js. Управляйте своими данными в Python, а затем визуализируйте их на карте Leaflet через Folium.

Folium makes it easy to visualize data that's been manipulated in Python on an interactive Leaflet map. It enables both the binding of data to a map for choropleth visualizations as well as passing Vincent/Vega visualizations as markers on the map.

Folium позволяет легко визуализировать данные, обработанные в Python, на интерактивной карте Leaflet. Он позволяет как привязать данные к карте для визуализации choropleth, так и передавать визуализации Винсента / Веги в качестве маркеров на карте.

The library has a number of built-in tilesets from OpenStreetMap, Mapbox, and Stamen, and supports custom tilesets with Mapbox or Cloudmade API keys. Folium supports both GeoJSON and TopoJSON overlays, as well as the binding of data to those overlays to create choropleth maps with color-brewer color schemes.

Библиотека имеет ряд встроенных наборов фрагментов из OpenStreetMap, Mapbox и Stamen и поддерживает настраиваемые наборы фрагментов с ключами API Mapbox или Cloudmade. Folium поддерживает наложения как GeoJSON, так и TopoJSON, а также привязку данных к этим наложениям для создания карт choropleth с цветовыми схемами цвета color-brewer.

Для интерактивной визуальной аналитики - библиотеку Folium сначала нужно установить. В терминале прописываем:

pip install folium

Теперь можно импортировать библиотеку Folium.

import folium

# Import folium MarkerCluster plugin
from folium.plugins import MarkerCluster
# Import folium MousePosition plugin
from folium.plugins import MousePosition
# Import folium DivIcon plugin
from folium.features import DivIcon

print('Folium installed and imported!')

Folium installed and imported!

Создание карты мира с помощью Folium довольно просто. Вы просто вызываете функцию карты - folium.Map(), и это все.

# define the world map
world_map = folium.Map()

# display world map
world_map
Карта мира (увеличенный масштаб)
Карта мира (увеличенный масштаб)

Что действительно интересно в картах, созданных Folium, так это то, что они являются интерактивными, поэтому можно увеличить или уменьшить масштаб после визуализации карты.

Карта мира
Карта мира

Стиль карты по умолчанию - OpenStreetMap (открытая карта улиц), которая показывает вид улицы области при масштабировании и показывает границы стран мира при масштабировании.

Карта мира, Стиль карты  - OpenStreetMap (открытая карта улиц)
Карта мира, Стиль карты - OpenStreetMap (открытая карта улиц)

Теперь давайте создадим карту мира вокруг России и назовем ее - russia_map . Для этого мы передаем значения широты и долготы России с помощью параметра location (местоположения) и с Folium вы можете установить начальный уровень масштабирования с помощью параметра zoom start.

russia_map = folium.Map(
    location = [64.6863136, 97.7453061],    # широта и долгота России
    zoom_start = 4
)

# display russia map
russia_map
Карта мира вокруг России
Карта мира вокруг России

zoom start - это начальный уровень масштабирования, т.к. легко можно изменить уровень масштабирования после отображения карты путем увеличения или уменьшения масштаба.

Еще одна удивительная особенность Folium заключается в том, что можно создавать различные стили карт с помощью параметра tiles

Давайте создадим стиль 'Stamen Toner’ карты мира вокруг России. Это высококонтрастные черно-белые карты.

Этот стиль отлично подходит для визуализации и изучения речных меандров (изгибы русла реки) и прибрежных зон.

russia_map = folium.Map(
    location = [64.6863136, 97.7453061],   # широта и долгота России
    zoom_start = 4,
    tiles = 'Stamen Toner'
)

# display russia map
russia_map
Стиль 'Stamen Toner’ карты  мира вокруг России
Стиль 'Stamen Toner’ карты мира вокруг России
Стиль 'Stamen Toner’ карты  мира вокруг России (увеличенный масштаб)
Стиль 'Stamen Toner’ карты мира вокруг России (увеличенный масштаб)

Другой стиль - 'Stamen Terrain’ (тиснение местности). Этот стиль отлично подходит для визуализации затенения холмов и природных цветов растительности.

russia_map = folium.Map(
    location = [64.6863136, 97.7453061],      # широта и долгота России
    zoom_start = 4,
    tiles = 'Stamen Terrain'
)

# display russia map
russia_map
Стиль 'Stamen Terrain’ карты  мира вокруг России
Стиль 'Stamen Terrain’ карты мира вокруг России

Это карты с затенением холмов и цветами естественной растительности. Они демонстрируют усовершенствованную маркировку и обобщение линий дорог с двусторонним движением.

Стиль 'Stamen Terrain’ карты  мира вокруг России (увеличенный масштаб)
Стиль 'Stamen Terrain’ карты мира вокруг России (увеличенный масштаб)

Как накладывать маркеры поверх карты для интересных визуализаций?

Давайте посмотрим, как мы можем добавить красный круговой знак в центр Санкт-Петербурга. Для этого нам нужно создать так называемую группу объектов под названием Saint_Petersburg.

Эта группа объектов пуста, а это значит, что дальше — нужно создать так называемые дочерние элементы (child) и добавлять их в группу объектов.

Так давайте создадим child в виде красного кругового знака, расположенного в центре Санкт-Петербурга. Для этого укажем местоположение нижестоящего элемента (Санкт-Петербурга), передавая его значения широты и долготы.

И как только мы закончим добавление дочерних элементов (child) в группу объектов, мы добавим выбранную группу на карту -

красный круговой знак наложен на верхней части карты и добавлен в центр города Санкт-Петербурга.

# generate map of Russia  (составить карту россии)
russia_map = folium.Map(
    location = [64.6863136, 97.7453061],    # широта и долгота России
    zoom_start = 4
)

# add a red marker to Saint Petersburg
# create a feature group (создать группу функций)
saint_petersburg = folium.map.FeatureGroup()

# style the feature group (стиль группы объектов)
saint_petersburg.add_child(
    folium.features.CircleMarker(
        [59.938732, 30.316229], radius = 5,  # широта и долгота Санкт-Петербурга
        color = 'red', fill_color = 'Red'
    )
)

# add the feature group to the map  (добавить группу объектов на карту)
russia_map.add_child(saint_petersburg)

# display russia map
russia_map
красный круговой знак наложен на верхней части карты и добавлен в центр города Санкт-Петербурга.
красный круговой знак наложен на верхней части карты и добавлен в центр города Санкт-Петербурга.

Давайте, теперь подпишем красный круговой знак: - 'Санкт-Петербург, в разговорной речи - Пи́тер, сокр. - СПб’. Для этого мы просто используем функцию маркера и параметр всплывающего окна, чтобы передать любой текст, который мы хотим добавить к этому маркеру.

# generate map of Russia
russia_map = folium.Map(
    location = [64.6863136, 97.7453061],    # широта и долгота России
    zoom_start = 4
)

# add a red marker to Saint Petersburg
# create a feature group
saint_petersburg = folium.map.FeatureGroup()

# style the feature group
saint_petersburg.add_child(
    folium.features.CircleMarker(
        [59.938732, 30.316229], radius = 5,    # широта и долгота Санкт-Петербурга
        color = 'red', fill_color = 'Red'
    )
)

# add the feature group to the map
russia_map.add_child(saint_petersburg)

# label the Marker (пометить маркер)
folium.Marker([59.938732, 30.316229],         # широта и долгота Санкт-Петербурга
popup = 'Санкт-Петербург, в разговорной речи - Пи́тер, сокр.- СПб').add_to(russia_map)

# display russia map
russia_map
подпись 'Санкт-Петербург, в разговорной речи - Пи́тер, сокр. - СПб’  к маркеру красный круговой знак
подпись 'Санкт-Петербург, в разговорной речи - Пи́тер, сокр. - СПб’ к маркеру красный круговой знак
подпись 'Санкт-Петербург, в разговорной речи - Пи́тер, сокр. - СПб’  к маркеру красный круговой знак (увеличенный масштаб), cтиль карты  - OpenStreetMap
подпись 'Санкт-Петербург, в разговорной речи - Пи́тер, сокр. - СПб’ к маркеру красный круговой знак (увеличенный масштаб), cтиль карты - OpenStreetMap

Давайте добавим MousePosition на карту, чтобы получить координаты наведения курсора мыши на точку на карте. Таким образом, это позволяет исследовать карту и легко найти координаты любых точек интереса (например, дворцовый мост, литейный мост).

# Add Mouse Position to get the coordinate (Lat, Long) for a mouse over on the map
formatter = "function(num) {return L.Util.formatNum(num, 5);};"
mouse_position = MousePosition(
    position='topright',
    separator=' Long: ',
    empty_string='NaN',
    lng_first=False,
    num_digits=20,
    prefix='Lat:',
    lat_formatter=formatter,
    lng_formatter=formatter,
)

russia_map.add_child(mouse_position)
russia_map
MousePosition (координаты показаны в верхнем левом углу)
MousePosition (координаты показаны в верхнем левом углу)

Можно рассчитать расстояние между двумя точками на карте на основе их значений широты и долготы, используя следующий метод:

from math import sin, cos, sqrt, atan2, radians

def calculate_distance(lat1, lon1, lat2, lon2):
    # approximate radius of earth in km
    R = 6373.0

    lat1 = radians(lat1)
    lon1 = radians(lon1)
    lat2 = radians(lat2)
    lon2 = radians(lon2)

    dlon = lon2 - lon1
    dlat = lat2 - lat1

    a = sin(dlat / 2)**2 + cos(lat1) * cos(lat2) * sin(dlon / 2)**2
    c = 2 * atan2(sqrt(a), sqrt(1 - a))

    distance = R * c
    return distance

Отметим точку на Дворцовом мосту с помощью MousePosition и вычислим расстояние от нашего красного круглого маркера до Дворцового моста.

#Distance to Palace Bridge  Дворцовый мост
coordinates = [
    [59.93876, 30.31623],           # координаты красного круглого маркера
    [59.94022, 30.30931]]           # координаты дворцового моста

lines=folium.PolyLine(locations=coordinates, weight=1)
russia_map.add_child(lines)
distance = calculate_distance(coordinates[0][0], coordinates[0][1],
                              coordinates[1][0], coordinates[1][1])
distance_circle = folium.Marker(
    [59.94022,30.30931],
    icon=DivIcon(
        icon_size=(20,20),
        icon_anchor=(0,0),
        html='<div style="font-size: 12; 
      color:#252526;"><b>%s</b></div>' % "{:10.2f} KM".format(distance),
        )
    )
russia_map.add_child(distance_circle)
russia_map
0.42 км - расстояние от нашего красного круглого маркера до Дворцового моста
0.42 км - расстояние от нашего красного круглого маркера до Дворцового моста

Отметим точку на Литейном мосту с помощью MousePosition и вычислим расстояние от нашего красного круглого маркера до Литейного моста.

#Distance to Foundry bridge   Литейный мост
coordinates = [
    [59.93876, 30.31623],       # координаты красного круглого маркера
    [59.94981, 30.34906]]       # координаты литейного моста

lines=folium.PolyLine(locations=coordinates, weight=1)
russia_map.add_child(lines)
distance = calculate_distance(coordinates[0][0], coordinates[0][1],
                              coordinates[1][0], coordinates[1][1])
distance_circle = folium.Marker(
    [59.94981,30.34906],
    icon=DivIcon(
        icon_size=(20,20),
        icon_anchor=(0,0),
        html='<div style="font-size: 12; 
      color:#252526;"><b>%s</b></div>' % "{:10.2f} KM".format(distance),
        )
    )
russia_map.add_child(distance_circle)
russia_map
2.20 км - расстояние от нашего красного круглого маркера до Литейного моста.
2.20 км - расстояние от нашего красного круглого маркера до Литейного моста.

Разве это не круто? Folium - это мощная библиотека визуализации данных в Python!

Комментарии (2)


  1. ne555
    09.05.2022 07:38
    +4

    Немного добавлю от себя.

    Folium - это библиотека с открытым исходным кодом,

    под свободной, либеральной лицензией (она и её компоненты/зависимости не используют GPL+, что позволяет, например, использовать lib в коммерческих целях).

    Folium зависит/тянет numpy, который требует параллельных вычислений (многопроцессорная обработка SemLock), т.е. по дефолту, например, библиотека не встанет в termux/android (необходимо будет немного модифицировать сам интерпретатор python).

    Также можете создать карту и наложить маркеры, а также кластеры маркеров поверх карты для крутых и очень интересных визуализаций.

    В статье, ИМХО, очень не хватает этих самых разнообразных примеров: "крутых и очень интересных визуализаций".

    Немного визуализации с folium
    Пример вычисления DDoS-атаки (от кого и откуда).
    Пример вычисления DDoS-атаки (от кого и откуда).

    Источник.


    1. tatvch Автор
      09.05.2022 15:00

      Спасибо за дополнение и за пример визуализации с folium!