在本系列中,我们已经确定了四(4)种制作漂亮地理图的方法:
- 交互式地理可视化第1部分-Holoviews
- 交互式地理可视化第2部分-Plotly Express
- 交互式地理可视化第3部分-Plotly Graph Objects(Go)
- 交互式地理可视化第4部分-Altair
在本文中,我们将学习如何使用我最喜欢的地理可视化软件包Folium创建一个类似但更自定义的绘图。
我还将向你展示如何使用Folium的“标记群集”功能,它为我们的geoviz提供了即时升级。
FOLIUM与PLOTLY
Folium可能是Python用户使用最广泛的地理可视化之一,他们打算创建更多自定义地图供个人甚至商业使用。
它建立在leaflet.js,可以比我们迄今为止所介绍的任何包都能满足更多的映射需求。
另一方面,Plotly的优点是在语法和扩展使用上更容易,尤其是它的高级绘图库Plotly Express。你也可以用这个包做很多事情,但不如用Folium做得多。
编码
确保首先安装folium:
pip install folium
环境
与其他人一样,让我们加载我们的包:
import numpy as np
import pandas as pd
import folium
from folium.plugins import MarkerCluster
import geopandas as gpd
from shapely import geometry
from shapely.geometry import Point
from shapely.geometry.polygon import Polygon
加载数据集
df = pd.read_csv('data/Coffee Brands Footprint.csv',
index_col=0)
df.head()
加载数据集后,我们可以开始创建Folium地图了!
FOLIUM代码
初始化地图
以下代码初始化地图:
m = folium.Map(location=[14.577924, 121.073972],
tiles="cartodbpositron") #Latitude first before Longitude
Folium.Map具有可以控制初始缩放的参数和控制贴图的磁贴。我们选择了cartodbpostron,因为它更接近我们其他包的底图。
初始化MARKERCLUSTER
Folium的MarkerCluster插件是对我们的geoviz的一个很好的补充,因为它可以为我们提供一些即时的见解。这是一种簇形式,因此你可以立即评估哪些区域有你的研究对象。
另一个明显的好处是,它有助于保持地图的整洁,因为它不会因为太多的标记而混乱。
要启动MarkerCluster对象:
marker_cluster = MarkerCluster(control=False).add_to(m)
我们将其存储在一个名为marker_cluster的变量中,稍后我们将调用它,或者添加到它。
不要忘记将这个MarkerCluster对象添加到名为m的地图对象中。
初始化标记
要为此启动标记,我们需要做一个初步步骤,将其存储在元组中或列出我们的地理代码。
#We need this cause apparently, folium can recognize not a geoseries but a normal tuple/list
df.reset_index(drop=True, inplace=True)
df['geocode'] = [[df['lat'][i],df['lng'][i]] for i in range(len(df)) ]
现在,让我们用定制的工具提示创建标记,显示咖啡店的品牌或名称。
for point in df.index: # loop through the plots
html = """
<h3>{name}</h3><br>
"""
popup_contents = folium.Html(html.format(name = df.loc[point, 'name']),
script = True)
popup = folium.Popup(popup_contents, max_width=1500)
# mark every addresses in the map from the data
folium.Marker(df['geocode'][point],
popup=popup).add_to(marker_cluster)
让我们分解上面的代码(步骤1-3用于弹出内容,步骤4用于标记):
- HTML字符串将包含我们的工具提示,单击散点图中的点时将显示该工具提示。
- 因此,我们的folium.HTML对象中会有这条空字符串。
- 因此,我们将其存储在folium.Popup可以进一步定制的对象中。
- 最后,为这些商店添加标记,folium.Marker为每个位置添加一个标记,为了确保这些标记是集群的,你需要将其添加到我们创建的Marker_cluster变量中。
为了简单地显示和聚集这些咖啡店,我们完成了!
然而,如果你想实现我们曾经使用过的彩色标记,就像在过去的文章中一样,那么我们需要选择不同的标记-圆形标记。
添加彩色圆圈标记以改进标记
你可以添加我们之前的标记,也可以选择添加圆形标记。下面是执行此操作的代码:
我们首先需要声明我们的品牌及其颜色:
#Let's Create a Color Dictionary for the Markers
coffee_brands = ["Coffee Bean and Tea Leaf", "Starbucks", "Tim Hortons", "Coffee Project"]
color_dict = {
"Starbucks": ' #00704A',
"Coffee Bean and Tea Leaf": '#362d26',
"Coffee Project": '#654321',
"Tim Hortons": '#dd0f2d'
}
接下来,我们需要迭代每个品牌并迭代添加彩色圆圈标记。请注意,这段代码替换了我们的代码folium.Marker。
#Since we need to add a filter for this, we need to add them by brand:
for brand in coffee_brands:
df_i = df[df['brand']==brand]
df_i.loc[:, "color"] = color_dict[brand]
for index, row in df_i.iterrows():
####### START OF THE SAME CODE FOR POPUP #######
html = """
<h3>{name}</h3><br>
"""
popup_contents = folium.Html(html.format(name = row['name']),
script = True)
popup = folium.Popup(popup_contents, max_width=1500)
####### END OF THE SAME CODE FOR POPUP #######
folium.vector_layers.CircleMarker(radius = 8,
location = (row.lat,
row.lng),
color = row.color,
fill = True,
fill_color = row.color,
name = brand,
popup=popup,
control = True,
overlay = True
).add_to(marker_cluster)
让我们分解上面的代码:
- 你可能已经注意到,添加标记是Folium的一个迭代过程。根本没有办法批量添加它们,因此出于我们的目的,它们必须是循环的一部分。因此,第一步是对品牌进行分组或筛选,以便为品牌分配颜色。
- 过滤品牌后,你可以创建另一个循环,从而增加市场。请注意,弹出内容必须添加到每个标记中,因此它们也是循环的一部分,并且具有与上面相同的代码。
- 最后,我们添加必要的参数,例如半径的大小、填充颜色,这些参数将遵循循环开始时分配的颜色。
最后
正如你所看到的,我们可以用folium做的事情范围是惊人的。如果你有为地图设计的特定磁贴,也可以自定义磁贴。
一个在很多方面都很有用的自定义是添加工具提示。正如我们所看到的,可以编写HTML代码以包含更多信息,这就是为什么这也是用于部署商业项目的包。
感谢阅读!