前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python数据分析--折线图

Python数据分析--折线图

原创
作者头像
MiaoGIS
发布2022-04-21 16:04:42
1.2K0
发布2022-04-21 16:04:42
举报
文章被收录于专栏:Python in AI-IOTPython in AI-IOT

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

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

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

子弹图,它的样子有点像子弹,能够表达比较丰富的信息,例如表现好、中、差的取值范围,并突出显示实际值与目标值的差异情况。

林骥老师在数据可视化分析中提到改进折线图的 12 个细节:

1、把标题变成左对齐,更加符合设计的审美;

2、把标题颜色换成深灰色,让观察者更加关注数据;

3、删除不必要的边框和网格线,避免它们消耗观察者的精力;

4、只保留最大值和最小值的标记,让对比更加明显;

5、去掉图例,直接在线条的附近标注,避免观察者在图例和数据之间来回移动;

6、去掉平均值线,让图表显得更加简洁;

7、更加谨慎而且有策略地使用颜色,去掉那些花花绿绿的颜色,换成只有蓝色和灰色,这样反而能够让重要的信息显得更加突出;

8、坐标轴和标签文字统一换成深灰色,让它们更自然地融入背景,在视觉上不与数据进行竞争;

9、把竖直的日期标签,换成横向的简化日期格式,以便提高阅读的体验,有研究表明,阅读 90 度角倾斜的文字,速度比阅读正常方向的文字平均慢 205%;

10、去掉最大值和最小值的具体数字,因为这里更加关心的是数据背后的事件,而不是数字本身;

11、增加 X 轴的标题「日期」,让它与最左侧的标签对齐;

12、增加 Y 轴的标题「PM2.5」,让它与最上方的标签对齐,为了更加方便阅读,采用换行的方法,把 Y 轴的标题文字变成竖直的方向。

现在我们对比一下改进前后的折线效果:

改进前如下图:

改进后如下:

数据格式如下:

代码语言:text
复制
date	value
2018年1月1日	205.1764706
2018年1月2日	131.7916667
2018年1月3日	43.5
2018年1月4日	34.95833333
......

2018年12月30日	65.625
2018年12月31日	83.25

代码如下:

代码语言:python
复制
# 导入所需的库
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
from datetime import timedelta

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

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

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

# 定义颜色,主色:蓝色,辅助色:灰色,互补色:橙色
colors = {'蓝色':'#00589F', '深蓝色':'#003867', '浅蓝色':'#5D9BCF','绿色':'green',
          '灰色':'#999999', '深灰色':'#666666', '浅灰色':'#CCCCCC','红色':'red',
          '橙色':'#F68F00', '深橙色':'#A05D00', '浅橙色':'#FBC171'}
# 数据源路径
filepath='./data/PM25.xlsx'

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

# 定义画图用的数据
x = [x.strftime('%m-%d') for x in df.date]
y = df.value


# 使用「面向对象」的方法画图,定义图片的大小
fig, ax=plt.subplots(figsize=(10, 6))

# 设置标题
ax.text(-3.9, y.max()+6, '\n郑州市2018年PM2.5变化趋势\n', fontsize=26, color=colors['深灰色'])

# 绘制折线图
ax.plot(x, y, marker='*', ms=16,color=colors['蓝色'], markevery=[y.idxmin(), y.idxmax()], mfc='w')

maxDate=df.date[y.idxmax()].strftime('%m月%d日')
minDate=df.date[y.idxmin()].strftime('%m月%d日')
# 标注最大值对应的事件
ax.annotate('(%s)最高值:%.2f'%(maxDate,y.max()), xy=(x[y.idxmax()], y.max()), color=colors['红色'],
             xytext=(y.idxmax()-4.2, y.max()), 
             arrowprops=dict(arrowstyle='->', color=colors['红色']), fontsize=16)

# 标注最小值对应的事件
ax.annotate('(%s)最低值:%.2f'%(minDate,y.min()), xy=(x[y.idxmin()], y.min()), color=colors['绿色'],
             xytext=(y.idxmin()-3.6, y.min()), 
             arrowprops=dict(arrowstyle='->', color=colors['绿色']), fontsize=16)

