- 在本期内容中,我们先从条形图开始,条形图实际上是用来表示分组(或离散)变量的可视化,可以使用matplotlib模块中的bar(barh)函数完成条形图的绘制。
- 案例一:直辖市GDP水平
- 中国的四个直辖市分别为北京市、上海市、天津市和重庆市,其2017年上半年的GDP分别为12406.8亿、13908.57亿、9386.87亿、9143.64亿。对于这样一组数据,我们该如何使用条形图来展示各自的GDP水平呢?
#导入matplotlib相关库 import matplotlib.pyplot as plt # 中文乱码的处理 plt.rcParams['font.sans-serif'] =['Microsoft YaHei'] plt.rcParams['axes.unicode_minus'] = False
- 由于matplotlib对中文的支持并不是很友好,所以需要提前对绘图进行字体的设置,即通过rcParams来设置字体,这里将字体设置为微软雅黑,同时为了避免坐标轴不能正常的显示负号,也需要进行设置;
#绘制条形图
plt.bar([0,1,2,3],[12406.8,13908.57,9386.87,9143.64],color = 'steelblue', alpha = 0.8)
#添加标题
plt.title("直辖市GDP水平")
#添加y轴标签
plt.ylabel("GDP")
#添加x轴标签
plt.xlabel("直辖市")
#添加刻度标签
plt.xticks(range(4),labels=["北京市","上海市","天津市","重庆市"])
# 设置Y轴的刻度范围
plt.ylim([5000,15000])
# 为每个条形图添加数值标签
for x,y in enumerate([12406.8,13908.57,9386.87,9143.64]):
plt.text(x,y+100,s=y,ha='center')
plt.show()
代码解读
- 首先通过plt.bar函数指定了条形图的x轴、y轴值,设置x轴刻度标签为水平居中,条形图的填充色color为铁蓝色,同时设置透明度alpha为0.8;
- 添加y轴标签、标题、x轴刻度标签值,为了让条形图显示各柱体之间的差异,将y轴范围设置在5000~15000;
- 通过循环的方式,通过plt.text()添加条形图的数值标签;
- enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。
- enumerate(sequence, [start=0])
- sequence – 一个序列、迭代器或其他支持迭代对象。
- start – 下标起始位置。
seasons = ['Spring', 'Summer', 'Fall', 'Winter'] list(enumerate(seasons))
- 输出
[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
# 下标从 1 开始 list(enumerate(seasons, start=1))
- 输出
[(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]
i = 0
seq = ['one', 'two', 'three']
for element in seq:
print(i,seq[i])
i+=1
- 输出
0 one 1 two 2 three
seq = ['one', 'two', 'three']
for i,element in enumerate(seq):
print(i,element)
- 输出
0 one 1 two 2 three二、简单水平条形图(plt.barh)
#导入matplotlib相关库 import matplotlib.pyplot as plt # 中文乱码的处理 plt.rcParams['font.sans-serif'] =['Microsoft YaHei'] plt.rcParams['axes.unicode_minus'] = False
#将上面的垂直条形图做成水平条形图,使用plt.barh
plt.barh(range(4),[12406.8,13908.57,9386.87,9143.64])
#添加标题
plt.title("直辖市GDP水平")
#添加y轴标签
plt.ylabel("直辖市")
#添加x轴标签
plt.xlabel("GDP")
#添加刻度标签
plt.yticks(range(4),labels=["北京市","上海市","天津市","重庆市"])
# 设置Y轴的刻度范围
plt.xlim([5000,16000])
# 为每个条形图添加数值标签
for x,y in enumerate([12406.8,13908.57,9386.87,9143.64]):
plt.text(y,x,s=y,va='center')
plt.show()
- 案例二:同一本书不同平台最低价比较
- 很多人在买一本书的时候,都比较喜欢货比三家,例如《python数据分析实战》在亚马逊、当当网、中国图书网、京东和天猫的最低价格分别为39.5、39.9、45.4、38.9、33.34。针对这个数据,我们也可以通过条形图来完成,这里使用水平条形图来显示:
plt.barh(range(5),[39.5,39.9,45.5,38.9,33.34])
#添加标题
plt.title("《python数据分析实战》在不同平台最低价")
#添加x轴标签
plt.xlabel("单价/元")
#添加y轴标签
plt.ylabel("不同平台")
#添加刻度标签
plt.yticks(range(5),labels=["亚马逊","当当网","中国图书网","京东","天猫"])
#为每个条形图添加数值标签
for x,y in enumerate([39.5,39.9,45.5,38.9,33.34]):
plt.text(y,x,s = y,va = "center")
plt.show()
代码解读
- 水平条形图的绘制与垂直条形图的绘制步骤一致,只是调用了barh函数来完成。
- 需要注意的是,条形图的数值标签设置有一些不一样,需要将标签垂直居中显示,使用va参数即可。
- 以上讲的简单垂直和水平条形图是基于一种离散变量的情况,针对两种离散变量的条形图我们可以使用水平交错条形图和堆叠条形图,下面我们就来看看这两种条形图是如何绘制的。
- 案例三:胡润财富榜:亿万资产超高净值家庭数
- 利用水平交错条形图对比2016年和2017年亿万资产超高净值家庭数(top5),其数据如下:
# 构建数据
Y2016 = [15600,12700,11300,4270,3620]
Y2017 = [17400,14800,12000,5200,4020]
labels = ['北京','上海','香港','深圳','广州']
bar_width = 0.35
#绘制图形
#plt.bar([1,2,3,4,5],Y2016,label = '2016',color = "steelblue",alpha = 0.8,width = bar_width)
#plt.bar([1.35,2.35,3.35,4.35,5.35],Y2017,label = '2017',color = "indianred",alpha = 0.8,width = bar_width)
import numpy as np
plt.bar(np.arange(5),Y2016,label = '2016',color = "steelblue",alpha = 0.8,width = bar_width)
plt.bar(np.arange(5)+bar_width,Y2017,label = '2017',color = "indianred",alpha = 0.8,width = bar_width)
#添加标题
plt.title("胡润财富榜:亿万资产超高净值家庭数")
#添加x轴标签
plt.xlabel("地区")
#添加y轴标签
plt.ylabel("家庭数")
#添加x轴刻度标签
plt.xticks(np.arange(5)+0.15,labels=labels)
#为每个条形图添加数值标签
for x,y in enumerate(Y2016):
plt.text(x,y+120,s = y,ha = "center")
for x,y in enumerate(Y2017):
plt.text(x+0.35,y+120,s = y,ha = "center")
#添加图例
plt.legend()
plt.show()
代码解读
- 水平交错条形图绘制的思想很简单,就是在第一个条形图绘制好的基础上,往左移一定的距离,再去绘制第二个条形图,所以在代码中会出现两个bar函数;
- 图例的绘制需要在bar函数中添加label参数;
- color和alpha参数分别代表条形图的填充色和透明度;
- 给条形图添加数值标签,同样需要使用两次for循环的方式实现;
- 导入matplotlib.pyplot库
import matplotlib.pyplot as plt
- 字体的设置
plt.rcParams["font.sans-serif"] = ["Microsoft YaHei"]
- 正常显示负号
plt.rcParams["axes.unicode_minus"] = False
- 绘制图形
plt.bar(x轴数值,y轴数值,color = "颜色",alpha = 透明度,width = 宽度) plt.barh(y轴数值,x轴数值,color = "颜色",alpha = 透明度,width = 宽度)
- 添加标题
plt.title("")
- 添加x轴标题
plt.xlabel("")
- 添加y轴标题
plt.ylabel("")
- 添加x轴刻度标题
plt.xticks(位置,labels=[])
- 添加y轴刻度标题
plt.yticks(位置,labels=[])
- 添加x轴刻度范围
plt.xlim([])
- 添加y轴刻度范围
plt.ylim([])
- 为每个条形图添加数值标签
for x,y in enumerate():
plt.text(x,y,s = 值,ha/va = "center")
- 显示图例
plt.legend()
- 显示图形
plt.show()从零开始学Python【2】–matplotlib(饼图)
- 我们用条形图来展示离散变量的分布呈现,在常见的统计图像中,还有一种图像可以表示离散变量各水平占比情况,这就是我们要讲解的饼图。饼图的绘制可以使用matplotlib库中的pie函数,首先我们来看看这个函数的参数说明。
- pie函数参数解读
plt.pie(x
,explode=None
,labels=None
,colors=None
,autopct=None
,pctdistance=0.6
,shadow=False
,labeldistance=1.1
,startangle=None
,radius=None
,counterclock=True
,wedgeprops=None
,textprops=None
,center=(0, 0)
,frame=False)
#x:指定绘图的数据;
#explode:指定饼图某些部分的突出显示,即呈现爆炸式;
#labels:为饼图添加标签说明,类似于图例说明;
#colors:指定饼图的填充色;
#autopct:自动添加百分比显示,可以采用格式化的方法显示;
#pctdistance:设置百分比标签与圆心的距离;
#shadow:是否添加饼图的阴影效果;
#labeldistance:设置各扇形标签(图例)与圆心的距离;
#startangle:设置饼图的初始摆放角度;
#radius:设置饼图的半径大小;
#counterclock:是否让饼图按逆时针顺序呈现;
#wedgeprops:设置饼图内外边界的属性,如边界线的粗细、颜色等;
#textprops:设置饼图中文本的属性,如字体大小、颜色等;
#center:指定饼图的中心点位置,默认为原点
#frame:是否要显示饼图背后的图框,如果设置为True的话,需要同时控制图框x轴、y轴的范围和饼图的中心位置;
饼图的绘制
- 案例:芝麻信用失信用户分析
- 关于绘图数据,我们借用芝麻信用近300万失信人群的样本统计数据,该数据显示,从受教育水平上来看,中专占比25.15%,大专占比37.24%,本科占比33.36%,硕士占比3.68%,剩余的其他学历占比0.57%。对于这样一组数据,我们该如何使用饼图来呈现呢?
#导入对应的库 import matplotlib.pyplot as plt
#解决中文乱码的问题 plt.rcParams["font.sans-serif"] = ["Microsoft YaHei"]
#绘制图形
plt.pie([25.15,37.24,33.36,3.68,0.57]
,explode=[0.1,0,0,0,0]
,labels = ["中专","大专","本科","硕士","其他"]
,colors = ['#9999ff','#ff9999','#7777aa','#2442aa','#dd5555'] # 自定义颜色
,autopct='%.1f%%' # 设置百分比的格式,这里保留一位小数
,pctdistance=0.8 # 设置百分比标签与圆心的距离
,labeldistance = 1.15 # 设置教育水平标签与圆心的距离
,startangle = 360 # 设置饼图的初始角度
,radius = 1 # 设置饼图的半径
,counterclock = False # 是否逆时针,这里设置为顺时针方向
,wedgeprops = {'linewidth': 0.5, 'edgecolor':'green'}# 设置饼图内外边界的属性值
,textprops = {'fontsize':12, 'color':'k'} # 设置文本标签的属性值
,center = (0.5,0.5) # 设置饼图的原点
,frame = False # 是否显示饼图的图框,这里设置不显示
)
#添加标题
plt.title("芝麻信用失信用户学历占比")
#显示图形
plt.show()
总结
- 相比较条形图设置,饼图大部分的设置都是在plt.pie里面完成的
- 记住上面pie函数参数即可
- 针对离散变量我们可以使用常见的条形图和饼图完成数据的可视化工作,那么,针对数值型变量,我们也有很多可视化的方法,例如箱线图、直方图、折线图、面积图、散点图等等。这一期,我们就先来介绍一下数值型变量的箱线图绘制。箱线图一般用来展现数据的分布(如上下四分位值、中位数等),同时,也可以用箱线图来反映数据的异常情况。
- boxplot函数的参数解读
plt.boxplot(
x
,notch=None
,sym=None
,vert=None
,whis=None
,positions=None
,widths=None
,patch_artist=None
,meanline=None
,showmeans=None
,showcaps=None
,showbox=None
,showfliers=None
,boxprops=None
,labels=None
,flierprops=None
,medianprops=None
,meanprops=None
,capprops=None
,whiskerprops=None)
#x:指定要绘制箱线图的数据;
#notch:是否是凹口的形式展现箱线图,默认非凹口;
#sym:指定异常点的形状,默认为+号显示;
#vert:是否需要将箱线图垂直摆放,默认垂直摆放;
#whis:指定上下须与上下四分位的距离,默认为1.5倍的四分位差;
#positions:指定箱线图的位置,默认为[0,1,2…];
#widths:指定箱线图的宽度,默认为0.5;
#patch_artist:是否填充箱体的颜色;
#meanline:是否用线的形式表示均值,默认用点来表示;
#showmeans:是否显示均值,默认不显示;
#showcaps:是否显示箱线图顶端和末端的两条线,默认显示;
#showbox:是否显示箱线图的箱体,默认显示;
#showfliers:是否显示异常值,默认显示;
#boxprops:设置箱体的属性,如边框色,填充色等;
#labels:为箱线图添加标签,类似于图例的作用;
#filerprops:设置异常值的属性,如异常点的形状、大小、填充色等;
#medianprops:设置中位数的属性,如线的类型、粗细等;
#meanprops:设置均值的属性,如点的大小、颜色等;
#capprops:设置箱线图顶端和末端线条的属性,如颜色、粗细等;
#whiskerprops:设置须的属性,如颜色、粗细、线的类型等;
箱线图绘制
- 案例:titanic:不同等级仓位的年龄箱线图
- 整体乘客的年龄箱线图
数据部分详情见这十套练习,教你如何用Pandas做数据分析
这篇内容的练习7-可视化
#导入必要的库 import pandas as pd #从以下地址导入数据 #将数据框命名为titanic titanic = pd.read_csv(r"D:PythonFliepythonpandaspandas_exerciseexercise_datatrain.csv") titanic.head()
- 输出
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked 0 1 0 3 Braund, Mr. Owen Harris male 22.0 1 0 A/5 21171 7.2500 NaN S 1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 0 PC 17599 71.2833 C85 C 2 3 1 3 Heikkinen, Miss. Laina female 26.0 0 0 STON/O2. 3101282 7.9250 NaN S 3 4 1 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0 1 0 113803 53.1000 C123 S 4 5 0 3 Allen, Mr. William Henry male 35.0 0 0 373450 8.0500 NaN S
# 检查年龄是否有缺失 titanic.info()
- 输出
RangeIndex: 891 entries, 0 to 890 Data columns (total 12 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 PassengerId 891 non-null int64 1 Survived 891 non-null int64 2 Pclass 891 non-null int64 3 Name 891 non-null object 4 Sex 891 non-null object 5 Age 714 non-null float64 6 SibSp 891 non-null int64 7 Parch 891 non-null int64 8 Ticket 891 non-null object 9 Fare 891 non-null float64 10 Cabin 204 non-null object 11 Embarked 889 non-null object dtypes: float64(2), int64(5), object(5) memory usage: 83.7+ KB
# 不妨删除含有缺失年龄的观察 titanic.dropna(subset=['Age'], inplace=True)
#在检查一下数据 titanic.info()
- 输出
Int64Index: 714 entries, 0 to 890 Data columns (total 12 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 PassengerId 714 non-null int64 1 Survived 714 non-null int64 2 Pclass 714 non-null int64 3 Name 714 non-null object 4 Sex 714 non-null object 5 Age 714 non-null float64 6 SibSp 714 non-null int64 7 Parch 714 non-null int64 8 Ticket 714 non-null object 9 Fare 714 non-null float64 10 Cabin 185 non-null object 11 Embarked 712 non-null object dtypes: float64(2), int64(5), object(5) memory usage: 72.5+ KB
#导入matplotlib库
import matplotlib.pyplot as plt
#解决中文乱码的问题
plt.rcParams["font.sans-serif"] = ["Microsoft YaHei"]
#绘制图形(注意这里需要删除缺失值后进行绘图,否则将没有图形显示)
plt.boxplot(titanic["Age"]
,notch=False
,sym="."
,vert=True
,patch_artist=False
,meanline=True
,showmeans=True
,showcaps=True
,showbox=True
,showfliers=True
,boxprops={'color':'black'}
,flierprops = {'marker':'o','markerfacecolor':'red','color':'black'} # 设置异常值属性,点的形状、填充色和边框色
,meanprops = {'marker':'D','markerfacecolor':'indianred'} # 设置均值点的属性,点的形状、填充色
,medianprops = {'linestyle':'--','color':'orange'} # 设置中位数线的属性,线的类型和颜色
)
# 设置y轴的范围
plt.ylim(0,85)
#显示图形
plt.show()
- 对于所有乘客而言,从图中容易发现,乘客的平均年龄在30岁,有四分之一的人低于20岁,另有四分之一的人超过38岁,换句话说,有一半的人,年龄落在20~38岁之间;从均值(红色的菱形)略高于中位数(黄色虚线)来看,说明年龄是有偏的,并且是右偏;同时,我们也会发现一些红色的异常值,这些异常值的年龄均在64岁以上。
# 按舱级排序,为了后面正常显示分组盒形图的顺序 titanic.sort_values(by = 'Pclass', inplace=True)
# 通过for循环将不同仓位的年龄人群分别存储到列表Age变量中
Age = []
Levels = titanic.Pclass.unique()
for Pclass in Levels:
Age.append(titanic.loc[titanic.Pclass==Pclass,'Age'])
#绘制图形
plt.boxplot(Age
,notch=False
,sym="."
,vert=True
,positions=[1,2,3]
,patch_artist=True
,labels = ['一等舱','二等舱','三等舱'] # 添加具体的标签名称
,meanline=True
,showmeans=True
,showcaps=True
,showbox=True
,showfliers=True
,boxprops={'color':'black'}
,flierprops = {'marker':'o','markerfacecolor':'red','color':'black'} # 设置异常值属性,点的形状、填充色和边框色
,meanprops = {'marker':'D','markerfacecolor':'indianred'} # 设置均值点的属性,点的形状、填充色
,medianprops = {'linestyle':'--','color':'orange'} # 设置中位数线的属性,线的类型和颜色
)
plt.show()
- 如果对人群的年龄按不同的舱位来看,我们会发现一个明显的趋势,就是舱位等级越高的乘客,他们的年龄越高,三种舱位的平均年龄为38、30和25,说明年龄越是偏大一点,他们的经济能力会越强一些,所买的舱位等级可能就会越高一些。同时,在二等舱和三等舱内,乘客的年龄上存在一些异常用户。
- 大部分设置也是在plt.boxplot里面进行设置,但是相比于之前的图,需要进一步处理数据,排除缺失值,否则会出错
- 后续难点在于存在多个箱线图的绘制,需要构建自己需要的数据才能继续绘制箱线图
- 上一部分展示了如何绘制数值型变量的箱线图,展现数据的分布,我们还可以使用直方图来说明,通过图形的长相,就可以快速的判断数据是否近似服从正态分布。之所以我们很关心数据的分布,是因为在统计学中,很多假设条件都会包括正态分布,故使用直方图来定性的判定数据的分布情况,尤其显得重要。这期我们就来介绍Python中如何绘制一个直方图。
- hist函数的参数解读
plt.hist(x
,bins=10
,range=None
,normed=False
,weights=None
,cumulative=False
,bottom=None
,histtype='bar'
,align='mid'
,orientation='vertical'
,rwidth=None
,log=False
,color=None
,label=None
,stacked=False)
#x:指定要绘制直方图的数据;
#bins:指定直方图条形的个数;
#range:指定直方图数据的上下界,默认包含绘图数据的最大值和最小值;
#normed:是否将直方图的频数转换成频率;
#weights:该参数可为每一个数据点设置权重;
#cumulative:是否需要计算累计频数或频率;
#bottom:可以为直方图的每个条形添加基准线,默认为0;
#histtype:指定直方图的类型,默认为bar,除此还有’barstacked’, ‘step’, ‘stepfilled’;
#align:设置条形边界值的对其方式,默认为mid,除此还有’left’和’right’;
#orientation:设置直方图的摆放方向,默认为垂直方向;
#rwidth:设置直方图条形宽度的百分比;
#log:是否需要对绘图数据进行log变换;
#color:设置直方图的填充色;
#label:设置直方图的标签,可通过legend展示其图例;
#stacked:当有多个数据时,是否需要将直方图呈堆叠摆放,默认水平摆放;
一元直方图的绘制
- 案例:titanic数据集
- 整体乘客的年龄直方图
#导入必要的库
import pandas as pd
#从以下地址导入数据 #将数据框命名为titanic titanic = pd.read_csv(r"D:PythonFliepythonpandaspandas_exerciseexercise_datatrain.csv") titanic.head()
- 输出
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked 0 1 0 3 Braund, Mr. Owen Harris male 22.0 1 0 A/5 21171 7.2500 NaN S 1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 0 PC 17599 71.2833 C85 C 2 3 1 3 Heikkinen, Miss. Laina female 26.0 0 0 STON/O2. 3101282 7.9250 NaN S 3 4 1 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0 1 0 113803 53.1000 C123 S 4 5 0 3 Allen, Mr. William Henry male 35.0 0 0 373450 8.0500 NaN S
# 检查年龄是否有缺失 titanic.info()
- 输出
RangeIndex: 891 entries, 0 to 890 Data columns (total 12 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 PassengerId 891 non-null int64 1 Survived 891 non-null int64 2 Pclass 891 non-null int64 3 Name 891 non-null object 4 Sex 891 non-null object 5 Age 714 non-null float64 6 SibSp 891 non-null int64 7 Parch 891 non-null int64 8 Ticket 891 non-null object 9 Fare 891 non-null float64 10 Cabin 204 non-null object 11 Embarked 889 non-null object dtypes: float64(2), int64(5), object(5) memory usage: 83.7+ KB
titanic.dropna(subset = ["Age"],inplace = True)
#导入matplotlib库
import matplotlib.pyplot as plt
#绘制图形
plt.hist(titanic.Age
,bins=20
,histtype ="barstacked"
,align ='mid'
,label = '年龄的频数直方图'
,color = 'steelblue'
,edgecolor = 'k'
)
#显示图例
plt.legend()
#显示图形
plt.show()
- 上图绘制的是年龄的频数直方图,从整体的分布来看,有点像正态分布,两边低中间高的倒钟形状。除此,我们还可以绘制累计频率直方图,并且设置5岁为组距,如下代码可以表示成:
import numpy as np
#绘制图形
plt.hist(titanic.Age
,bins=np.arange(titanic.Age.min(),titanic.Age.max(),5)
,density=True
,cumulative=True
,align ='mid'
,label = '年龄的频率直方图'
,color = 'steelblue'
,edgecolor = 'k'
)
#设置x轴范围
plt.xlim([0,80])
# 设置坐标轴标签和标题
plt.title('乘客年龄直方图')
plt.xlabel('年龄')
plt.ylabel('频率')
#显示图例
plt.legend()
#显示图形
plt.show()
- plt.hist(titanic.Age,bins=np.arange(0,90,5),normed=True,align =‘mid’,label = ‘年龄的频率直方图’,color = ‘steelblue’,edgecolor = ‘k’)
- 会报’Rectangle’ object has no property 'normed’错
- 去掉normed,改成density(布尔值),意思是开启概率分布(直方图面积为1)
- 上面绘制的直方图都是基于所有乘客的年龄,如果想对比男女乘客的年龄直方图的话,我们可以通过两个hist将不同性别的直方图绘制到一张图内,具体代码如下:
#导入matplotlib库
import matplotlib.pyplot as plt
#绘制图形
plt.hist(titanic.Age[titanic.Sex == 'male']
,bins=np.arange(titanic.Age.min(), titanic.Age.max(), 2)
,label = "男性"
,histtype ="barstacked"
,align ='mid'
,color = 'steelblue'
,edgecolor = 'k'
,alpha = 0.7
)
plt.hist(titanic.Age[titanic.Sex == 'female']
,bins=np.arange(titanic.Age.min(), titanic.Age.max(), 2)
,label = "女性"
,histtype ="barstacked"
,align ='mid'
,edgecolor = 'k'
,alpha = 0.6
)
# 设置坐标轴标签和标题
plt.title('乘客年龄直方图')
plt.xlabel('年龄')
plt.ylabel('人数')
#显示图例
plt.legend()
#显示图形
plt.show()
- 图中结果反映了,不同年龄组内几乎都是男性乘客比女性乘客要多;同时,也说明男女性别的年龄组分布几乎一致
- 折线图一般是用来表示某个数值变量随着时间的推移而形成的趋势,这种图还是比较常见的,如经济走势图、销售波动图、PV监控图等。在Python的matplotlib模块中,我们可以调用plot函数就能实现折线图的绘制了,先来看看这个函数的一些参数含义。
- plot函数的参数解读
plt.plot(x
,y
,linestyle
,linewidth
,color
,marker
,markersize
,markeredgecolor
,markerfactcolor
,label
,alpha)
#x:指定折线图的x轴数据;
#y:指定折线图的y轴数据;
#linestyle:指定折线的类型,可以是实线、虚线、点虚线、点点线等,默认文实线;
#linewidth:指定折线的宽度
#marker:可以为折线图添加点,该参数是设置点的形状;
#markersize:设置点的大小;
#markeredgecolor:设置点的边框色;
#markerfactcolor:设置点的填充色;
#label:为折线图添加标签,类似于图例的作用;
一元折线图的绘制
- 案例:每天进步一点点2015公众号文章阅读人数
#导入数据 import pandas as pd wechart = pd.read_csv(r"D:PythonFliepythonpandaspandas_exerciseexercise_datawechart.csv") wechart.head(-5)
- 输出
date article_reading_cnts article_reading_times collect_times 0 2017/1/1 37 124 1 1 2017/1/2 51 149 7 2 2017/1/3 93 369 5 3 2017/1/4 58 278 6 4 2017/1/5 58 216 2 ... ... ... ... ... 261 2017/9/19 95 231 8 262 2017/9/20 83 230 19 263 2017/9/21 78 364 3 264 2017/9/22 69 248 9 265 2017/9/23 539 799 29 266 rows × 4 columns
#查看数据情况 wechart.info() #不存在缺失值
- 输出
RangeIndex: 271 entries, 0 to 270 Data columns (total 4 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 date 271 non-null object 1 article_reading_cnts 271 non-null int64 2 article_reading_times 271 non-null int64 3 collect_times 271 non-null int64 dtypes: int64(3), object(1) memory usage: 8.6+ KB
#绘制公众号文章阅读人数随时间折线图
#导入对应的库
import matplotlib.pyplot as plt
#解决中文乱码问题
plt.rcParams["font.sans-serif"] = ['Microsoft YaHei']
# 设置图框的大小
fig = plt.figure(figsize=(20,6))
#绘图
plt.plot(wechart.date[wechart.date >= '2017/9/1']
,wechart.article_reading_cnts[wechart.date >= '2017/9/1']
,linestyle = '-' # 折线类型
,linewidth = 2 # 折线宽度
,color = 'steelblue' # 折线颜色
,marker = 'o' # 点的形状
,markersize = 6 # 点的大小
,markeredgecolor='black' # 点的边框色
,markerfacecolor='brown' # 点的填充色
)
#设置标题
plt.title("公众号文章九月份阅读人数折线图")
#设置x轴,y轴标题
plt.xlabel("日期/天")
plt.ylabel("人数")
# 为了避免x轴日期刻度标签的重叠,设置x轴刻度自动展现,并且45度倾斜
fig.autofmt_xdate(rotation = 45)
#显示图形
plt.show()
- 发散一下思维:如果做每个月阅读人数总和的折线图,应该怎么做?
from datetime import datetime
#首先把需要的数据弄一下
wechart["月份"] = wechart["date"].apply(lambda a:datetime.strptime(a, '%Y/%m/%d').strftime('%Y-%m'))
wechart.head()
- 输出
date article_reading_cnts article_reading_times collect_times 月份 0 2017/1/1 37 124 1 2017-01 1 2017/1/2 51 149 7 2017-01 2 2017/1/3 93 369 5 2017-01 3 2017/1/4 58 278 6 2017-01 4 2017/1/5 58 216 2 2017-01
#在将article_reading_cnts根据月份聚合一下
wechart.groupby(by = "月份").aggregate({"article_reading_cnts":sum})
- 输出
article_reading_cnts 月份 2017-01 2461 2017-02 4397 2017-03 3400 2017-04 4687 2017-05 1688 2017-06 3777 2017-07 4133 2017-08 4132 2017-09 7444
#导入对应的库
import matplotlib.pyplot as plt
#解决中文乱码问题
plt.rcParams["font.sans-serif"] = ['Microsoft YaHei']
# 设置图框的大小
fig = plt.figure(figsize=(10,6))
#绘图
plt.plot(wechart.groupby(by = "月份").aggregate({"article_reading_cnts":sum}).index
,wechart.groupby(by = "月份").aggregate({"article_reading_cnts":sum})
,linestyle = '-' # 折线类型
,linewidth = 2 # 折线宽度
,color = 'steelblue' # 折线颜色
,marker = 'o' # 点的形状
,markersize = 6 # 点的大小
,markeredgecolor='black' # 点的边框色
,markerfacecolor='brown' # 点的填充色
)
#设置标题
plt.title("公众号文章九月份阅读人数折线图")
#设置x轴,y轴标题
plt.xlabel("日期/天")
plt.ylabel("人数")
# 为了避免x轴日期刻度标签的重叠,设置x轴刻度自动展现,并且45度倾斜
fig.autofmt_xdate(rotation = 45)
#显示图形
plt.show()
补充:从字符串中提取年月日
#导入时间模块
from datetime import datetime
a = '2017/8/2'
b = datetime.strptime(a, '%Y/%m/%d').strftime('%m-%d')
b
- 输出
'08-02'一元折线图的绘制—图形优化
#绘制公众号文章阅读人数随时间折线图
#导入对应的库
import matplotlib.pyplot as plt
import matplotlib as mpl
#解决中文乱码问题
plt.rcParams["font.sans-serif"] = ['Microsoft YaHei']
# 设置图框的大小
fig = plt.figure(figsize=(20,6))
#绘图
plt.plot(wechart.date[wechart.date >= '2017/9/1']
,wechart.article_reading_cnts[wechart.date >= '2017/9/1']
,linestyle = '-' # 折线类型
,linewidth = 2 # 折线宽度
,color = 'steelblue' # 折线颜色
,marker = 'o' # 点的形状
,markersize = 6 # 点的大小
,markeredgecolor='black' # 点的边框色
,markerfacecolor='brown' # 点的填充色
)
#设置标题
plt.title("公众号文章九月份阅读人数折线图")
#设置x轴,y轴标题
plt.xlabel("日期/天")
plt.ylabel("人数")
# 获取图的坐标信息
ax = plt.gca()
# 设置日期的显示格式
date_format = mpl.dates.DateFormatter("%m-%d")
ax.xaxis.set_major_formatter(date_format)
# 设置x轴显示多少个日期刻度
#xlocator = mpl.ticker.LinearLocator(10)
# 设置x轴每个刻度的间隔天数
xlocator = mpl.ticker.MultipleLocator(2)
ax.xaxis.set_major_locator(xlocator)
# 为了避免x轴日期刻度标签的重叠,设置x轴刻度自动展现,并且45度倾斜
fig.autofmt_xdate(rotation = 45)
#显示图形
plt.show()
多元折线图的绘制
- 如果你需要在一张图形中画上两条折线图,也很简单,只需要在代码中写入两次plot函数即可,其他都不需要改动了。具体可以参考下面的代码逻辑:
#绘制公众号文章阅读人数随时间折线图
#导入对应的库
import matplotlib.pyplot as plt
#解决中文乱码问题
plt.rcParams["font.sans-serif"] = ['Microsoft YaHei']
# 设置图框的大小
fig = plt.figure(figsize=(20,6))
#绘图
plt.plot(wechart.date[wechart.date >= '2017/9/1']
,wechart.article_reading_cnts[wechart.date >= '2017/9/1']
,linestyle = '-' # 折线类型
,linewidth = 2 # 折线宽度
,color = 'steelblue' # 折线颜色
,marker = 'o' # 点的形状
,markersize = 6 # 点的大小
,markeredgecolor='black' # 点的边框色
,markerfacecolor='brown' # 点的填充色
,label = "人数"
)
#绘图
plt.plot(wechart.date[wechart.date >= '2017/9/1']
,wechart.article_reading_times[wechart.date >= '2017/9/1']
,linestyle = '-' # 折线类型
,linewidth = 2 # 折线宽度
,color = '#ff9999' # 折线颜色
,marker = 'o' # 点的形状
,markersize = 6 # 点的大小
,markeredgecolor='black' # 点的边框色
,markerfacecolor='brown' # 点的填充色
,label = "次数"
)
#设置标题
plt.title("公众号每天阅读人数和次数趋势图")
#设置x轴,y轴标题
plt.xlabel("日期/天")
plt.ylabel("人数/次数")
#设置图例
plt.legend()
# 为了避免x轴日期刻度标签的重叠,设置x轴刻度自动展现,并且45度倾斜
fig.autofmt_xdate(rotation = 45)
#显示图形
plt.show()
- 两条折线图很完美的展现在一张图中,公众号的阅读人数与次数趋势完全一致,而且具有一定的周期性,即过几天就会有一个大幅上升的波动,这个主要是由于双休日的时候,时间比较空闲,就可以更新并推送文章了。
#导入对应的库
import matplotlib.pyplot as plt
#解决中文乱码问题
plt.rcParams["font.sans-serif"] = ['Microsoft YaHei']
# 设置图框的大小
fig = plt.figure(figsize=(10,6))
#绘图
plt.plot(wechart.groupby(by = "月份").aggregate({"article_reading_cnts":sum}).index
,wechart.groupby(by = "月份").aggregate({"article_reading_cnts":sum})
,linestyle = '-' # 折线类型
,linewidth = 2 # 折线宽度
,color = 'steelblue' # 折线颜色
,marker = 'o' # 点的形状
,markersize = 6 # 点的大小
,markeredgecolor='black' # 点的边框色
,markerfacecolor='steelblue' # 点的填充色
,label = "人数"
)
plt.plot(wechart.groupby(by = "月份").aggregate({"article_reading_cnts":sum}).index
,wechart.groupby(by = "月份").aggregate({"article_reading_times":sum})
,linestyle = '-' # 折线类型
,linewidth = 2 # 折线宽度
,color = '#ff9999' # 折线颜色
,marker = 'o' # 点的形状
,markersize = 6 # 点的大小
,markeredgecolor='black' # 点的边框色
,markerfacecolor='#ff9999' # 点的填充色
,label = "次数"
)
#设置标题
plt.title("公众号文章九月份阅读人数折线图")
#设置x轴,y轴标题
plt.xlabel("日期/天")
plt.ylabel("人数")
#设置图例
plt.legend()
# 为了避免x轴日期刻度标签的重叠,设置x轴刻度自动展现,并且45度倾斜
fig.autofmt_xdate(rotation = 45)
#显示图形
plt.show()
总结
- 折线图的制作同条形图以及直方图一样,在原来图的基础上,在添加即可,不同的是直方图与折线图直接添加就可以了,条形图需要设置好相对的位置来展示另一个条形图



