最近阅读学习了林骥老师的《数据化分析 Python 实战》,书中讲好的技能应该刻意的练习,而不是简单的重复。
学习林骥老师的数据可视化的每种图表时,原来代码略微修改,使其适用于自己工作业务中的数据可视化。
林骥老师将数据可视化分析源代码分享在他的GitHub空间https://github.com/linjiwx/mp
引用林骥老师关于雷达图的使用场景:
雷达图的背景一圈一圈地像雷达,用多边形来展现数据的大小,适合用于有多种不同维度的情形,是发现差距的一种好工具。
(1)如果在一个雷达图中展现超过 2 组数据,会让图表难以阅读。
(2)变量的个数不宜过多,否则密密麻麻的线条可能让人抓不到重点。
(3)从表达数据的精确度来看,极坐标中的角度,不如直角坐标中的位置。
数据如下:
代码语言:text复制type 郑州 焦作
CO 1.026010613 1.213508772
NO2 48.34346358 39.14192377
O3 69.27411963 72.05813249
PM10 118.915409 126.1797168
PM2.5 65.44621322 68.32829138
SO2 14.74927641 17.02480339
代码如下:
代码语言:python代码运行次数:0复制# 导入所需的库
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.image as image
# 正常显示中文标签
mpl.rcParams['font.sans-serif'] = ['SimHei']
# 自动适应布局
mpl.rcParams.update({'figure.autolayout': True})
# 正常显示负号
mpl.rcParams['axes.unicode_minus'] = False
# 禁用科学计数法
pd.set_option('display.float_format', lambda x: '%.2f' % x)
# 定义颜色,主色:蓝色,辅助色:灰色,互补色:橙色
c = {'蓝色':'#00589F', '深蓝色':'#003867', '浅蓝色':'#5D9BCF',
'灰色':'#999999', '深灰色':'#666666', '浅灰色':'#CCCCCC',
'橙色':'#F68F00', '深橙色':'#A05D00', '浅橙色':'#FBC171'}
# 数据源路径
filepath='./data/aqi.xlsx'
# 读取 Excel文件
df = pd.read_excel(filepath)
dictRange={
'SO2':[0,150,500,650,800],
'NO2':[0,100,200,700,1200,2340,3090,3840],
'PM10':[0,50,150,250,350,420,500,600],
'CO':[0,5,10,35,60,90,120,150],
'O3':[0,160,200,300,400,800,1000,1200],
'PM2.5':[0,35,75,115,150,250,350,500],
}
label = df.iloc[:,0].values
def rank(x):
series=pd.Series(dictRange[x[0]])
print(series)
return series.searchsorted(x[1:])
data=df.apply(rank,1,result_type='expand').values
# 提取画图所需的数据
data0 = data[:, 0]
data1 = data[:, 1]
# data 有几个数据,就把整圆 360° 分成几份
angle = np.linspace(0, 2*np.pi, len(data0), endpoint=False)
# 增加第一个 angle 到所有 angle 里,以实现闭合
angles = np.concatenate((angle, [angle[0]]))
# 倒转顺序,以让雷达图顺时针显示
angles = angles[::-1]
#提取标签
#增加第一个 data 到所有的 data 里,以实现闭合
data0 = np.concatenate((data0, [data0[0]]))
data1 = np.concatenate((data1, [data1[1]]))
# 使用「面向对象」的方法画图,定义图片的大小
fig, (ax1,ax2)=plt.subplots(1,2,figsize=(8, 8), subplot_kw=dict(polar=True))
# 设置背景颜色
fig.set_facecolor('w')
ax1.set_facecolor('w')
ax2.set_facecolor('w')
# 设置标题
ax1.set_title(f'2018年{df.columns[1]}空气污染类别分布nn', fontsize=18, loc='left', color=c['深灰色'])
ax2.set_title(f'2018年{df.columns[2]}空气污染类别分布nn', fontsize=18, loc='left', color=c['深灰色'])
# 设置网格标签
ax1.set_thetagrids(angles*180/np.pi, labels=label)
ax2.set_thetagrids(angles*180/np.pi, labels=label)
# 画雷达图,用顺时针显示
ax1.plot(angles, data0, 'o-', label=df.columns[1])
ax2.plot(angles, data1, 'o-', label=df.columns[2])
# 设置极坐标 0° 的位置
ax1.set_theta_zero_location('N')
ax2.set_theta_zero_location('N')
# 设置显示的极径范围
ax1.set_rlim(0, 5)
ax2.set_rlim(0, 5)
# 填充颜色
ax1.fill(angles, data0, facecolor=c['浅蓝色'], alpha=0.6)
ax2.fill(angles, data1, facecolor=c['浅橙色'], alpha=0.6)
# 设置极径标签,放在第一象限的中间位置
ax1.set_rlabel_position(360-360/len(data0)/2)
ax2.set_rlabel_position(360-360/len(data0)/2)
ax1.spines['polar'].set_visible(False)
ax2.spines['polar'].set_visible(False)
# 设置坐标标签字体大小和颜色
ax1.tick_params(labelsize=16, colors=c['深灰色'])
ax2.tick_params(labelsize=16, colors=c['深灰色'])
plt.show()