Python中国社区  »  Python

从零开始学Python数据分析【18】-- matplotlib(热力图)

Python爱好者社区 • 10 月前 • 377 次点击  

作者:刘顺祥

个人微信公众号:每天进步一点点2015


前文传送门:

从零开始学Python数据分析【1】--数据类型及结构

从零开始学Python数据分析【2】-- 数值计算及正则表达式

从零开始学Python数据分析【3】-- 控制流与自定义函数

从零开始学Python数据分析【4】-- numpy

从零开始学Python数据分析【5】-- pandas(序列部分)

从零开始学Python数据分析【6】-- pandas(数据框部分01)

从零开始学Python数据分析【7】-- pandas(数据框部分02)

从零开始学Python数据分析【8】-- pandas(数据框部分03)

从零开始学Python数据分析【9】-- pandas(数据框部分04)

从零开始学Python数据分析【10】-- matplotlib(条形图)

从零开始学Python数据分析【11】-- matplotlib(饼图)

从零开始学Python数据分析【12】-- matplotlib(箱线图)

从零开始学Python数据分析【13】-- matplotlib(直方图)

从零开始学Python数据分析【14】-- matplotlib(折线图)

从零开始学Python数据分析【15】-- matplotlib(散点图)

从零开始学Python数据分析【16】-- matplotlib(雷达图)

从零开始学Python数据分析【17】-- matplotlib(面积图)


前言


       新讲开始啦~今天我们带给大家带来的是关于如何绘制填充表格热力图的知识点,先给大家看一下效果图。


       从效果图里我们可以发现,所谓的填充表格热力图就是将原本为数字表(数组)的单元格以颜色来填充,颜色的深浅表示数值的大小。我想,对于这样的图来说,总比直接看密密麻麻的数值表要轻松的多吧,毕竟颜色感官比数字感官要直接,要具有更强的冲击。除了填充表格热力图,还有更为常见的地图热力图等。那填充表格热力图是如何应用Python来实现的呢?就让我们手把手的进行讲解吧~

数据采集—气温数据


       在绘图之前,需要说明一下绘图的数据源,案例中的数据是通过爬虫获取的,用的是上海9月份每天的最高气温,即生成两列数据(日期和最高气温)。在有了原始数据的基础上,还需要对数据进行清洗和整理,关于这部分是做任何数据分析或可视化都必经的坎。详细可以通过下面的代码来了解:

  • 步骤一:数据采集

# ========== Python3 + Jupyter ========== #
# 导入所需的第三方包
import datetime
import calendar
import requests
from bs4 import BeautifulSoup
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# 采集数据
# 上海2017年9月份历史气温数据
url = 'http://lishi.tianqi.com/shanghai/201709.html'

# 发送爬虫请求
response = requests.get(url).text
# 解析源代码
soup = BeautifulSoup(response, 'html.parser')
# 根据HTML标记语言,查询目标标记下的数据
datas = soup.findAll('div',{'class':'tqtongji2'})[0].findAll('ul')[1:]

# 抓取日期数据
date = [i.findAll('li')[0].text for i in datas]
# 抓取最高温数据
high = [i.findAll('li')[1].text for i in datas]

# 创建数据框
df = pd.DataFrame({'date':date, 'high':high})
# 变量类型
df.dtypes


  • 步骤二:数据整理

# 将date变量转换为日期类型
df.date = pd.to_datetime(df.date)
# 将high变量转换成数值型
df.high = df.high.astype('int')

# 数据处理
# 由日期型数据衍生出weekday
df['weekday'] = df.date.apply(pd.datetime.weekday)

# 由日期型数据计算week_of_month,即当前日期在本月中是第几周
# 由于没有现成的函数,这里自定义一个函数来计算week_of_month
def week_of_month(tgtdate):    # 由日期型参数tgtdate计算该月的天数    days_this_month = calendar.mdays[tgtdate.month]    # 通过循环当月的所有天数,找出第二周的第一个日期    for i in range(1, days_this_month + 1):        d = datetime.datetime(tgtdate.year, tgtdate.month, i)        
       if d.day - d.weekday() > 0:            startdate = d            
           break    # 返回日期所属月份的第一周    return (tgtdate - startdate).days //7 + 1

df['week_of_month'] = df.date.apply(week_of_month) df.head()

到此为止,我们就完成了数据的采集和清洗过程,接下来我们就可以借助该数据完成填充热力(日历)图的绘制。

填充热力图的绘制


基于matplotlib绘制热力图

       其实,我需要绘制的是一个数据表,只不过把表中的每一个单元格用颜色填充起来。而表的结构是:列代表周一到周日,行代表9月份第一周到第五周。很显然,我们刚刚完成的数据并不符合这样的结构,故需要通过pandas模块中的pivot_table函数制作一个透视表,然后才可以绘图。关于热力图,我们可以使用matplotlib模块中的pcolor函数,具体我们可以看下方的绘图语句:

# ==================绘图前的数据整理=====================
# 构建数据表(日历)
target = pd.pivot_table(data = df.iloc[:,1:],values = 'high',                        index = 'week_of_month', columns = 'weekday') target

# 缺失值填充(不填充的话pcolor函数无法绘制)
target.fillna(0,inplace=True)
# 删除表格的索引名称
target.index.name = None
# 对索引排序(为了让“第一周”到“第五周”的刻度从y轴的高到底显示)
target.sort_index(ascending=False, inplace=True)

# ======================开始绘图=========================
# 设置中文和负号正常显示
plt.rcParams['font.sans-serif'] = 'Microsoft YaHei'
plt.rcParams['axes.unicode_minus'] = False

plt.pcolor(target, # 指定绘图数据           cmap=plt.cm.Blues, # 指定填充色           edgecolors = 'white' # 指点单元格之间的边框色          )

# 添加x轴和y轴刻度标签(加0.5是为了让刻度标签居中显示)
plt.xticks(np.arange(7)+0.5,['周一','周二','周三','周四','周五','周六','周日']) plt.yticks(np.arange(5)+0.5,['第五周','第四周','第三周','第二周','第一周'])

# 消除图框顶部和右部的刻度线
plt.tick_params(top='off', right = 'off')
# 添加标题
plt.title('上海市2017年9月份每日最高气温分布图')
# 显示图形
plt.show()

绘图数据的表结构

热力图展现

OK,一张填充表格热力图就奇迹般的显示了,而且看上去还蛮舒服的。从图框看,9月份的第一天是周五,之后的每一天都有对应的颜色显示。但我在绘图过程中发现几个问题

1)绘图用的数据,不能包含缺失值,否则填充图是绘制不出来的,所有需要对缺失值做填充处理;

2)最终的图例无法实现,即颜色的深浅,代表了具体的数值范围是什么?

3)不方便将具体的温度值显示在每个单元格内

       为解决上面的三个问题,我们借助于seaborn模块中的heatmap函数重新绘制一下热力图,而且这些问题在heatmap函数看来根本不算问题。

基于seaborn绘制热力图

# 通过透视图函数形成绘图数据
target = pd.pivot_table(data = df.iloc[:,1:],values = 'high',                        index = 'week_of_month', columns = 'weekday')

# 绘图
ax = sns.heatmap(target, # 指定绘图数据                 cmap=plt.cm.Blues, # 指定填充色                 linewidths=.1, # 设置每个单元方块的间隔                 annot=True # 显示数值                )

# 添加x轴刻度标签(加0.5是为了让刻度标签居中显示)
plt.xticks(np.arange(7)+0.5,['周一','周二','周三','周四','周五','周六','周日'])
# 可以将刻度标签置于顶部显示
# ax.xaxis.tick_top()

# 添加y轴刻度标签
plt.yticks(np.arange(5)+0.5,['第一周','第二周','第三周','第四周','第五周'])
# 旋转y刻度0度,即水平显示
plt.yticks(rotation = 0)

# 设置标题和坐标轴标签
ax.set_title('上海市2017年9月份每日最高气温分布图') ax.set_xlabel('') ax.set_ylabel('')

# 显示图形
plt.show()


完美热力图的绘制太简单了!不需要做任何的特殊处理,只需要将绘图数据扔给heatmap函数即可。想想是不是有点小激动啊~激动过后,还得跟着步骤操作一表哦~

结语


       OK,今天关于填充表格热力图的绘制,我们就分享到这里。如果你有问题,欢迎在公众号的留言区域表达你的疑问。同时,也欢迎各位朋友继续转发与分享文中的内容,让跟多的人学习和操作。最后,本文相关的Python脚本和PDF版本已存放到百度云盘,可以通过下面的链接获取

链接: https://pan.baidu.com/s/1c1JwACo 密码: jsgx

Python爱好者社区历史文章大合集

Python爱好者社区历史文章列表(每周append更新一次)

福利:文末扫码立刻关注公众号,“Python爱好者社区”,开始学习Python课程:

关注后在公众号内回复课程即可获取:

0.小编的Python入门视频课程!!!

1.崔老师爬虫实战案例免费学习视频。

2.丘老师数据科学入门指导免费学习视频。

3.陈老师数据分析报告制作免费学习视频。

4.玩转大数据分析!Spark2.X+Python 精华实战课程免费学习视频。

5.丘老师Python网络爬虫实战免费学习视频。



今天看啥 - 高品质阅读平台
本文地址:http://www.jintiankansha.me/t/Y5M1sbzPuj
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/4376
 
377 次点击  
分享到微博