Как стать автором
Обновить

Folium. Как сделать несколько choropleth карт в одной и зачем нужна dualMap?

Время на прочтение5 мин
Количество просмотров3.3K

Привет, Хабр!

Меня зовут Екатерина Кононова, я Data Scientist и участник профессионального сообщества NTA.  Часто возникает проблема визуализации данных за несколько периодов времени. Те, кто уже пытался создавать карты знают, что эту проблему можно решить с помощью разных слоёв на карте. Если заглянуть в код, то можно увидеть, что именно строка folium.LayerControl(). add_to(m) позволяет добавить на карту возможность переключения между слоями, но об этом чуть позже.

Предположу, что есть некоторые данные о количестве плохих и хороших отзывов для каждой из точек сети ресторанов ХХХ. Нужно понять, какие оценки получают рестораны сети от гостей, посетивших эти заведения.

Сделаю карту, на которой нарисую несколько точек и раскрашу по цветам, в зависимости от оценки, где зелёный цвет – отлично, жёлтый – хорошо, все остальные красным цветом.

В таблице обязательно должны присутствовать данные о ресторанах: координаты, оценка, идентификатор. Дополнительную информацию, такую как адрес, директор и другую информацию можно вынести в подсказки (tooltip или popup, подробнее о них можно почитать в других публикациях). Подгружу данные.

data_01=pd.read_excel('test.xlsx')

Создам карту и нанесу на неё точки:

map = folium.Map(location=[55.000,57.000], zoom_start = 4, tiles = ‘CartoDB position’)
lat  = data[‘LAT’]
lon = data[‘LON’]
name = data[‘name’]
mes = data[‘mes’]
for lat, lon, name, mes in zip(lat, lon, name, mes):
	marker = folium.CircleMarker( location = [lat, lon], 
				tooltip = (‘Доля положительных отзывов:’+ mes+’.’+name) 
				fill_opacity = 0.6, 
				radius = 7,
				fill_color = color_change(mes),
				color = ‘mes’).add_to(layer)

Получаю карту, на которой можно видеть точки, окрашенные в определенный цвет:

Choropleth. Несколько карт в одной.

Данная карта уже отражает нужную информацию, но её можно сделать более читабельной с помощью создания карты Chrolopleth, тогда можно будет понимать ситуацию не только по конкретным точкам, но и по региону в целом.

Существует несколько способов создания таких карт: функции Chrolopleth и GeoJson.

Создам карту и подгружу данные о границах некоторых регионов России:

map = folium.Map(location=[55.000,57.000], zoom_start = 4, tiles = ‘CartoDB position’)
url = “formap.geojson”
df = geopandas.read_file(url)

Создать choropleth можно двумя способами:

1 способ

Choropleth = folium.Choropleth(
		data = regions_color,
		columns=[“cartodb_id”, “mes”],
		key_on=’feature.properties.cartodb_id’,
		fill_opacity=0.9,
		line_opacity=0.7,
		geo_data=regions,		
		fill_color = ‘YlGn’,
		name = ‘Choropleth2’).add_to(m)	

Где regions – это датасет с границами регионов, regions_color - датасет с данными по отзывам.

Обязательно должен быть уникальный идентификатор региона в обоих файлах.

2 способ

itog = folium.GeoJson(
		full_merge,
		style_function=lambda x: {
			“fillColor”: colormap(x[‘properties’][“compl”])
			if  x[‘properties’][“compl”] is not None
			else “transparent”,
			“color”: “black”,		
			“fillOpacity”: 0.7},
		tooltip=tooltip,
		name=”ИТОГ”).add_to(map)

Full_merge файл, где по идентификатору региона объединены два моих файла с данными.

Попробую построить карты на основе данных за 2022 год.

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

Есть небольшой минус в первом случае - невозможно самостоятельно выбрать 3 цвета и необходимо использовать системные настройки цветов.

Во втором случае создаю палитру цветов. Вот таким образом:

Colormap = branca.colormap.LinerColormap(
	Vmin=4.00,
	Vmax=5.00,
	caption = “Выполнение плана”,
	colors = [“red”, “yellow”, “green”])

