Python数据分析--哑铃图

2022-04-20 15:45:00 浏览数 (1)

最近阅读学习了林骥老师的《数据化分析 Python 实战》,书中讲好的技能应该刻意的练习,而不是简单的重复。

学习林骥老师的数据可视化的每种图表时,原来代码略微修改,使其适用于自己工作业务中的数据可视化。

林骥老师将数据可视化分析源代码分享在他的GitHub空间https://github.com/linjiwx/mp

首先介绍哑铃图:

哑铃图,是指用一条横线连接两个点、看起来有点像哑铃的图,主要是用来强调从一个点到另一个点的变化。

数据如下:

代码语言:text复制
城市	2017	2018
郑州	109.05	103.47
洛阳	108.39	95.86
安阳	119.99	110.99
开封	102.13	103.24
焦作	110.68	103.46
平顶山	99.78	97.45
信阳	80.95	82.19
周口	94.32	96.86
鹤壁	99.82	91.68
新乡	99.78	95.48
濮阳	104.13	98.85
许昌	97.36	101.87
漯河	97.02	98.4
南阳	90.04	92.36
商丘	98.02	97.48
驻马店	90.95	92.66
三门峡	96.61	96.57

代码如下:

代码语言:python代码运行次数:0复制
# 导入所需的库
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt

# 正常显示中文标签
mpl.rcParams['font.sans-serif'] = ['SimHei']

# 自动适应布局
mpl.rcParams.update({'figure.autolayout': True})

# 正常显示负号
mpl.rcParams['axes.unicode_minus'] = False

# 定义颜色,主色:蓝色,辅助色:灰色,互补色:橙色
c = {'蓝色':'#00589F', '深蓝色':'#003867', '浅蓝色':'#5D9BCF',
     '灰色':'#999999', '深灰色':'#666666', '浅灰色':'#CCCCCC',
     '橙色':'#F68F00', '深橙色':'#A05D00', '浅橙色':'#FBC171'}
 

# 数据源路径
filepath='./data/AQI.xlsx'

# 读取 Excel文件
df = pd.read_excel(filepath,0)

# 定义画图用的数据
category_names = df.index
labels = df.columns
data = df.values

df['变化'] = df.iloc[:, 2] - df.iloc[:, 1]
 
# 使用「面向对象」的方法画图,定义图片的大小
fig, ax = plt.subplots(figsize=(8, 6))

# 设置背景颜色
fig.set_facecolor('w')
ax.set_facecolor('w')


# 设置标题
plt.title('n河南省各地市2017年-2018年AQI对比nn', loc='center', size=26, color=c['深灰色'])

# 定义范围
rng = range(1, len(df.index) 1)
rng_pos = list(map(lambda x:x 1, df[df['变化']>=0].index))
rng_neg = list(map(lambda x:x 1, df[df['变化']<0].index))

# 绘制哑铃图中间的线条
ax.vlines(x=rng_pos, ymin=df[df['变化']>=0].iloc[:, 1], ymax=df[df['变化']>=0].iloc[:, 2], color=c['浅橙色'], zorder=1, lw=5,label='升高')
ax.vlines(x=rng_neg, ymin=df[df['变化']< 0].iloc[:, 1], ymax=df[df['变化']< 0].iloc[:, 2], color=c['浅蓝色'], zorder=1, lw=5,label='下降')

# 绘制哑铃图两头的圆点
ax.scatter( rng,df.iloc[:, 1], color=c['蓝色'], label=df.columns[1], s=80, zorder=2 )
ax.scatter( rng,df.iloc[:, 2], color=c['橙色'], label=df.columns[2], s=80, zorder=2 )

# 显示数据标签
for i, (txt1, txt2,change) in enumerate(zip(df.iloc[:, 1], df.iloc[:, 2],df.iloc[:, 3])):
    
    color=c['橙色'] if(change>0) else c['蓝色']
    radio=(float(txt2)-float(txt1))/float(txt2)
    label=' {:.2%}'.format(radio) if radio>0 else '{:.2%}'.format(radio)
    print(df.iloc[i,1:3].mean())
    ax.annotate(label, ( df.index[i] 1.2,df.iloc[i,2]), color=color, ha='left', va='center', fontsize=12)
 
# 设置 Y 轴标签
plt.xticks(rng, df.iloc[:, 0], va='bottom', color=c['深灰色'], size=12)

# 隐藏边框
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['bottom'].set_visible(False)
ax.spines['left'].set_visible(False)

ymin=df.iloc[:,1:3].min().min()
ymax=df.iloc[:,1:3].max().max()
ax.set_ylim(ymin*0.8, ymax*1.2)
ax.legend()

ax.tick_params(axis='x', which='major', length=0)
plt.tight_layout()
plt.show()

0 人点赞