用python实现热力图可视化

在数据分析过程中,有时候需要一些数据以热力图的形式进行显示出来,从而能够更加直观地查看分析数据。下面以实际情况为例,展示热力图在两种不同情况下的应用。

一、识别图片中行人的关注点,并绘制热力图

我们在做超市商品卖场力分析的时候,可以通过分析超市密集人群的关注点,生成热力图,给厂商直观的视觉感受。步骤分为以下几步:
1、首先用行人检测技术检测出超市场景中的顾客,再用眼动追踪技术得到顾客眼睛凝视点的中心坐标。
2、将所有凝视点的中心坐标放入一个list类型的变量data中,即data = [[x1,y1],[x2,y2] …],或者data=[[x1,y1,z1],[x2,y2,z2]…],其中z点代表(x,y)点所在位置的权重。
3、绘制热力图,并将热力图加权叠加到原图上。
简单代码展示如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import cv2
import numpy as np
from PIL import Image
from pyheatmap.heatmap import HeatMap
def apply_heatmap(image,data):
  '''image是原图,data是坐标'''
  '''创建一个新的与原图大小一致的图像,color为0背景为黑色。这里这样做是因为在绘制热力图的时候如果不选择背景图,画出来的图与原图大小不一致(根据点的坐标来的),导致无法对热力图和原图进行加权叠加,因此,这里我新建了一张背景图。'''
    image1=cv2.imread(image)
    background = Image.new("RGB", (image1.shape[1], image1.shape[0]), color=0)
  # 开始绘制热度图
    hm = HeatMap(data)
    hit_img = hm.heatmap(base=background, r = 100) # background为背景图片,r是半径,默认为10
    hit_img = cv2.cvtColor(np.asarray(hit_img),cv2.COLOR_RGB2BGR)#Image格式转换成cv2格式
    overlay = image1.copy()
    alpha = 0.5 # 设置覆盖图片的透明度
    cv2.rectangle(overlay, (0, 0), (image1.shape[1], image1.shape[0]), (255, 0, 0), -1) # 设置蓝色为热度图基本色蓝色
    image2 = cv2.addWeighted(overlay, alpha, image1, 1-alpha, 0) # 将背景热度图覆盖到原图
    image3 = cv2.addWeighted(hit_img, alpha, image2, 1-alpha, 0) # 将热度图覆盖到原图
    cv2.imshow('ru',image3)
    cv2.imwrite('rtj91.jpg',image3)
    cv2.waitKey(0)
    return image3
if __name__=='__main__':
    apply_heatmap('8.jpg',[[600,436,30],[296,416,50],[270,400,32],[280,426,10],[580,440,30],[360,430,36],[540,460,50],[482,469,5],
    [400,463,8],[320,453,26],[200,1140,20],[180,1136,10],[120,1130,10],[90,1126,20]])#数据来自通过眼动追踪技术生成的顾客凝视点中心坐标

原图(取自佳乐家超市):
在这里插入图片描述
经过处理后生成的热力图:
在这里插入图片描述
可以看出,顾客的关注点主要在带铁罐和塑料盒装的德芙巧克力上,其中,放在货架高处(与一般顾客人眼高度相近的位置)的德芙巧克力要比放在货架底部位置的德芙巧克力受到的关注点要更高一些。

二、在地图上进行热力图绘制

在热力图绘制过程中,有很多种情况是直接在中国地图或者世界地图上甚至于是在某个城市的地图上进行热力图绘制,这时可以用到folium,folium是python的一个用来绘制地图,并在地图上生成热力图的工具。
例:今年国庆节以来有不少朋友向我买莱阳梨,这其中大多数的莱阳梨是以邮寄的形式寄出,因此,可以通过买家给出的地址得到相关地址的经纬度,从而在中国地图上生成热力图,显示出莱阳梨售往了哪些地方。

1
2
3
4
5
6
7
8
9
10
11
12
13
import numpy as np
import pandas as pd
import folium
from folium.plugins import HeatMap
posi=pd.read_excel('laiyangli.xlsx')#读取文件中的信息
num=18 #买家数量
lat=np.array(posi['lat'][0:num])#选取纬度信息
lon=np.array(posi['lon'][0:num])#选取经度信息
data1=[[lat[i],lon[i]] for i in range(num)]#生成热力图需要的经纬度坐标
map_osm=folium.Map(location=[35,110],zoom_start=5)#绘制Map,开始缩放程度是5倍中国
HeatMap(data1).add_to(map_osm)#将热力图添加到前面建立的Map里
file_path=r"D:\Files\python\ditu\lyl.html"#地图生成路径,其文件类型为html格式
map_osm.save(file_path)#保存html文件,没网不能用,只能在有网的时候打开

结果:
在这里插入图片描述
通过热力图显示买家所处的位置,一目了然!