目录
本书中所有的数据文件保存在data文件夹中,链接如下:
https://pan.baidu.com/s/1Tu__B-YfXDz_yXzbzNKB4A?pwd=sfw2
提取码:sfw2
P70思考与练习1
1.叙述Pandas和Matplotlib绘图工具之间的关系。如何在绘图中综合使用两种工具的绘图函数,达到既快速绘图又可精细化设置图元的目标。
1.pandas封装了Matplotlib的主要绘图功能。pandas基于Series与DataFrame绘图,使用Series与DataFrame封装数据,调Series.plot()或DataFrame.plot()完成绘图。pandas绘图简单直接,若要更细致地控制图标样式,如添加标注、在一幅图中包含多副子图,必须使用Matplotlib提供的基础函数。Matplotlib中使用pyplot的图元设置函数来实现图形的精细化设置,能够对pandas绘出的图形进行精细化设置。
我们可以先将数据封装成Series或DataFrame,通过Pandas快速绘图,最后再通过Matplotlib中的pyplot图元设置函数对图形进一步精细化设置,达到精细化绘图的目的。
2. 2012~2020年我国人均可支配收入为[1.47, 1.62, 1.78, 1.94, 2.38, 2.60,2.82,3.07,3.21](单位:万元)。按照要求绘制以下图形。
1)模仿例4-1和4-3,绘制人均可支配收入折线图。用小矩形标记数据点,黑色虚线,用注解标注最高点,图例标题“Income ”,设置坐标轴标题,最后将图形保存为jpg文件。
2)模仿例4-2,使用多个子图分别绘制人均可支配收入的折线图、箱形图以及柱状图(效果如下图所示)。
【提示】:
(1)本实验准备数据时可使用Series对象或DataFrame对象。
(2)创建3个子图分别使用(2,2,1)、(2,2,2)和(2,1,2)作为参数。
(3)使用plt.subplots_adjust()函数调整子图间距离,以便添加图标题。
新书第二版要求的画图效果
第(1)题:
共列举以下三种方法
【方法一】:使用Series.plot画图,数据为Series形式
【方法二】:使用DataFrame.plot画图,数据为DataFrame形式
【方法三】:使用plt.plot函数画图(默认kind='line‘,画折线图),数据为列表形式
#方法一:Series.plot
import matplotlib.pyplot as plt
from pandas import Series
Income_data = Series([1.47, 1.62, 1.78, 1.94, 2.38, 2.60,2.82,3.07,3.21],index = ['2012','2013','2014','2015','2016','2017','2018','2019','2020'])
Income_data.plot(title = '2012-2020 年人均可支配收入',marker = 's',linestyle = 'dotted',grid = True,label = 'Income',
yticks = [0.0,0.5,1.0,1.5,2.0,2.5,3.0,3.5],c = 'black') #label代表图例,c代表线、点的颜色
plt.xlabel('Year') #添加x轴标题
plt.ylabel('Income(RMB Ten Thousand)') #添加y轴标题
plt.legend() #显示图例,若无则不显示
plt.annotate('Largest!',xy = (8,3.21),xytext = (6.1,2.6),arrowprops = dict(arrowstyle = '->',color = 'r'),color = 'r') #xy为箭头位置坐标,xytext为文字起点位置
plt.show()
#方法二:DataFrame.plot
import matplotlib.pyplot as plt
from pandas import DataFrame
#DataFrame1中columns即为图例,index即为横坐标值
Income_data = DataFrame([1.47, 1.62, 1.78, 1.94, 2.38, 2.60,2.82,3.07,3.21],index = ['2012','2013','2014','2015','2016','2017','2018','2019','2020'],columns = ['Income'])
Income_data.plot(title = '2012-2020 年人均可支配收入',marker = 's',linestyle = 'dotted',grid = True,
yticks = [0.0,0.5,1.0,1.5,2.0,2.5,3.0,3.5],c = 'black')
plt.xlabel('Year')
plt.ylabel('Income(RMB Ten Thousand)')
plt.annotate('Largest!',xy = (8,3.21),xytext = (6.1,2.6),arrowprops = dict(arrowstyle = '->',color = 'r'),color = 'r')
plt.show()
#方法三:plt.plot
import matplotlib.pyplot as plt
Income_data = [1.47, 1.62, 1.78, 1.94, 2.38, 2.60,2.82,3.07,3.21]
plt.plot(['2012','2013','2014','2015','2016','2017','2018','2019','2020'],[1.47, 1.62, 1.78, 1.94, 2.38, 2.60,2.82,3.07,3.21],marker = 's',
linestyle = 'dotted',c = 'black',label = 'Income')
plt.title('2012-2020 年人均可支配收入')
plt.yticks([0.0,0.5,1.0,1.5,2.0,2.5,3.0,3.5])
plt.xlim(0,8) #设置x轴刻度范围
plt.xlabel('Year')
plt.ylabel('Income(RMB Ten Thousand)')
plt.annotate('Largest!',xy = (8,3.21),xytext = (6.1,2.6),arrowprops = dict(arrowstyle = '->',color = 'r'),color = 'r')
plt.legend()
plt.grid() #显示网格线
结果如下:
第(2)题:
共列举以下6种方法
可采用figure.add_subplot()函数或plt.subplot()两种函数创建子图。而数据形式分别为Series、DataFrame与列表三种形式。由此列举6种方法求解。
前三种方法采用figure.add_subplot()函数
【方法一】:采用figure.add_subplot()函数创建子图。使用Series.plot画图,数据为Series形式。
【方法二】:采用figure.add_subplot()函数创建子图。使用DataFrame.plot画图,数据为DataFrame形式。
【方法三】:采用figure.add_subplot()函数创建子图。使用各类画图函数画图(plt.plot()画折线图,plt.boxplot()画箱形图,plt.bar()画柱状图),数据为列表形式。
后三种方法采用plt.subplot()函数
【方法四】:采用plt.subplot()函数创建子图。使用Series.plot绘图,数据为Series形式。
【方法五】:采用plt.subplot()函数创建子图。使用DataFrame.plot画图,数据为DataFrame形式。
【方法六】:采用plt.subplot()函数创建子图。使用各类画图函数画图(plt.plot()画折线图,plt.boxplot()画箱形图,plt.bar()画柱状图),数据为列表形式。
前三种方法(采用figure.add_subplot()函数):
先定义画布:fig = plt.figure(figsize = ())
再创建子图:fig.add_subplot()或者ax1... = fig.add_subplot()
对于Series与列表类型的数据:可不返回ax=ax1,ax=ax2,ax=ax3....。(也可返回)
对于DataFrame类型的数据:写为ax1(ax2、ax3...) = fig.add_subplot(),每次画图在画图函数里都要返回ax=ax1,ax=ax2,ax=ax3....。例如DataFrame.plot(...,ax = ax1)等,否则画图出错。
#方法一:采用figure.add_subplot()函数创建子图。使用Series.plot画图,数据为Series形式
import matplotlib.pyplot as plt
from pandas import Series
Income_data =Series([1.47, 1.62, 1.78, 1.94, 2.38, 2.60,2.82,3.07,3.21],index = ['2012','2013','2014','2015','2016','2017','2018','2019','2020'])
fig = plt.figure(figsize = (10,6)) #figure创建绘图对象,figsize设置画布尺寸
#将绘图区域分为2行2列4份,在第1份上作图
ax1 = fig.add_subplot(2,2,1)
#绘制折线图
ax1.plot(Income_data) #采用AxesSubplot绘制折线图
plt.title('Line chart')
plt.xlabel('Year')
plt.ylabel('Incone')
'''
还可采用Series.plot()函数绘制折线图:
Income_data.plot(title = 'Line chart') #采用Series.plot画折线图
plt.xticks(range(0,9),['2012','2013','2014','2015','2016','2017','2018','2019','2020']) #让x轴刻度显示全
plt.xlim(-0.5,8.5) #增大x轴刻度范围
plt.xlabel('Year')
plt.ylabel('Income')
'''
#将绘图区域分为2行2列4份,在第2份上作图
ax2 = fig.add_subplot(2,2,2) #也可去掉"ax2="写为fig.add_subplot(2,2,2)
#绘制箱形图
Income_data.plot(kind = 'box',title = 'Box-whisker plot')
plt.xlabel('2012-2020')
plt.ylabel('Income')
plt.xticks([])
#将绘图区域分为2行1列2份,在第2份作图
ax3 = fig.add_subplot(2,1,2) #也可去掉"ax3="写为fig.add_subplot(2,1,2)
#绘制柱状图
Income_data.plot(kind = 'bar',label = 'Income')
plt.title('Bar chart')
plt.xlabel('Year')
plt.ylabel('Income')
plt.legend() #显示图例
#调整子图间距离
plt.subplots_adjust(wspace = 0.5,hspace = 0.5)
#方法二:采用figure.add_subplot()函数创建子图。使用DataFrame.plot画图,数据为DataFrame形式,需返回ax=ax1,ax=ax2,ax=ax3
import matplotlib.pyplot as plt
from pandas import DataFrame
Income_data =DataFrame([1.47, 1.62, 1.78, 1.94, 2.38, 2.60,2.82,3.07,3.21],index = ['2012','2013','2014','2015','2016','2017','2018','2019','2020'],
columns = ['Income'])
fig = plt.figure(figsize = (10,6))
#画折线图
ax1 = fig.add_subplot(221) #(2,2,1)可连写(221)
Income_data.plot(title = 'Line chart',legend = False,ax = ax1) #返回ax1 #legend = False去掉图例
plt.xticks(range(0,9),['2012','2013','2014','2015','2016','2017','2018','2019','2020']) #让x轴刻度显示全
plt.xlim(-0.5,8.5) #增大x轴刻度范围
plt.xlabel('Year')
plt.ylabel('Income')
#画箱形图
ax2 = fig.add_subplot(222)
Income_data.plot(kind = 'box',title = 'Box-whisker plot',xticks = [],ax = ax2) #返回ax2
plt.xlabel('2012-2020')
plt.ylabel('Income')
#画柱状图
ax3 = fig.add_subplot(212)
Income_data.plot(kind = 'bar',title = 'Bar chart',ax = ax3) #返回ax3
plt.xlabel('Year')
plt.ylabel('Income')
#调间距
plt.subplots_adjust(wspace = 0.5,hspace = 0.5)
plt.savefig('Income222.jpg',dpi = 400,bbox_inches = 'tight') #保存导出图像
plt.show()
#方法三:采用figure.add_subplot()函数创建子图。使用各类画图函数画图,数据为列表形式
import matplotlib.pyplot as plt
Income_data = [1.47, 1.62, 1.78, 1.94, 2.38, 2.60,2.82,3.07,3.21]
fig = plt.figure(figsize = (10,6))
#画折线图
fig.add_subplot(221)
plt.plot(['2012','2013','2014','2015','2016','2017','2018','2019','2020'],Income_data) #折线图函数:plt.plot()
plt.title('Line chart')
plt.xlabel('Year')
plt.ylabel('Incone')
#画箱形图
fig.add_subplot(222)
plt.boxplot(Income_data,boxprops = {'color':'#1F77B4'},medianprops = {'color':'green'},whiskerprops={'color':'#1F77B4'})
#箱形图函数:plt.boxplot()。boxprops设置箱体的属性,whiskerprops设置须的属性,medianprops设置中位数的属性
plt.title('Box-whisker plot')
plt.xlabel('2012-2020')
plt.xticks([]) #不显示坐标轴刻度
plt.ylabel('Income')
#画柱状图
fig.add_subplot(212)
plt.bar(['2012','2013','2014','2015','2016','2017','2018','2019','2020'],Income_data,label = 'Income') #柱状图函数:plt.bar(x,height)
plt.title('Bar chart')
plt.legend()
plt.xlabel('Year')
plt.xticks(rotation = 90) #rotation设置刻度旋转角度值
plt.ylabel('Income')
#调间距
plt.subplots_adjust(wspace = 0.5,hspace = 0.5)
plt.savefig('Income2.jpg',dpi = 400,bbox_inches = 'tight')
plt.show()
后三种方法(采用plt.subplot()函数):
思路同上三种方法。
先定义画布:plt.figure(figsize = ())
再创建子图:plt.subplot()
对于Series与列表类型的数据:可不返回ax=ax1,ax=ax2,ax=ax3....。(也可返回)
对于DataFrame类型的数据:写为ax1(ax2、ax3...) = plt.subplot(),每次画图在画图函数里都要返回ax=ax1,ax=ax2,ax=ax3....。否则画图出错。如下:
#方法四:采用plt.subplot()函数创建子图。使用Series.plot绘图,数据为Series形式
import matplotlib.pyplot as plt
from pandas import Series
Income_data = Series([1.47, 1.62, 1.78, 1.94, 2.38, 2.60,2.82,3.07,3.21],index = ['2012','2013','2014','2015','2016','2017','