如何使用Python和Folium在地图上绘制你的数据
利用Python的数据和Leaflet.js在地图上的力量,创建丰富的地图可视化。
最后更新于2021年4月23日作者: Juan Cruz Martinez
Folium 是一个Python包,它将Python提供的所有工具与 Leaflet javascript库结合起来,以创建丰富的互动地图。
像我的文章一样,我提供了一个Google colab jupyter笔记本,里面有所有的代码和结果,你可以 在这里 访问。
创建一个基本的地图
在我们开始构建任何东西之前,让我们先安装一些我们将在整个教程中使用的库。你可以使用任何打包工具,我将提供pipenv和pip prepending
!
的例子,这样它就能在像Google colab这样的jupyter笔记本上工作。
pipenv install folium pandas
!pip install folium pandas
在安装了这些库之后,创建一个地图只需要简单的一行代码。
import folium
folium.Map(location=[48.130518, 11.5364172], zoom_start=12)
这将自动生成一个交互式地图,并将其输出到jupyter笔记本上,在那里你将能够与它进行交互。函数Map
,需要一些可选的参数,在我们的例子中,我们要发送位置(坐标)和一个默认的缩放级别。
如果一切顺利的话,你应该看到一个像这样的地图。
尽管这已经非常令人兴奋了,但我们并没有用它做什么特别的事情。folium
的真正力量来自于将库的制图能力与 Python 的数据操作能力相结合,所以让我们开始做一些这样的事情。
我们可以为我们的地图添加的一个基本功能是标记地方的能力,这样可以很容易地找到它们,或者突出重要信息。
这可以通过folium
中的Marker
函数轻松实现,我们接下来演示一下。
m = folium.Map(location=[48.218871184761596, 11.624819877497147], zoom_start=15)
tooltip = "Click Here For More Info"
marker = folium.Marker(
location=[48.218871184761596, 11.624819877497147],
popup="<stong>Allianz Arena</stong>",
tooltip=tooltip)
marker.add_to(m)
与第一个例子类似,首先我们创建一个地图对象,但是我们也创建一个标记对象。标记对象是通过传递点的坐标来创建的,当有人点击标记时,我们想在弹出的窗口中显示什么,以及标记的工具提示等选项。
带标记的地图
标记有大量的配置选项,而且由于标记的弹出窗口期望有一个HTML,所以有很多可能性。但是,如果我们想在弹出窗口中显示图表怎么办?有什么简单的方法吗?
用于标记的图表弹出窗口
Folium
提供了对任何标记类型的可视化的内置支持。可视化是由vincent和altair库启用的。
为了呈现一些可视化,我们需要一些数据,所以让我们先得到这些数据。
import json
import requests
url = (
"https://raw.githubusercontent.com/python-visualization/folium/master/examples/data"
data = json.loads(requests.get(f"{url}/vis1.json").text)
接下来,让我们把数据绘制在一个标记中。
m = folium.Map(location=[48.218871184761596, 11.624819877497147], zoom_start=15, tiles="Stamen Terrain")
marker = folium.Marker(
location=[48.218871184761596, 11.624819877497147],
popup=folium.Popup(max_width=450).add_child(
folium.Vega(data, width=450, height=250)
marker.add_to(m)
带标记的地图和绘图
太棒了,但是我们能不能真正改变标记本身,而不仅仅是弹出的窗口?简短的回答是可以,而且几乎可以用任何东西。
Marker
函数允许一些参数化,从改变预定义图标库中的标记图标、形状到使用HTML建立你自己的标记,在这篇文章中,我们将看到3种情况的例子,首先使用预定义图标。
m = folium.Map(location=[48.218871184761596, 11.624819877497147], zoom_start=15)
tooltip = "Click Here For More Info"
marker = folium.Marker(
location=[48.218871184761596, 11.624819877497147],
icon=folium.Icon(icon="cloud"),
popup="<stong>Allianz Arena</stong>",
tooltip=tooltip)
marker.add_to(m)
带有图标标记的地图
回到我们简单的安联球场的例子,我们现在已经用云彩改变了标记的图标,但是这些图标是从哪里来的?有什么可供选择的?
这些图标来自bootstrap库,但你也可以使用font awesome。
接下来让我们使用形状,比如圆形来建立我们的标记。
m = folium.Map(location=[48.218871184761596, 11.624819877497147], zoom_start=15)
tooltip = "Click Here For More Info"
marker = folium.CircleMarker(
location=[48.218871184761596, 11.624819877497147],
radius=50,
popup="<stong>Allianz Arena</stong>",
tooltip=tooltip)
marker.add_to(m)
带有圆形标记的地图
最后,我们可以使用HTML来建立我们想要的任何类型的标记。
m = folium.Map(location=[48.218871184761596, 11.624819877497147], zoom_start=15)
tooltip = "Click Here For More Info"
marker = folium.Marker(
location=[48.218871184761596, 11.624819877497147],
popup="<stong>Allianz Arena</stong>",
icon=folium.DivIcon(html=f"""
<div style="color:#f00;background:#fff;width:60px;text-align:center;">MARKER</div>
"""),
tooltip=tooltip)
marker.add_to(m)
带有HTML标记的地图
在这最后一个例子中,我们使用HTML创建了一个DIV元素,并放置了一些文本作为标记,但我们也可以使用SVG并呈现任何你想要的东西。只要记住将你的HTML居中,使标记在正确的位置,这是我在例子中没有做到的。
Choropleth地图
Choropleth地图是流行的专题地图,用于在预定的地理区域(即国家或州)上通过各种阴影图案或符号来表示统计数据。它们善于利用数据来轻松地表示所需测量的变异性,跨越一个区域。
为了创建脉络图,我们需要使用2种类型的数据,即我们想要表达的色调或颜色的统计数据,以及地理空间数据。
在我们的例子中,我们将使用美国各州来定义区域,以及美国的失业统计数据(不是真实数据)。
让我们从绘制地理区域,也就是美国各州开始。
data_url = (
"https://raw.githubusercontent.com/python-visualization/folium/master/examples/data"
us_states_url = f"{data_url}/us-states.json"
m = folium.Map([43, -100], zoom_start=4)
folium.GeoJson(us_states_url).add_to(m)
我们的新地图现在包含一个突出美国各州的叠加图,但我们可以做得更多,我们现在可以使用我们拥有的关于美国失业率的统计信息,突出显示失业率较高和较低的州。
首先,让我们看看这些数据是什么样子的。
import pandas as pd
us_unemployment_url = f"{data_url}/US_Unemployment_Oct2012.csv"
unemployment = pd.read_csv(us_unemployment_url)
unemployment.head()
州 失业率 0 AL 7.1 1 AK 6.8 2 亚利桑那州 8.1 3 AR 7.2 4 CA 10.1
数据很简单,一栏是州,另一栏是失业率。
有了这些数据,我们就可以开始为我们的地图着色了。
m = folium.Map(location=[48, -102], zoom_start=3)
folium.Choropleth(
geo_data=us_states,
name='choropleth',
data=unemployment,
columns=['State', 'Unemployment'],
key_on='feature.id',
fill_color='YlGn',
fill_opacity=0.7,
line_opacity=0.2,
legend_name='Unemployment Rate %'
).add_to(m)
美国各州的失业率(假数据)
做得很好!
热力图是地图的另一个流行选择,它们可以用于多种用途,包括天气状况、污染、人口密度等。
它们是非常强大的工具,在pandas
和folium
的帮助下,超级容易建立。让我们以芝加哥市的自行车站为例。我在网上找到了一个有趣的数据集,里面有自行车站的坐标,我们将用它来建立我们的热图。
让我们加载数据。
stations_url = 'https://gbfs.divvybikes.com/gbfs/en/station_information.json'
stations = json.loads(requests.get(stations_url).text)['data']['stations']
stations = pd.json_normalize(stations)
stations = stations[['lat', 'lon']]
stations.head()
纬度 长 0 41.876511 -87.620548 1 41.867226 -87.615355 2 41.856268 -87.613348 3 41.874053 -87.627716 4 41.886976 -87.612813
自行车站的数据有多列,有大量的数据,但是对于我们的目的,我们只需要坐标,所以我们删除了其他的数据。现在,每一行都代表了一组自行车站所在的坐标(经度和纬度)。
接下来我们将建立一个热图,以突出城市中自行车站比较集中的区域。
from folium import plugins
m = folium.Map([41.8781, -87.6298], zoom_start=11)
# convert to (n, 2) nd-array format for heatmap
stationArr = stations.values
# plot heatmap
m.add_child(plugins.HeatMap(stationArr, radius=15))
带热力图的地图
伟大的工作!热力图的秘密是简单地使用一个来自folium
的插件,传递一个包含每个站点的经纬度和半径的矩阵。
最后,在结束之前,我想强调folium
的另一个功能,即地图瓦片。到目前为止,我们只使用了一种地图的渲染方式,但是我们可以使用很多选项,每一种都会使地图看起来不同。
让我们来看看一些例子。
m = folium.Map(location=[30.4407159,-66.6017203], zoom_start=3)
folium.TileLayer('stamenterrain').add_to(m)
带有花蕊地形层的地图
m = folium.Map(location=[30.4407159,-66.6017203], zoom_start=3)
folium.TileLayer('stamentoner').add_to(m)
带有花蕊墨粉层的地图
或者更好的是,你可以让用户选择通过使用另一个功能,即layerControl
m = folium.Map(location=[30.4407159,-66.6017203], zoom_start=4)
# Add tiles
folium.TileLayer('stamentoner').add_to(m)
folium.TileLayer('stamenwatercolor').add_to(m)
folium.TileLayer('cartodbpositron').add_to(m)
folium.TileLayer('openstreetmap').add_to(m)
# Add the option to switch tiles
folium.LayerControl().add_to(m)
带有多层的地图
你现在可以看到在这个地图上,在右上方,有一个图层选择,用户可以用它来切换地砖。
写这篇文章超级有趣!Folium
,提供了很多配置选项,有大量的机会来构建伟大的地图,我一定会继续玩下去,做出一些有趣的东西。
在研究这个话题的时候,我遇到了一些问题,因为文档不是很好,然而,在他们的github页面上,他们提供了很好的例子,你可以运行,看看如何实现我们今天学到的一些东西。我强烈建议你浏览一下这些例子。
谢谢你的阅读!