Python中国社区  »  Python

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

Python爱好者社区 • 2 周前 • 183 次点击  

作者:刘顺祥

个人微信公众号:每天进步一点点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
 
183 次点击  
分享到微博
分享
社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
WEB开发
linux   Bootstrap   IE   NGINX   js   MQ   其他Web框架   peewee   web工具   Jquery   zookeeper   MongoDB   tornado   Git   Redis   NoSql   bottle   DATABASE  
机器学习
机器学习算法  
Python88.com
公告   社区推广   反馈