直接上图
现在很多的数据分析中,都会用热力图来直观展示特征群体的分布情况,为后期的营销运营等服务。
本篇主要介绍,在经过前期数据整理后,利用python和百度地图API,如何根据拿到的地址列表绘制出热力图。
整个过程的思路大体分为部分:
1、读入已经整理好的地址列表,调用百度API功能取出各个地址对应的经纬度;
2、将所有地址及地址对应的经纬度,存入一个csv文件备份;
3、将经纬度数据整理成热力图html需要的格式;
4、按照热力图html格式,整理完成并打开。
百度API是什么?百度地图API是为开发者免费提供的一套基于百度地图服务的应用接口,基于这些应用接口,我们就可以很方便地将实际地址转换为经纬度坐标。
如下图,在百度拾取坐标系统(http://api.map.baidu.com/lbsapi/getpoint/index.html)中,直接输入地址,点击“百度一下”,在右边选择对应的目标,即可复制出经纬度了,咱们接下来的经纬度就是这样来的。
使用百度地图API功能,需要先在百度开发者平台上http://lbsyun.baidu.com/,注册,然后申请密匙,应用名称自定义,应用类型选择浏览器端即可。(注意,如果调用代码是提示{"status":220,"message":"APP Referer校验失败"},说明浏览器的AK没在白名单中,最简单粗暴的方式,就是直接将白名单定为*,意思是所有的IP都能调用此API,有一丢丢危险,慎用哈!)
定义一个函数取经纬度
from bs4 import BeautifulSoup
import requests
import csv
import re
#调用百度地图API查询位置
def getlocation(name):
bdurl='http://api.map.baidu.com/geocoder/v2/?address='
output='json'
ak='应用AK'#输入刚刚申请的AK
callback='showLocation'
uri=bdurl+name+'&output=t'+output+'&ak='+ak+'&callback='+callback
headers = {'Connection': 'close'}
res=requests.get(uri,headers = headers)
s=BeautifulSoup(res.text,'lxml')
lng=s.find('lng')#经度
lat=s.find('lat')#纬度
if lng:
return lng.get_text()+','+lat.get_text()
一开始输入的地址文件格式如下图左边红色部分,取经纬度后备份文件格式如右边的绿色部分
百度热力图的经纬度格式如下: 。lng表示经度; lat表示纬度; count表示热力值,这个数越大,最终在图上的亮度越高,经过本人测试,对于单点,热力值=10时在地图上才可见,热力值>=100时,亮度达到最高,由于本案中每个地址仅出现一次,可以默认这个热力值为30即可
需要将获取的经纬度整理成以上格式,代码如下:
#将坐标按照百度API的格式进行整理
import csv
reader=csv.reader(open('yyc.csv'))
for row in reader:
loc=row[1]
sloc=loc.split(',')
lng=''
lat=''
if len(sloc)==2:#第一行是列名需要做判断
lng=sloc[0]
lat=sloc[1]
count='30'
#row[2]
out='{\"lng\":'+lng+',\"lat\":'+lat+',\"count\":'+count+'},'
print(out)
from bs4 import BeautifulSoup
import requests
import csv
import re
#调用百度地图API查询位置
def getlocation(name):
bdurl='http://api.map.baidu.com/geocoder/v2/?address='
output='json'
ak='应用AK'#输入百度地图上申请的密匙,代码如果给别人,这个密钥一定要删掉
callback='showLocation'
uri=bdurl+name+'&output=t'+output+'&ak='+ak+'&callback='+callback
headers = {'Connection': 'close'}
res=requests.get(uri,headers = headers)
s=BeautifulSoup(res.text,'lxml')
lng=s.find('lng')#经度
lat=s.find('lat')#纬度
if lng:
return lng.get_text()+','+lat.get_text()
#将csv文件中的地址读取出来并构建成一个list
with open('donghuicheng.csv','r',newline='',encoding='utf-8') as csvfile:
reader = csv.reader(csvfile)
data = []
for row in reader:
data.append(row[0])
#print(data)
#houses=[]#定义列表用于存放房子的信息
#特别注意一个问题,当查询的数据量大时(len(p)约>900时),会出现ConnectionAbortedError问题,查了一下有人说了异步提交的问题
#也有人说是电脑防火墙等软件的问题阻止的,经过自己的尝试,最后锁定是并发问题,普通API用户的并发是60/秒,认证用户是160/秒,需要设置休眠
import time
n=1
num=len(data)-1#去掉标题行
file=open('yyc.csv', 'w', newline='')#自己定义一个文件yyc,用于备份保存地址、经纬度信息
headers = ['name', 'loc', 'count']
writers = csv.DictWriter(file, headers)
writers.writeheader()
while n
以上代码执行结果会得到符合热力图html格式的经纬度,接下来把这些经纬度复制到html模板即可。
把上面代码获取的内容,复制到下面var points中即可
热力图功能示例
将这个html文件在浏览器中打开,就是本篇中第一个图