相关文章推荐
还单身的弓箭  ·  在SSIS中使用临时表·  1 年前    · 
愉快的核桃  ·  Android greenDAO ...·  1 年前    · 
近视的墨镜  ·  Python中strip()、lstrip( ...·  1 年前    · 

如何使用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 提供了对任何标记类型的可视化的内置支持。可视化是由vincentaltair库启用的。

为了呈现一些可视化,我们需要一些数据,所以让我们先得到这些数据。

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()
失业率
0AL7.1
1AK6.8
2亚利桑那州8.1
3AR7.2
4CA10.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)

美国各州的失业率(假数据)

做得很好!

热力图是地图的另一个流行选择,它们可以用于多种用途,包括天气状况、污染、人口密度等。

它们是非常强大的工具,在pandasfolium 的帮助下,超级容易建立。让我们以芝加哥市的自行车站为例。我在网上找到了一个有趣的数据集,里面有自行车站的坐标,我们将用它来建立我们的热图。

让我们加载数据。

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()
纬度
041.876511-87.620548
141.867226-87.615355
241.856268-87.613348
341.874053-87.627716
441.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页面上,他们提供了很好的例子,你可以运行,看看如何实现我们今天学到的一些东西。我强烈建议你浏览一下这些例子。

谢谢你的阅读!

FacebookFacebook TwitterTwitter LinkedIn

编程 Python 数据科学 人工智能

  • 私信
    1,253