前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用Python制作3个简易地图

使用Python制作3个简易地图

作者头像
代码医生工作室
发布2019-06-21 17:38:08
4.1K0
发布2019-06-21 17:38:08
举报
文章被收录于专栏:相约机器人相约机器人

作者 | Ritvik Kharkar

来源 | Medium

编辑 | 代码医生团队

在处理地理空间数据时,经常需要以最自然的方式可视化这些数据:地图。如果可以使用Python快速轻松地创建数据的交互式地图,在本教程中使用洛杉矶县所有星巴克位置的数据集。在文章的最后将能够创建:

  • 洛杉矶县所有星巴克酒店的基本点图
  • 一个等值线图,根据每个星巴克中包含的星巴克数量,在洛杉矶县的邮政编码中加以遮蔽
  • 一个热图这凸显了洛杉矶县星巴克的“热点”

你会需要:

  • Python包pandas。这用于在Python中轻松操作数据
  • Python包folium。这用于非常轻松地创建地图
  • 在洛杉矶县纬度/星巴克的经度电子表格

https://github.com/ritvikmath/StarbucksStoreScraping/blob/master/starbucksInLACounty.csv

  • LA县的GeoJSON(基本上是描述复杂形状的json)

https://github.com/ritvikmath/StarbucksStoreScraping/blob/master/laMap.geojson

  • LA县所有邮政编码的GeoJSON

https://github.com/ritvikmath/StarbucksStoreScraping/blob/master/laZips.geojson

为了熟悉数据,这里是前几行的快照:

只需要担心此分析的纬度,经度和zip字段。

以下是所需的Python导入,加载星巴克数据以及加载LA County GeoJSON

代码语言:javascript
复制
import folium
import pandas as pd
import json
from folium import plugins
 
df = pd.read_csv('starbucksInLACounty.csv')
 
with open('laMap.geojson') as f:
    laArea = json.load(f)

基本点图

从数据框中的纬度/经度对创建洛杉矶县所有星巴克的基本点图非常简单。

代码语言:javascript
复制
#initialize the map around LA County
laMap = folium.Map(location=[34.0522,-118.2437], tiles='Stamen Toner', zoom_start=9)
 
#add the shape of LA County to the map
folium.GeoJson(laArea).add_to(laMap)
 
#for each row in the Starbucks dataset, plot the corresponding latitude and longitude on the map
for i,row in df.iterrows():
    folium.CircleMarker((row.latitude,row.longitude), radius=3, weight=2, color='red', fill_color='red', fill_opacity=.5).add_to(laMap)
 
#save the map as an html    
laMap.save('laPointMap.html')

打开laPointMap.html,看到以下地图:

可以清楚地看到洛杉矶县的所有星巴克都是洛杉矶县内的小红点。当然可以自定义点的任何颜色和形状。

Choropleth地图

在使用Python中的地图之前,实际上不知道什么是等值线图,但事实证明它们在可视化聚合的地理空间数据方面非常有用。

等值线图将回答这个问题:“洛杉矶县哪些邮政编码的星巴克最多?”。基于其他变量的值,在案例中星巴克商店的数量,等值线图基本上在每个邮政编码中着色。

首先回顾创建一个所需的基本代码:

代码语言:javascript
复制
#group the starbucks dataframe by zip code and count the number of stores in each zip code
numStoresSeries = df.groupby('zip').count().id
#initialize an empty dataframe to store this new data
numStoresByZip = pd.DataFrame()
#populate the new dataframe with a 'zipcode' column and a 'numStores' column
numStoresByZip['zipcode'] = [str(i) for i in numStoresSeries.index]
numStoresByZip['numStores'] = numStoresSeries.values
 
#initialize the LA County map
laMap = folium.Map(location=[34.0522,-118.2437], tiles='Stamen Toner', zoom_start=9)
 
#draw the choropleth map. These are the key components:
#--geo_path: the geojson which you want to draw on the map [in our case it is the zipcodes in LA County]
 
#--data: the pandas dataframe which contains the zipcode information
# AND the values of the variable you want to plot on the choropleth
 
#--columns: the columns from the dataframe that you want to use
#[this should include a geospatial column [zipcode] and a variable [numStores]
 
#--key_on: the common key between one of your columns and an attribute in the geojson.
#This is how python knows which dataframe row matches up to which zipcode in the geojson
 
laMap.choropleth(geo_path='laZips.geojson', data=numStoresByZip, columns=['zipcode', 'numStores'], \
                 key_on='feature.properties.zipcode', fill_color='YlGn', fill_opacity=1)
 
laMap.save('laChoropleth.html')

由于个人发现更难理解如何将所有组件放到适当的位置,看一下单独的视觉效果,看看它是如何工作的。

例如,等值线需要知道填写邮政编码90001的颜色。它检查由所引用的数据帧大熊猫数据字段,搜索KEY_ON为邮政编码列,并发现中列出的其他列的列是numStores。然后它知道它需要在邮政编码90001中填写对应于3个商店的颜色。

然后它会查看geo_path字段引用的GeoJSON ,并找到邮政编码90001及其相关的形状信息,该信息告诉它在地图上为该邮政编码绘制哪种形状。通过这些链接,它具有所有必要的信息。来看看laChoropleth.html中产生的等值线!

看到它顶部有一个漂亮的彩条供参考。

热图

在上面的等值线图中,看到南洛杉矶县的地区似乎总体上有更多的星巴克商店,可以找出附近有很多星巴克店的地方吗?创建一个热图来突出洛杉矶县的星巴克“热点”。

代码语言:javascript
复制
#initialize the LA County map
laMap = folium.Map(location=[34.0522,-118.2437], tiles='Stamen Toner', zoom_start=9)
 
#add the shape of LA County to the map
folium.GeoJson(laArea).add_to(laMap)
 
#for each row in the Starbucks dataset, plot the corresponding latitude and longitude on the map
for i,row in df.iterrows():
    folium.CircleMarker((row.latitude,row.longitude), radius=3, weight=2, color='red', fill_color='red', fill_opacity=.5).add_to(laMap)
 
#add the heatmap. The core parameters are:
#--data: a list of points of the form (latitude, longitude) indicating locations of Starbucks stores
 
#--radius: how big each circle will be around each Starbucks store
 
#--blur: the degree to which the circles blend together in the heatmap
 
laMap.add_children(plugins.HeatMap(data=df[['latitude', 'longitude']].as_matrix(), radius=25, blur=10))
 
#save the map as an html
laMap.save('laHeatmap.html')

热图中需要一些试验和错误的主要参数是半径,它控制每个星巴克商店周围的圆圈大小以及控制圆圈“混合”在一起的模糊程度。

更高的半径意味着任何给定的星巴克影响更广泛的区域,更高的模糊意味着两个相距更远的星巴克仍然可以贡献一个热点。参数由您决定!

laHeatmap.html中看到热图的图片。

似乎一切都是红色的。如果放大热图可能会更有价值。放大一点看看是否可以识别更具体的热点。

从上面的地图可以清楚地看到,在地图中有一些热点和一些非热点。最引人注目的是洛杉矶市中心。

唯一遗憾的是,还没有找到一种方法将这些地图的实际交互式版本嵌入到Medium帖子中,所以只能显示截图。强烈建议通过此帖子运行一小段代码,以便自己使用交互式地图。这是一次完全不同的体验。

包含此分析中使用的所有代码的完整笔记本可以在GitHub上找到。

https://github.com/ritvikmath/StarbucksStoreScraping/blob/master/MakingLAMaps.ipynb

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-04-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 相约机器人 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档