# 计算 7 天移动平均
y2 = y.rolling(7).mean()
# 绘制趋势线
ax.plot(x, y2, ls='-', color=colors['灰色'], label='七天移动平均')
# 绘制趋势线末端的箭头
plt.annotate('', xy=(x[-1:], y2[-1:]), xytext=(x[-2:-1], y2[-2:-1]), 
             arrowprops=dict(arrowstyle='->', color=colors['灰色'], shrinkB=0))
# 文字说明移动平均
ax.text(len(x)-7.8, y2[-8:-7], '七天移动平均', color=colors['深灰色'], fontsize=12, bbox=dict(facecolor='w', edgecolor='w'))

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

# 隐藏 X 轴的刻度线
ax.tick_params(axis='x', which='major', length=0)

xticks=[i if i[-2:]=='01' else '' for i in x]
xticks[-1]=x[-1]
ax.set_xticks(xticks)

# 设置 X、Y 轴的标题,适当留白
ax.text(len(x)/2, -55, '日期', ha='left', fontsize=20, color=colors['深灰色'])
ax.text(-50, y.max()/2, 'PM2.5日均值', va='top', fontsize=20, color=colors['深灰色'])

# 设置坐标标签字体大小和颜色
ax.tick_params(labelsize=16, colors=colors['深灰色'])

# 设置 y 轴的刻度范围
ax.set_ylim(0, y.max()+6)
fig.autofmt_xdate()
plt.show()

为了体现数据的上下浮动范围,可以在折线的基础上添加填充区域。

数据如下:

代码语言:text
复制
date	mean	amax	amin
20180101	205.1764706	286	74
20180102	131.7916667	206	85
20180103	43.5	73	22
20180104	34.95833333	49	25
20180105	72.16666667	136	42
20180106	120.5416667	146	100
20180107	135	169	93
20180108	29.875	87	19
20180109	20.79166667	27	15
20180110	19.875	25	15
20180111	30.25	50	22
20180112	79.875	120	37
20180113	125	154	84
......

20181230	65.625	83	53
20181231	83.25	118	61

代码如下:

代码语言:python
复制
# 导入所需的库
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
from datetime import datetime

from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()
# 正常显示中文标签
mpl.rcParams['font.sans-serif'] = ['SimHei']

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

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

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

# 数据源路径
filepath='./data/2020年第一季度上证指数.xlsx'

# 读取 Excel文件
df = pd.read_excel(filepath,1)
df.date=df['date'].map(lambda x:datetime.strptime(str(x),'%Y%m%d'))

# 使用「面向对象」的方法画图
fig, ax = plt.subplots(figsize=(10, 6))
fig.tight_layout()
# 设置标题
ax.set_title('\n郑州市2018年PM2.5变化趋势\n', fontsize=26, loc='left', color=colors['深灰色'])

# 开始画图,时间线图(颜色/线条类型/标记)

 
# 填充区域
ax.fill_between(df['date'], df['amin'], df['amax'], color=colors['浅灰色'],label='最高最低区间')
ax.plot(df['date'], df['mean'], label='日均值', color=colors['蓝色'], ls='-', lw=1,
        marker='o',markevery=[-1] )
  
 

# 显示最后 n 个数据的标签
n = 1
# 设置第一条折线图的数据标签
for a, b in zip(df['date'][-n:], df['mean'][-n:]):
    plt.text(a, b+25, '%.0f' % b, ha='center', va= 'bottom', fontsize=12, color=colors['浅蓝色'])
  
 
# 隐藏边框
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['bottom'].set_color(colors['灰色'])
ax.spines['left'].set_color(colors['灰色'])

# 隐藏 X 轴的刻度线
ax.tick_params(axis='x', which='major', length=0)

# 设置坐标标签字体大小和颜色
ax.tick_params(labelsize=16, colors=colors['深灰色'])
plt.legend()
fig.autofmt_xdate()
plt.show()

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com