Сегодня делимся с вами пошаговым руководством создания интерактивных карт для веб-приложения или блога. Просто сохраните эту статью в закладках. Хоть и существует, например, библиотека d3.js, которая может создавать пользовательские карты, есть несколько инструментов еще проще. В этом посте посмотрим на три простые в обращении, но мощные библиотеки Python с открытым исходным кодом и поработаем с ними.
Когда документация вводит в ступор
Несколько месяцев назад я хотел создать интерактивную карту для интересного веб-приложения, которое мы разрабатывали. Я провел часы в интернете в поисках идеальной библиотеки для начала работы, но мне было очень трудно смотреть документацию, так как не было надлежащего пошагового руководства для реализации и настройки визуальных элементов по мере необходимости. Мне хотелось, чтобы у меня было руководство, в котором сравниваются функции и правильная реализация вместе с подробностями о настройке. Эта статья — попытка написать такое руководство.
Далее в статье сравниваются реализации интерактивной фоновой карты (хороплета) с использованием трех популярных библиотек, доступных для Python, а также подробности и настройки окончательного результата.
- Altair — простая и быстрая реализация с легкодоступным набором функций.
- Plotly — обладает богатой функциональностью. Включает в себя Mapbox, пользовательские настройки и стилизацию.
- Folium — Leaflet — полностью настраиваемая и интерактивная. Включает в себя подсказки, всплывающие окна и многое другое.
Предварительные требования
Хороплетная карта требует двух видов данных в фоновом режиме, один из которых — это геопространственные данные, географические границы для заполнения карты (обычно это векторный файл
.shp
(Shapefile) или GeoJSON), и две точки данных на каждом квадрате карты для цветового кодирования карты в зависимости от самих данных.Библиотека Geo Pandas полезна, когда нужно получить данные в требуемом формате. В примере используется файл GeoJSON индийских штатов. Вы можете начать с любого общедоступного Shapefile или GeoJSON.
Altair
Altair — библиотека визуализации для Python, основанная на Vega. Хороплет реализуется минимальными усилиями и включает интерактивные элементы — выделение, всплывающие подсказки и т.д.
Altair совместима с fastpages. Вы можете создавать простые записи блога в считанные минуты, просто конвертируя файлы Jupyter Notebook с помощью минимального количества кода. Ознакомьтесь с Readme на GitHub.
Фрагмент кода:
# Importing required Libraries
import geopandas as gpd
import json
import altair as alt
import pandas as pd
Читаем Shapefile как фрейм GeoPandas:
gdf = gpd.read_file('states_india.shp')
Фрейм выглядит так:
Создаем базовый слой и слой хороплета:
# Creating configs for color,selection,hovering
multi = alt.selection_multi(fields=['count','state'], bind='legend')
color = alt.condition(multi,
alt.Color('count', type='ordinal',
scale=alt.Scale(scheme='yellowgreenblue')),
alt.value('lightgray'))
hover = alt.selection(type='single', on='mouseover', nearest=True,
fields=['x', 'y'])
#Creating an altair map layer
choro = alt.Chart(gdf).mark_geoshape(
stroke='black'
).encode(
color=color,
tooltip=['state','count']
).add_selection(
multi
).properties(
width=650,
height=800
)
# Legend
c1 = alt.layer(choro).configure_legend(
orient = 'bottom-right',
direction = 'horizontal',
padding = 10,
rowPadding = 15
)
#Adding Labels
labels = alt.Chart(gdf).mark_text().encode(
longitude='x',
latitude='y',
text='count',
size=alt.value(8),
opacity=alt.value(0.6)
)
c2 = alt.Chart(gdf).mark_geoshape(
stroke='black'
).encode(
color=color,
tooltip=['state','count']
).add_selection(
hover
).project(
scale=100,
)
(c1+labels).configure_view(strokeWidth=0)
Код выше должен визуализировать интерактивную карту с функцией отображения подсказки и подсветки при выборе (клике).
Плюсы:
- Простая и быстрая реализация. Включает предопределенный набор функций, чтобы ускорить работу.
- Совместимость с fastpages
Минусы:
- Мало вариантов настройки и ограниченная интерактивность.
- Нет возможности использовать внешние стилизованные части карты, такие как OSM, Mapbox и т.п.
- API плохо документирован.
Реализация c помощью Plotly
Библиотека Plotly для построения графиков на Python отрисовывает готовые к публикации карты с большим количеством интерактивных и настраиваемых функций.
Доступны пользовательские конфигураций базовой карты из Mapbox, OSM и другие стилевые опции, а также простая реализация с помощью Plotly Express и обширная документация. Это делает Plotly одним из предпочтительных вариантов для создания интерактивных карт.
Фрагмент кода:
# Importing required libraries
from plotly.graph_objs import Scatter, Figure, Layout
import plotly
import plotly.graph_objs as go
import json
import numpy as np
import geopandas as gpd
Импортирование Shapefile:
gdf = gpd.read_file('states_india.shp')
with open('states_india_1.json') as response:
india = json.load(response)
Создание базового слоя и добавление частей карты:
fig = go.Figure(go.Choroplethmapbox(geojson=india, locations=gdf['st_nm'], z=gdf['state_code'],featureidkey="properties.st_nm",colorscale="Viridis", zmin=0, zmax=25,marker_opacity=0.5, marker_line_width=1))
fig.update_layout(mapbox_style="carto-positron",
mapbox_zoom=3.5,mapbox_center = {"lat":23.537876 , "lon": 78.292142} )
fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
fig.show()
Код выше должен визуализировать интерактивную карту с отображением подсказки и функцией масштабирования. Эта реализация включает большое количество других возможностей, подробнее о которых написано здесь.
Плюсы:
- Очень простая реализация с помощью библиотек диаграмм и Plotly Express. Имеется обширная документация.
- Множество настроек и настраиваемых опций стилизации.
- Совместимость с Dash и другими вариантами для встраивания фрагмента во внешние веб-приложения.
Минусы:
- Нет возможности добавлять всплывающие окна и другие интерактивные элементы, кроме предварительно заданных вариантов.
- Может потребоваться доступ по токену для работы с несколькими внешними стилями. Ограниченные возможности управления ограничениями масштабирования и связанной с этими возможностями интерактивностью.
Реализация с помощью Folium
Folium сочетает в себе простоту использования экосистемы Python и сильные стороны картографирования библиотеки leaflet.js. Это позволяет визуализировать настраиваемые, отзывчивые и интерактивные хороплетные карты, а также передавать богатые векторные, растровые, HTML-визуализации в виде маркеров на карте.
Библиотека имеет ряд встроенных наборов частей карт из OpenStreetMap, Mapbox и Stamen, а также поддерживает пользовательские наборы через API Mapbox или Cloudmade. Поддерживаются изображения, видео, GeoJSON и TopoJSON.
Фрагмент кода:
# Importing required Libraries
import geopandas as gpd
import pandas as pd
import folium
import branca
import requests
import json
from folium.features import GeoJson, GeoJsonTooltip, GeoJsonPopup
Импортирование Shapefile:
gdf = gpd.read_file('states_india.shp')
with open('states_india_1.json') as response:
india = json.load(response)
#Creating a custom tile (optional)
import branca
# Create a white image of 4 pixels, and embed it in a url.
white_tile = branca.utilities.image_to_url([[1, 1], [1, 1]])
Добавление базовых слоев и слоев Choropleth:
#Base layer
f = folium.Figure(width=680, height=750)
m = folium.Map([23.53, 78.3], maxZoom=6,minZoom=4.8,zoom_control=True,zoom_start=5,
scrollWheelZoom=True,maxBounds=[[40, 68],[6, 97]],tiles=white_tile,attr='white tile',
dragging=True).add_to(f)
#Add layers for Popup and Tooltips
popup = GeoJsonPopup(
fields=['st_nm','cartodb_id'],
aliases=['State',"Data points"],
localize=True,
labels=True,
style="background-color: yellow;",
)
tooltip = GeoJsonTooltip(
fields=['st_nm','cartodb_id'],
aliases=['State',"Data points"],
localize=True,
sticky=False,
labels=True,
style="""
background-color: #F0EFEF;
border: 1px solid black;
border-radius: 3px;
box-shadow: 3px;
""",
max_width=800,
)
# Add choropleth layer
g = folium.Choropleth(
geo_data=india,
data=gdf,
columns=['st_nm', 'cartodb_id'],
key_on='properties.st_nm',
fill_color='YlGn',
fill_opacity=0.7,
line_opacity=0.4,
legend_name='Data Points',
highlight=True,
).add_to(m)
folium.GeoJson(
india,
style_function=lambda feature: {
'fillColor': '#ffff00',
'color': 'black',
'weight': 0.2,
'dashArray': '5, 5'
},
tooltip=tooltip,
popup=popup).add_to(g)
f
Код выше должен отображать интерактивную хороплетную карту с подсказкой по наведению, кликом для увеличения масштаба и пользовательским окном, всплывающим по клику.
Плюсы:
- Количество настроек и настраиваемых опций стиля наряду с уникальными интерактивными функциями, такими как пользовательские всплывающие окна/части карты/фон, а также увеличение по клику.
- Опция передачи векторных, растровых, HTML визуализаций в виде маркеров на карте.
- Опция отображения карты в виде HTML и другие опции встраивания фрагмента во внешние веб-приложения.
- Достойный объем документации для изучения всех доступных функций.
Минусы:
- Зависит от нескольких библиотек.
Заключение
Эти три инструмента позволяют без особых хлопот реализовать индивидуально настроенные интерактивные карты для веб-сайтов.
Уважаемые читатели, а вам приходилось делать такие интерактивные карты для своих проектов?
Получить востребованную профессию с нуля или Level Up по навыкам и зарплате, можно пройдя онлайн-курсы SkillFactory:
- Курс «Python для веб-разработки»
- Профессия Веб-разработчик
- Обучение профессии Data Science с нуля
- Онлайн-буткемп по Data Science
- Онлайн-буткемп по Data Analytics
- Профессия аналитика с любым стартовым уровнем
Eще курсы
- Курс по Machine Learning
- Курс «Математика и Machine Learning для Data Science»
- Продвинутый курс «Machine Learning Pro + Deep Learning»
- Курс по аналитике данных
- Курс по DevOps
- Профессия iOS-разработчик с нуля
- Профессия Android-разработчик с нуля
- Профессия Java-разработчик с нуля
- Курс по JavaScript
- Профессия UX-дизайнер с нуля
- Профессия Web-дизайнер
sshikov
Агащазблин. Если вспомнить, что d3.js вообще не про карты, а скорее про диаграммы, например, то конечно же другие инструменты, специально ориентированные на картографию, будут проще. Конечно, если d3 дать скажем geojson, или там topojson, то библиотека их конечно покажет — в виде полилиний, не более того.