Python画哑铃图

阅读 688 标签:python  

首先介绍哑铃图:

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

数据如下:

城市	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

代码如下:

# 导入所需的库
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对比\n\n', 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()



文章来源:网络 版权归原作者所有,如涉及知识产权问题,请权利人联系我们,我们将立即处理.
标签: python
专栏:   python
文章 获得 个赞 共 个粉丝

推荐阅读 更多精彩内容