Задам максимальное и минимальное значение самостоятельно. То есть всё, что равно максимальному значению и больше, окрашивается в зелёный, значения попадающие в промежуток – жёлтым и все остальные – красным. Удобство такого способа состоит в том, что можно самостоятельно делать настройки цвета. Выбирать при каких обстоятельствах появляется тот или иной цвет, а также назначить даже розовый или чёрный, если нужно как-то по-особенному выделить.

Можно заметить, что карты похожи, однако, минус функции choropleth не только в ограничениях по палитре цветов, но и в том, что при попытке создания нескольких слоёв появляется несколько подсказок сверху, что значительно ухудшает внешний вид, ведь достаточно одной.

Воспользовавшись функцией GeoJson, сделаю несколько слоёв раскрасив регионы России и получу результат:

Справа есть панель, с помощью которой буду переключать слои, выбирая нужный год. Каждый год – это отдельная choropleth карта, но в данном случае, я объединила их в одну😊

Слои создам таким образом:

y2022= folium.GeoJson(
		full_merge,
		style_function=lambda x: {
			“fillColor”: colormap(x[‘properties’][“compl”])
			if  x[‘properties’][“compl”] is not None
			else “transparent”,
			“color”: “black”,		
			“fillOpacity”: 0.7},
		tooltip=tooltip,
		name=”2022”).add_to(map)
for lat, lon, name, mes in zip(lat, lon, name, mes):
	marker = folium.CircleMarker( location = [lat, lon], 
				tooltip = (‘Доля положительных отзывов:’+ mes+’.’+name) 
				fill_opacity = 0.6, 
				radius = 7,
				fill_color = color_change(mes),
				color = ‘mes’).add_to(y2022)
colormap.add_to(map)
folium.LayerControl(collapsed=False).add_to(map)

Слой – это непосредственно geojson функция, которая создает карту choropleth, далее добавляю точки на этот слой. Также наношу на карту подсказку и добавляю панель, которая будет переключать слои.

DualMap – что это за карта и зачем нужна?

Допустим, человеку необходимо знать и данные по территории и данные по конкретной точке. Очевидный вариант решения – две карты, так как если сделать все на одной, то это будет нечитабельно.

Однако, две карты могут отражаться на одной html странице, именно такую возможность предоставляем dualMap функция. Попробую сделать на моих данных:

1.      Создам основную DualMap карту m

2.      Далее, если нужно что-то добавить на одну карту – пишу add_to(m.m1), если хочу добавить на вторую - add_to(m.m2).

Если написать просто add_to(m), то данные добавятся на обе карты, и они будут полностью идентичными.

1.      Создаю карту и подтягиваю необходимые данные:

map = folium.DualMap(location=[55.000,57.000], zoom_start = 4, tiles = ‘CartoDB position’)
url = “formap.geojson”
df = geopandas.read_file(url)

2.      Добавляю необходимые слои на обе карты.

layer= folium.GeoJson(
		full_merge,
		style_function=lambda x: {
			“fillColor”: colormap(x[‘properties’][“compl”])
			if  x[‘properties’][“compl”] is not None
			else “transparent”,
			“color”: “black”,		
			“fillOpacity”: 0.7},
		tooltip=tooltip,
		name=”2022”).add_to(m.m1)

И получаю следующее:

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

Итак, карта – это удобный инструмент, который при правильном использовании может лаконично и наглядно отразить данные, которые обычно показывают таблицами, графиками или что ещё хуже – просто большим количеством текста.

Существует множество функций, и каждый найдёт то, что ему по душе. Конечно же, библиотека folium имеет некоторые ограничения. Вспомнить, например, ту же функцию choropleth, но их можно обходить при помощи других функций.

Кроме того, даже на этом возможности folium карт не заканчиваются. Можно также добавить текст (заголовок, описание, общая статистка, но придется использовать html и css код). Или в подсказки можно вставить графики (использовать pandas). Вариантов масса, осталось только попробовать😊.

Теги:
Хабы:
Рейтинг0
Комментарии1

Публикации

Истории

Работа

Data Scientist
60 вакансий
Python разработчик
136 вакансий

Ближайшие события