关于matplotlib详解,请看这篇文章
1. matplotlib入门
1.1 %matplotlib inline与%matplotlib notebook
%matplotlib notebook
是在Jupyter中,用于生成交互式绘图
如果只是简单的画图,不需要生成交互式绘图,则在jupyter中只需要使用魔术命令%matplotlib inline
而%matplotlib
是在IPython中画图需要的,用于在IPython生成交互式绘图
%matplotlib inline#注意与下面的%matplotlib notebook生成的图比较
import matplotlib.pyplot as plt
import numpy as np
data = np.arange(10)
print(data)
plt.plot(data,data)
%matplotlib notebook#注意与上面的%matplotlib inline生成的图比较
import matplotlib.pyplot as plt
import numpy as np
data = np.arange(10)
print(data)
plt.plot(data,data)
1.2 图片与子图
两种生成图和子图的方式:
-
#先生成图,然后添加子图 fig = plt.figure() ax1 = fig.add_subplot(2,2,1)#子图序号从1开始 ax2 = fig.add_subplot(2,2,2) ax3 = fig.add_subplot(2,2,3)
-
fig,axes = plt.subplots(2,2)#图与子图一起生成 #这里通过axes数组来调用某个子图时,和正常数组索引一样,从零开始,而不像上面一样,子图序号从1开始
在Jupyter中,最好将所有的绘图命令放在一个单元格内,因为在Jupyter中每个单元格运行后,图表会被重置,在后面运行的绘图指令可能不会显示。
子图就是坐标系,但坐标系不是子图,二者区别可以看文章前面的链接。画图命令可以直接通过坐标系调用,(上面的ax1,ax2,ax3都是坐标系,axes是一个2*2的坐标系列表),如果不通过坐标系来调用绘图命令,直接通过plt来调用绘图命令,则会自动调用子图中最后一个子图来绘图
fig,axes = plt.subplots(2,2)
# axes[0,0].plot(data)
plt.plot(data)#并没有指明在哪一个子图上面绘图,会自动在最后一个子图上面绘图
1.2.1 调整子图间的间距
plt.subplots_adjust(wspace,hspace)
- wspace:表示子图间横向间隔距离
- hspace:表示子图间纵向间隔距离
fig,axes = plt.subplots(2,2)
# axes[0,0].plot(data)
plt.plot(data)
plt.subplots_adjust(wspace=0,hspace=0)#下图中,子图间的间隔为0
1.2.2 设置图的大小
在生成图的时候传入参数figsize=(长,宽),就可以设置图的大小,长和宽的的单位都是像素
具体来说
- figure = plt.figure(figsize=(长,宽))
- figure,axes = plt.subplots(nrows,ncols,figsize=(长,宽))
1.3 设置绘图范围
- 获取绘图范围
- plt.xlim(),plt.ylim()
- ax.get_xlim(),ax.get_ylim()
- 优先选用ax方式来获得绘图范围
- 设置绘图范围
- plt.xlim([0,10]),plt.ylim([0,10])
- ax.set_xlim([0,10]),ax.set_ylim([0,10])
- 上面两种方法将坐标轴的绘图范围设置为0到10
- 优先选用ax的方式来设置绘图范围,因为比较清晰,比较显示知道在干什么
1.4 设置标题
ax.set_title('title')
1.5 设置轴标签
ax.set_xlabel('xlabel')#设置x轴的标签
ax.set_ylabel('ylabel')#设置y轴的标签
1.6 设置刻度以及刻度标签
ax.set_xticks([0,250,500,750,1000])
ax.set_xticklabels(['one','two','three','four','five'],rotation=30,fontsize='small')
#y轴上面的刻度设置类似
1.7 批量设置绘图属性
props = {'title':'my title','xlabel':'xlabel'}
ax.set(**props)#即可批量设置ax的标题和x轴标签,两个*不能少
1.2~1.7举例
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
fig,ax = plt.subplots(2,2,figsize=(10,10))#设置图片大小
plt.subplots_adjust(wspace=0.15,hspace=0.15)#设置子图间间距
data = np.random.randn(1000).cumsum()
ax[0,0].plot(data)
ax[0,0].get_xlim()
ax[0,0].get_ylim()
ax[0,0].set_xlim(-100,1100)#设置x轴的绘图范围
ax[0,0].set_ylim(data.min()-10,data.max()+10)#设置y轴的绘图范围
ax[0,0].set_title('Random Data')#设置标题
ax[0,0].set_xlabel('xlabel')#设置x轴的标签
ax[0,0].set_ylabel('ylabel')#设置y轴的标签
ax[0,0].set_xticks([0,200,400,600,800,1000])#设置x轴上的刻度
ax[0,0].set_xticklabels(['a','b','c','d','e','f'],rotation=30,fontsize='small')#设置x轴上的刻度标签
#######上述属性设置,除了xticklabels中的rotation和fontsize不知道怎么用下面方法代替,其他全部可以通过下面set方法,批处理代替
# props = {'title':'Random Data','xlim':[-100,1100],'ylim':[data.min()-10,data.max()+10],
# 'xlabel':'xlabel','ylabel':'ylabel','xticks':[0,200,400,600,800,1000],
# 'xticklabels':['a','b','c','d','e','f']}
# ax[0,0].set(**props)
没有使用set批处理方法的结果
使用set批处理方法的结果
1.8 添加图例
ax.legend(loc)
- loc:传入的参数表示显示图例的位置,一般传入’best’,它会自动选择合适的位置
- 只有画图时传入了label参数(比如调用plot()函数画折线时,传入了label参数),调用ax.legend()才会有用
- 如果想要不想在图例中显示label,则画图时不要传入label参数,或者传入label=’_nolegend_’
1.9 添加文本
ax.text(x,y,文本,family,fontsize)
- x,y分别是文本的坐标
- 文本:要显示的文本内容
- family:字体
- fontsize:文本大小
ax.text(x,y,'hello.world',family='monospace',fontsize=10)
1.10 添加注释
注释可以同时绘制文本和箭头
ax.annotate(label,xy,xytext,ha,va,arrowprops)
- label:要显示的文本
- xy:箭头的头坐标
- xytext:箭头的尾坐标
- ha:水平对齐方式
- va:竖直对齐方式
- arrowprops:传入一个字典,设置箭头的其他属性
ax.annotate('hello',xy=(1,1),xytext=(5,5),ha='center',va='center',arrowprops=dict(facecolor='black',headwidth=4,width=2,headlength=4))
1.11 保存图片
plt.savefig(fname,dpi,facecolor,format,bbox_inches)
- fname:要保存的文件路径或者Python文件型对象字符串。图片格式可以从文件扩展名推断出来(.png,.pdf等)
- dpi:分辨率,默认是100
- facecolor或edgecolor:子图之外的图形的背景颜色;默认是白色的(‘w’)
- format:文件格式。在只给出文件名,没有给出文件扩展名时,可以通过这个参数来指明文件格式
- bbox_inches:要保存的图片范围,如果传入’tight’,则会去除图片周围空白部分
plt.savefig('figpath.png',dpi=400,bbox_inches='tight')
#fname不一定需要传入文件的路径,也可以传入Python文件型对象字符串
from io import BytesIO
buffer = BytesIO()
plt.savefig(buffer)
plot_data = buffer.getvalue()
1.12 全局设置matplotlib
plt.rc(参数1,参数2)
- 参数1:你想要重新设置属性的组件
- 参数2:你想修改的组件的属性,既可以传入一个属性,也可以传入一个字典,一次性修改多个属性
plt.rc('figure',figsize=(3,6))#将图的大小设置为3*6
font_options = {'family':'monospace','weight':'bold','size':'small'}
plt.rc('font',**font_options)#重新设置的字体的属性,两个*号不能少
2.常见的基本图形的绘制方法
这部分的基本图形的绘制都是基本都是基于Series对象和DataFrame对象的。
2.1 plot()折线图
ax.plot(x,y,color,linestyle,marker,label)
- plot使用来画折线图的
- x参数是折线图中的点的横坐标,可以省略这个参数,则自动使用y参数的下标当做横坐标
- y参数是折线图中的点的纵坐标,不可省略,只传入一个坐标参数时,则传入的值会被当做纵坐标
- color,线的颜色,可省略
- linestyle,线的样子,可以省略
- marker,怎样显示折线图中的点,如果省略则不显示点
- label,在生成图例legend的时候需要label来区分不同的线
2.2 Series对象和DataFrame对象中的plot()函数
2.2.1 Series对象的plot()函数
默认情况下,series.plot()绘制的是折线图,但是series.plot()可以为series对象绘制其他的图形。
Series.plot()参数列表
- label:图例的标签
- ax:绘图所用的matplotlib子图对象,如果没有传值,则使用当前活动的matplotlib子图
- style:传给matplotlib的样式字符串,如’ko–’
- alpha:图片的不透明度(从0到1)
- logy:在y轴上使用对数缩放
- use_index:bool对象,使用对象索引当做刻度标签
- rot:刻度标签的旋转度数(0到360)
- xticks:x轴刻度
- yticks:y轴刻度
- xlim:x轴的绘制范围
- ylim:y轴的绘制范围
- grid:bool对象,展示轴的网格(默认为False不展示)
import pandas as pd
s = pd.Series(np.random.randn(10).cumsum(),index=np.arange(0,100,10))
s.plot(grid=True)
2.2.2 DataFrame对象中的plot()函数
默认情况下,df.plot()会将df中的每一列绘制为不同的折线,并自动生成图例
在Series对象中的plot()函数的参数的基础上,加上下面几个参数
- subplots:bool对象,将DataFrame的每一列绘制在独立的子图中
- sharex:bool对象,如果subplots=True,则共享相同的x轴,刻度和范围
- sharey:bool对象,如果subplots=True,则共享相同的y轴
- figsize:图片的尺寸
- title:标题
- legend:bool对象,默认是True,即默认生成图例。
- sort_columns:按字母顺序绘制各列,默认情况下使用已有的列顺序
df = pd.DataFrame(np.random.randn(10,4).cumsum(axis=0),columns=['A','B','C','D'],index=np.arange(0,100,10))
df.plot()#默认绘制
df.plot(subplots=True,legend=False,title='TEST')#修改了一些属性,注意对比两幅图的区别
2.3 柱状图
- plot.bar() 用于绘制垂直柱状图
- plot.barh()用于绘制水平柱状图
- 柱状图也叫条形图
2.3.1 Series对象中的柱状图
在绘制柱状图时,Series对象或者DataFrame对象的索引会被用作x轴刻度(bar)或y轴刻度(barh)
fig, axes = plt.subplots(2,1)
s = pd.Series(np.random.randn(16),index=list('abcdefghijklmnop'))
s.plot.bar(ax=axes[0],color='k',alpha=0.7)#ax参数是指明在哪一个坐标系中画图
s.plot.barh(ax=axes[1],color='k',alpha=0.7)
2.3.2 DataFrame对象中的柱状图
在DataFrame对象中,柱状图将每一行中的值分组到并排的柱子中的一组
df = pd.DataFrame(np.random.randn(6,4),index = ['one','two','three','four','five','six'],columns=pd.Index(['A','B','C','D'],name='Genus'))
df.plot.bar()
df.plot.barh()
2.3.2.1 堆积柱状图
df.plot.bar(stacked=True)
df.plot.barh(stacked=True)
堆积柱状图会将df中的每一行的值堆积在一起
df = pd.DataFrame(np.random.randn(6,4),index = ['one','two','three','four','five','six'],columns=pd.Index(['A','B','C','D'],name='Genus'))
df.plot.bar(stacked=True)
df.plot.barh(stacked=True)
2.4 直方图和密度图
直方图是一种条形图,用于给出值频率的离散显示。数据点被分成离散的,均匀间隔的箱,并且绘制每个箱中数据点的数量
2.4.1 Series对象中的直方图
series.plot.hist(bins)
- bins,表示将数据划分为几个箱,默认值为10
- series的索引会被忽略
s = pd.Series(np.random.randn(16),index=list('abcdefghijklmnop'))
s.plot.hist()
2.4.2 DataFram对象中的直方图
df.plot.hist(bins)
不建议直接对一个df对象调用直方图,因为df.plot.hist()会对每一列调用plot.hist()函数,然后显示在一副图里面,这样会造成不同列的直方图相互覆盖,失去了图形的直观这一特点
df
df.plot.hist(bins=10)
2.3 密度图
- series.plot.density()
- df.plot.density()
密度图:通过计算可能产生观测数据的连续概率分布估计而产生。通常做法是将这种分布近似为“内核”的混合,也像正态分布那样简单的分布。因此密度图也被称之为内核密度估计图(KDE),因此密度图还可以通过**series.plot.kde()或者df.plot.kde()**方法生成。
s = pd.Series(np.random.randn(16),index=list('abcdefghijklmnop'))
s.plot.hist()
s.plot.density()
df
df.plot.density()
2.4 通过seaborn.distplot()来生成直方图和密度图
import seaborn as sns
comp1 = np.random.normal(0,1,size=200)
comp2 = np.random.normal(10,2,size=200)
values = pd.Series(np.concatenate([comp1,comp2]))
sns.distplot(values,bins=100)
2.5 散点图
只有DataFrame对象有df.plot.scatter(列名1,列名2)来画散点图的方法,Series对象没有。
-
通过df对象的plot.scatter()方法绘制散点图
df.plot.scatter('A','B')
-
通过plt.scatter()方法绘制散点图
plt.scatter(df['A'],df['B'])
-
通过seaborn库来绘制散点图
import seaborn as sns sns.scatterplot('A','B',data=df) sns.regplot('A','B',data=df)#同时画出散点图和回归线
2.6 成对图或散点图矩阵
sns.pairplot(df,diag_kind,plot_kws={})
- df:数据源,需要绘制的数据,一般是DataFrame对象
- diag_kind:表示在主对角线上,画画什么图形,如’kde’表示在主对角线上画密度图,'hist’表示在主对角线上画直方图
- plot_kws={}:表示传入的是一个字典,用来设置成对图或散点图矩阵的一些属性
import seaborn as sns
sns.pairplot(df,diag_kind='kde',plot_kws={'alpha':0.2})
2.7 分面网格和多分类数据
使用seaborn库中的factorplot()函数,可以非常方便的绘制多分类数据。factorplot()函数会返回一个包含多个子图的图,
sns.factorplot(x,y,hue,row,col,kind,data)
- x:每个子图的横轴,传入的是data的列名
- y:每个子图的纵轴,传入的是data的列名
- hue:如果分类完全了,则不需要hue参数,如果没有分类 完全,则需要hue参数来定义哪一列需要在每个子图中按类别画,传入的是data的列名
- col:如果将子图矩阵看成一个dataframe的话,col就是columns,传入的是data的列名
- row:如果将子图矩阵看成一个dataframe的话,row就是index,传入的是data的列名
- kind:表示需要画什么样的图形,如’kde’表示画密度图,'hist’表示画直方图
- data:传入的是数据源,一般是DataFrame对象,需要画图形的数据
举例:
tips.head()
sns.factorplot(x='day', y='tip_pct', hue='time', col='smoker',
kind='bar', data=tips[tips.tip_pct < 1])
sns.factorplot(x='day', y='tip_pct', row='time',
col='smoker',
kind='bar', data=tips[tips.tip_pct < 1])
sns.factorplot(x='tip_pct', y='day', kind='box',
data=tips[tips.tip_pct < 0.5])#箱线图