matplotlib
Matplotlib是一个帮助我们绘制数据的python库。通过它,你可以画出线图、散点图、等高线图; 条形图、直方图、3D 图形甚至是图形动画等等。
当横轴为时间时,使用线图
当两个变量存在相关性时,使用散点图
当想要观察数值数据的分布时,使用直方图
我们可以在图表中定义以下属性:颜色、标签、线宽、标题、不透明度、网格、图形大小、坐标轴刻度、线型等
条形图
-
条形图:一种以长方形的长度为变量的表达图形的统计报告图,由一系列高度不等的纵向条纹表示数据分布的情况,用来比较两个或以上的价值(不同时间或者不同条件),只有一个变量,通常利用于较小的数据集分析
- 条形图:柱形图、堆积柱形图、百分比堆积柱形图等。
-
适用场景
- 适合分析分类数据字段、或者连续的数据字段,利用柱子的高度来反映数据的数值差异。、
- 适合分析对比组内各项数据
- 堆积柱:可以形象的展示一个大分类包含的每个小分类的数据,以及小分类的占比情况,显示的是单个项目与整体之间的关系
- 百分比堆积柱形图:矩形高度表示每子项占当前项的百分比
案例
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
x=np.arange(1,6)
y=np.random.randint(1,100,5) #随机生成5个1到100之间的数
条形图:维度分类较多或维度名称比较长的时候使用横向树状图(条形图)
plt.bar(x,y,color='g')
plt.show()
堆积图:更直观对比整体的数据,可以更清晰的看出各种类别的占比情况
y.plot(kind='barh',stacked=True,figsize=(16,9)) #传递参数stacked=True来生成堆积树状图
plt.show()
百分比堆积树状图:展示的占比的情况
y.div(data.sum(1),axis=0).plot(kind='barh',figsize=(16,9),stacked=True)
plt.show()
直方图
-
直方图:又称质量分布图,是一种统计报告图,由一系列高度不等的纵向条纹或线段表示数据分布的情况。 一般用横轴表示数据类型,纵轴表示分布情况。用来整理计量值的观测数据,分析其分布状态的统计方法,用于对总体的分布特征进行推断
应用场景:表示分布状态,分析数据是否服从正态分布,判断数据是否异常或者孤立
-
直方图与柱状图的比较:
直方图展示数据的分布,柱状图比较数据的大小。这是直方图与柱状图最根本的区别。直方图表示在一定值的区间中,有多少数据,表现的是数据的分布情况。柱状图表示,每一个数据的值的大小,表现的是值大小的对比
直方图X轴为定量数据,柱状图X轴为分类数据。 直方图的x轴通常是连续排列的,柱状图是分开排列的
柱状图是以矩形的长度表示每一组的数据大小,其宽度(表示类别)则是固定的,利于较小的数据集分析。
直方图是以矩形的长度表示每一组的频数或频率,宽度则表示各组的组距,因此其高度与宽度均有意义,利于展示大量数据集的统计结果。
-
画直方图一般流程
- 计算极差(最大值 - 最小值)
- 设置组距
- 计算组数(极差/ 组距)(通常对于数据较少的情况,分为5 ~ 12组 )
案例
x=np.random.randn(500)
plt.hist(x,bins=20,color='g',rwidth=0.5)
plt.show()
散点图
-
散点图:用两组数据构成多个坐标点,考察坐标点的分布,判断两变量之间是否存在某种关联或总结坐标点的分布模式。散点图将序列显示为一组点。值由点在图表中的位置表示。
应用场景:判断两个变量之间是否存在关联,判断异常值
探究 投资额和住宅投资的关系
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
x=np.arange(10)
y_c=np.random.normal(size=10)
plt.scatter(x,y_c,color='y')
饼图
-
饼图:用于表示不同分类的占比情况,通过弧度大小来对比各种分类。饼图通过将一个圆饼按照分类的占比划分成多个区块,整个圆饼代表数据的总量,每个区块(圆弧)表示该分类占总体的比例大小,所有区块(圆弧)的加和等于 100%。
应用场景:分类占比
每个省份投资额占比
from matplotlib import pyplot as plt
a=np.random.randint(1,10,5)
plt.pie(a,autopct="%1.2f%%",shadow=True,explode=(0,0,0.3,0,0),startangle=90)
plt.show()
#让饼图保持正圆形
plt.axis('equal')
plt.show()
参数解释:
y 为dataframe列名,或者列名列表,当绘制多列数据,指定subplots=True,绘制在不同的子图中
autopct:在图中显示百分比
shadow:布尔值,为饼图增加阴影效果
explode:为饼图增加破裂效果,值越大,破裂越大
startangle:饼图旋转角度,从X轴逆时针旋转
折线图
-
折线图:可以很直观的反应出数据的变化趋势,反应事物的变化情况
- 应用场景:适合二维的大数据集,还适合多个二维数据集的比较
-
案例
-
绘制标普500指数的收盘价的变化
import numpy as np import pandas as pd import matplotlib.pyplot as plt data = pd.read_csv('d:/test_data/spx.csv',index_col='Unnamed: 0',parse_dates=True) #index_col:DataFrame的列用作行索引, parse_dates:解析索引 data.head() SPX 1990-02-01 328.79 1990-02-02 330.92 1990-02-05 331.85 1990-02-06 329.66 1990-02-07 333.75
-
面向对象画图
#创建画布 fig,ax=plt.subplots(figsize=(16,6),dpi=100) #准备数据 x=data.index y=data['SPX'] ax.plot(x,y,color='r') plt.show()
-
*在图中截取2007-2010年金融危机部分*
```python
#截取2007-2011年
#set_xlim, setylim:设置图表的边界
ax.set_xlim(['2007-1-1','2011-1-1'])
#截取SPX>600
ax.set_ylim([600,1800])
#添加标题
ax.set_title('2007-2010年金融危机标普500指数变化趋势')
#添加坐标轴标签
ax.set_xlabel('Date')
ax.set_ylabel('SPX')
```
*在图中添加文字*
```python
# ax.annotate('Peak of bull market',xy=(datetime(2007,10,11),y['2007-10-11']),
xytext=(datetime(2007,10,11),y['2007-10-11'] + 160),
arrowprops=dict(facecolor='c'))
"""
s:字符串,注释文本
xy:注释的点(x,y)
xytext:放置文本的位置(x,y)
arrowprops:在xy和xytext之间绘制箭头的属性(字典)
"""
crisis_date = [
(datetime(2007,10,11),'Peak of bull market'),
(datetime(2008,3,12),'Bear Stearns Fails'),
(datetime(2008,9,15),'Lehman Bankruptcy')
]
for date,label in crisis_date:
ax.annotate(label,xy=(date,y[date]),xytext=(date,y[date]+160),
arrowprops=dict(facecolor='c'))
```
*关于annotate更多请参考:*
*https://matplotlib.org/api/_as_gen/matplotlib.pyplot.annotate.html*
*https://matplotlib.org/users/annotations_intro.html*
*在这里我们另外补充了面向对象画图的另外几个功能*
-
Dataframe画图
在前面我们都是直接使用 matplotlib进行绘图,我们的pandas集成了matplotlib画图的方法,我们也可以还有 pandas直接进行绘制
import numpy as np import pandas as pd import matplotlib.pyplot as plt from datetime import datetime data = pd.read_csv('d:/test_data/spx.csv',index_col='Unnamed: 0',parse_dates=True) data.plot(figsize=(16,6),color='r', xlim=['2007-1-1','2011-1-1'], ylim =[600,1800], title='2007-2010年金融危机标普500指数变化趋势' ) #plt.xlim(['2007-1-1','2011-1-1']) #plt.ylim([600,1800]) plt.xlabel('Date') plt.ylabel('SPX') crisis_date = [ (datetime(2007,10,11),'Peak of bull market'), (datetime(2008,3,12),'Bear Stearns Fails'), (datetime(2008,9,15),'Lehman Bankruptcy') ] for date,label in crisis_date: plt.annotate(label,xy=(date,y[date]),xytext=(date,y[date]+160), arrowprops=dict(facecolor='c')) plt.show()
我们使用dataframe画图,当不能满足于我们的需求时,可以和 plt方法,或者面向画图方法结合使用
箱线图
-
箱线图:是一种直观简洁的方式去呈现一组数据的分布. 因其形状如箱子而得名. 箱线图广泛用于各个数据分析领域. 它能非常简单明了地显示一组数据中5个重要数值, 最大值 (Maximum Value), 最小值 (Minimum Value), 中位数 (Median Value), 下四分位数 (First Quartile), 上四分位数 (Third Quartile). 箱线图还能发现一组数据中的存在的异常值 (Outliers).
分位数:把所有数值由小到大排列并分成四等份,处于三个分割点位置的数值就是四分位数。
🐉查看投资数据的异常值
x=np.random.randint(1,11,10)
plt.boxplot(x)
print(x)
plt.show()
matplotlib参数调整
在前面我们已经知道了matplotlib图的结构,下面我们着重于matplotlib的辅助显示,颜色,标记,线类型,刻度,标签,图例,以及图片保存
-
模拟股票10分钟的变化趋势
- 画出股票趋势图
import numpy as np import pandas as pd import matplotlib.pyplot as plt #1)准备数据 x = range(1,11) #股票10分钟 y = np.random.normal(size=10) #正态分布随机生成10个数据 #2)创建画布 fig = plt.figure(figsize=(16,6),dpi=100) #设置大小,设置dpi #3)绘制折线图 plt.plot(x,y) #4)显示图像 plt.show() #show方法会释放figure资源
-
设置刻度标签,设置刻度值
plt.xticks(x,kwargs):x:显示的刻度值
plt.yticks(y,kwargs):y:显示的刻度值
#构造刻度标签 x_ticks_label = ['10点{}分'.format(i) for i in x] plt.xticks(x,x_ticks_label,rotation=45) #rotation:将刻度标签旋转多少度
-
设置轴标签,标题
#设置x,y轴标签 plt.xlabel('时间') plt.ylabel('涨幅') #设置图像标题 plt.title('股票10分中的涨幅')
-
设置颜色,标记和线类型
#设置颜色color #设置线类型linestyle #设置标记marker plt.plot(x,y,color='r',linestyle='--',marker='o')
-
显示图例
可能我们在一个绘图区,需要绘制多个图形,多次plot就可以解决
#在添加一条数据 y_B = np.random.normal(size=10) #进行绘制 #plt.plot(x,y_B,color='b',marker='o') #添加图例 #显示图例我们需要先加上label标签 plt.plot(x,y,color='r',linestyle='--',marker='o',label='A') plt.plot(x,y_B,color='b',marker='o',label='B') plt.legend(loc='best') #添加网格显示 plt.grid(True,linestyle='--',alpha=1) #appha:透明度
-
常见颜色
标识 描述 r 红色 g 绿色 b 蓝色 w 白色 c 青色 m 洋红 y 黄色 k 黑色 -
常见线类型
标识 描述 - 实线 -- 虚线 -. 点划线 : 点虚线 ‘’ 空格 -
常见标记
标识 描述 '.' point marker ',' pixel marker 'o' circle marker 'v' triangle_down marker '^' triangle_up marker '<' triangle_left marker '>' triangle_right marker '1' tri_down marker '2' tri_up marker '3' tri_left marker '4' tri_right marker 's' square marker 'p' pentagon marker '*' star marker 'h' hexagon1 marker 'H' hexagon2 marker '+' plus marker 'x' x marker 'D' diamond marker 'd' thin_diamond marker '|' vline marker '_' hline marker -
显示图例位置
位置的字符串 位置的标识 best 0 upper right 1 upper left 2 lower left 3 lower right 4 right 5 center left 6 center right 7 lower center 8 upper center 9 center 10
matplotlib图像构造
-
实现一个简单的matplotlib画图
import numpy as np import matplotlib.pyplot as plt data= np.arange(10) plt.plot(data) #折线图函数 plt.show()#输出图像
-
Part of a Figure
matplotlib绘制的图位于 (Figure)对象中
-
Figure:整个图形(可以改变大小和分辨率),想象为画画的画布,可以有任意数量的 Axes,至少要有一个有用
#创建一个画布 fig = plt.figure() """ 参数: figsize:画布大小,默认None,(width,height)整数元组 dpi:图像分辨率,默认None,整数 facecolor:背景颜色 """
Axes:坐标系,数据绘图的区域
Axis:坐标轴(大小限制,刻度,刻度标签),坐标系中的一条轴
-
辅助显示层
辅助显示层为Axes(绘图区)内的除了根据数据绘制出的图像以外的内容,主要包括Axes外观(facecolor)、边框线(spines)、坐标轴(axis)、坐标轴名称(axis label)、坐标轴刻度(tick)、坐标轴刻度标签(tick label)、网格线(grid)、图例(legend)、标题(title)等内容。
-
图像层
图像层指Axes内通过plot、scatter、bar、histogram、pie等函数根据数据绘制出的图像。
matplotlib绘制子图
- 我们在程序中尽量采用面向对象进行绘图,有利于我们可以绘制多个子图,这里为了大家更方便的理解,给出一般的画图流程
-
plt.subplots:(nrows,ncols,sharex,sharey,fig_kw)
参数 描述 nrows 子图的行数 ncols 子图的列数 sharex 子图共享x轴刻度,默认:False sahrey 子图共享y轴刻度,默认:False **fig_ky 生成画布时使用额外的关键字参数 *subplots创建一个新的画布,返回是一个元组,包含 figure对象,生成子图对象的 Numpy数组, 我们在选择子图对象时,可以使用索引进行选取,同时我们在相同比例下进行数据对比的时候可以使用 sharex,sharey来让子图拥有相同的 x轴或 y轴刻度.
#创建一个包含4个子图对象的figure,默认生成1个 plt.subplots(2,2,figsize=(16,6),dpi=100) #返回一个元组,里面包含了figure对象,以及4个子图对象 #选取子图进行绘制,选取第二行的第二个进行绘制 #准备数据 fig,axs = plt.subplots(2,2,figsize=(16,6),dpi=100,sharex=True,sharey=True) x=[1,2,3,4,5] y=[0.6,0.8,-0.3,0.2,-0.1] #选取我们所需的子图我们使用数组索引 axs[1,1].plot(x,y)
从上图我们可以看出,我们子图和子图之间默认会有一定的间距,我们可以使用subplots_adjust对间距进行调整
subplts_adjust(wspace, hspace)
wspace:宽度百分比:
hspace:高度百分比
#调整子图的间距
plt.subplots_adjust(wspace=0,hspace=0) #消除了子图与子图之间的间距
-
模拟股票10分钟变化趋势,使用面向对象进行绘图
使用面向对象绘图有一些基本方法改变:
set_xticks:设置 x轴的刻度
set_yticks:设置 y轴的刻度
set_xticklabes:设置 x轴的刻度标签
set_yticklabes:设置 y轴的刻度标签
set_xlabel:设置 x轴标签
set_ylabe:设置 y轴标签
set_title:设置标题
#创建画布,默认生成一个 fig,ax = plt.subplots(figsize=(16,6),dpi=100) #面向对象进行画图 ax.plot(x,y,color='r',linestyle='--',marker='o',label='A') ax.plot(x,y_B,color='b',marker='D',label='B') #显示图例,默认是best ax.legend() #添加网格 ax.grid(linestyle='--',alpha=1) #添加标题 ax.set_title('股票10分中的涨幅') #设置轴的标签 ax.set_xlabel('时间') ax.set_ylabel('涨幅') #设置刻度值 ax.set_xticks(x) #设置刻度值标签 ax.set_xticklabels(x_ticks_label) #释放figure资源,输出图像 plt.show()
- 绘制子图
#创建一个2*1的画布
fig,axs = plt.subplots(2,1,figsize=(16,6),dpi=100,sharex=True)
#多个子图进行绘图的时候,我们需要选择我们绘图区(axes)
#选择第一个axes
axs[0].plot(x,y,color='r',linestyle='--',marker='o',label='A')
#选择第二个axes
axs[1].plot(x,y_B,color='b',marker='D',label='B')
axs[0].legend()
axs[1].legend()
axs[0].grid(linestyle='--',alpha=1)
axs[1].grid(linestyle='--',alpha=1)
axs[0].set_title('A股票10分中的涨幅')
axs[1].set_title('B股票10分中的涨幅')
axs[0].set_xlabel('时间')
axs[1].set_xlabel('时间')
axs[0].set_ylabel('涨幅')
axs[1].set_ylabel('涨幅')
#在创建画布的时候,设置了sharex=True,所有的子图共享x轴刻度
axs[0].set_xticks(x)
axs[0].set_xticklabels(x_ticks_label)
plt.show()