目录
一、Matplotlib 简介
matplotlib是python重要可视化库,通过此库绘制的图像,可以达到印刷要求直接出版。因此学习此库的内容,将非常便于今后的图形绘制,尤其在面临批量图形绘制方面,此库比excel绘制方便快捷,且易于上手,推荐学习。
二、Matplotlib库安装及调用
推荐安装anaconda工具包获得 https://www.anaconda.com/download
常用的调取方式为 import matplotlib.pyplot as plt
三、Matplotlib 快速入门
1)绘图基本要素 Figure,Axes,Axis,Artists
Figure
通常可以理解为画布,例如画画前需要准备好一张画图,用于承载所有的绘制内容;
Axes
可以理解为画布中的细分画图区域,如一张画布中,可以分为4个绘制区域,每个绘制区域可以单独绘制各种类型的图表
Axis
简单理解为图表中的轴,常规的折线图、柱状图、直方图、散点图等,均有横、纵坐标轴
Artist
图表中一切可见内容均称为Artist
2)绘图简单示例
基础包导入及设置
import pandas as pd #常规导入所需的库
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']='SimHei' #避免中文字体显示乱码
plt.rcParams['axes.unicode_minus']=False #避免坐标轴中文字体显示出现-
%matplotlib inline
#魔法函数,可以省略plt.show() 操作,在绘制图表函数被调用后即可显示图形
np.set_printoptions(suppress=True,threshold=np.nan) #不以科学计数形式展示,压缩0浮点数字
np.set_printoptions(precision=2) #显示精度为小数点后两位
pd.options.display.max_rows=100 #pandas DataFrame 显示最大行数
pd.options.display.max_columns=100 #pandas DataFrame 显示最大列数
开始绘制简单折线图
fig=plt.figure(figsize=(10,5)) #布置画布,画布大小(10,5)
ax1=fig.add_axes([0,0,1,1]) #规划画图区域,其中[0,0,1,1] 中前两位代表起始的左 、下指标。0,0代表从画布坐下角开始,后两位1,1代表画布的宽度及高度
#在绘图区域中,画折线图
x=np.arange(0,10,0.1)
y=x**2+x*2+3
ax1.plot(x,y)
基于简单示例,添加横纵轴名称,图表名称
fig=plt.figure(figsize=(10,5)) #布置画布,画布大小(10,5)
ax1=fig.add_axes([0,0,1,1]) #规划画图区域,其中[0,0,1,1] 中前两位代表起始的左 、下指标。0,0代表从画布坐下角开始,后两位1,1代表画布的宽度及高度
#在绘图区域中,画折线图
x=np.arange(0,10,0.1)
y=x**2+x*2+3
ax1.plot(x,y)
#------------------#
ax1.set_xlabel('X坐标轴',fontsize=15)
ax1.set_ylabel('Y坐标轴',fontsize=15)
ax1.set_title('我的第一个折线图',fontsize=20)
设置图表横、纵坐标轴标签显示,添加图表折线图数据展示
fig=plt.figure(figsize=(10,5)) #布置画布,画布大小(10,5)
ax1=fig.add_axes([0,0,1,1]) #规划画图区域,其中[0,0,1,1] 中前两位代表起始的左 、下指标。0,0代表从画布坐下角开始,后两位1,1代表画布的宽度及高度
#在绘图区域中,画折线图
x=np.arange(1,10,0.1)
y=x**2+x*2+3
ax1.plot(x,y)
#------------------#
ax1.set_xlabel('X坐标轴',fontsize=15)
ax1.set_ylabel('Y坐标轴',fontsize=15)
ax1.set_title('我的第一个折线图',fontsize=20)
#------------------#
ax1.set_xticks(list(range(1,11)))
ax1.set_xticklabels(['第%s天' %i for i in list(range(1,11))])
for m,n in zip(x[::2],y[::2]):
ax1.text(m,n+2,'%.d' %n,va='bottom', ha='right',bbox=dict(facecolor='y',alpha=0.1,edgecolor='r'),wrap=True)
fig.show()
设置图表折线显示、标签节点等
fig=plt.figure(figsize=(10,5)) #布置画布,画布大小(10,5)
ax1=fig.add_axes([0,0,1,1]) #规划画图区域,其中[0,0,1,1] 中前两位代表起始的左 、下指标。0,0代表从画布坐下角开始,后两位1,1代表画布的宽度及高度
#在绘图区域中,画折线图
x=np.arange(1,10,0.1)
y=x**2+x*2+3
#----本小结更新内容----#
ax1.plot(x,y,marker='*',ms=3,ls='--',color='r',mec='k')
#------------------#
ax1.set_xlabel('X坐标轴',fontsize=15)
ax1.set_ylabel('Y坐标轴',fontsize=15)
ax1.set_title('我的第一个折线图',fontsize=20)
#------------------#
ax1.set_xticks(list(range(1,11)))
ax1.set_xticklabels(['第%s天' %i for i in list(range(1,11))])
for m,n in zip(x[::2],y[::2]):
ax1.text(m,n+4,'%.d' %n,va='bottom', ha='center',bbox=dict(facecolor='lightgreen',alpha=0.1,edgecolor='k'),wrap=True)
fig.show()
四、Matplotlib常用图表介绍
折线图:plt.plot()
柱状图:plt.bar(),plt.barh()
直方图:plt.hist()
饼图:plt.pie()
盒须图:plt.boxplot()
辅助类:plt.axvline(),plt.axhline(),plt.annotate()
1、折线图
fig=plt.figure(figsize=(8,5))#创建画布
ax=fig.add_axes([0,0,1,1],facecolor='lightgreen',alpha=0.2) #创建绘图区域1
ax2=fig.add_axes([0.05,0.55,0.4,0.4],facecolor='lightblue') #创建绘图区域2
ax.plot([1,2,3],[1,2,3],color='k',marker='.') #区域1绘制折线图
ax.set_title('第一个绘制区域1',fontsize=20) #区域1绘制折线图
ax2.plot(np.arange(-np.pi,np.pi,np.pi/16),np.sin(np.arange(-np.pi,np.pi,np.pi/16)),color='r',ls='--')
ax2.set_title('第二个绘制区域')
ax.set_ylim([0,4])
ax.set_yticks(list(range(5)))
ax.set_yticklabels(['%s 吨' %i for i in list(range(5))])
fig.show()
2、柱状图
fig,ax=plt.subplots() #创建画布及绘图区域
left=np.array([1,2,3])
height=np.array([1,2,3])
ax.bar(left=left-0.1,height=height,width=0.2)
ax.bar(left=left+0.1,height=height+1,width=0.2)
ax.set_title('柱状图')
ax.set_xticks([1,2,3])
ax.set_xticklabels(['A','B','C'])
#设置数据标签
for x,y in zip(left-0.1,height):
ax.text(x,y,str(y),ha='center',va='bottom')
for x,y in zip(left+0.1,height+1):
ax.text(x,y,str(y),ha='center',va='bottom')
ax.set_yticks(np.arange(0,5,1))
fig.show()
3、直方图
fig,ax=plt.subplots() #创建画布及绘图区域
data=np.random.randint(0,1000,100)
ax.set_title('直方图')
n,bins,patches=ax.hist(data,bins=10,range=(0,1000),rwidth =1,color='lightblue')
for x,y in zip(bins,n):
ax.text(x,y,'%d' %y,ha='left',va='bottom')
ax.set_yticks(np.arange(0,20,5))
ax.set_xticks(np.arange(0,1100,100))
ax.grid(axis='x')
fig.show()
4、饼图
fig,ax=plt.subplots(figsize=(6,6)) #创建画布及绘图区域
labels=['一','二','三','四'] #标签显示
values=[1,2,3,4]
patches,texts,autotexts=ax.pie(x=values,labels=labels,autopct='%1.2f%%',explode=[0,0,0,0.1],shadow=True,startangle=180,
textprops=dict(fontsize=13)) #显示格式百分比
ax.axis('equal') #横纵轴大小相同,饼图比例协调
ax.set_title('饼图',fontsize=20,color='r')
fig.show()
5、箱形图及辅助类线形和标签
fig,ax=plt.subplots(figsize=(10,8)) #创建画布及绘图区域
values1=np.random.randint(1,500,size=1000)+np.random.randint(200,1000,1000)
values2=np.random.randint(1,500,size=1000)+np.random.randint(200,1000,1000)
ax.boxplot(x=[values1,values2],notch=True,showfliers=True,showcaps=True,labels=['A','B']) #显示格式百分比
ax.set_title('箱形图',fontsize=20,color='r')
#辅助类
ax.axhline(xmin=0,xmax=0.45,y=np.median(values1),ls='--',lw=1,color='r',label='A中位线')
ax.axhline(xmin=0,xmax=0.45,y=np.percentile(values1,75),ls='--',lw=1,color='y',label='B上四分位线')
ax.axhline(xmin=0,xmax=0.45,y=np.percentile(values1,25),ls='--',lw=1,color='g',label='C下四分位线')
ax.axhline(xmin=0.55,xmax=1,y=np.median(values2),ls='--',lw=1,color='r',label='B中位线')
ax.axhline(xmin=0.55,xmax=1,y=np.percentile(values2,75),ls='--',lw=1,color='y',label='B上四分位线')
ax.axhline(xmin=0.55,xmax=1,y=np.percentile(values2,25),ls='--',lw=1,color='g',label='B下四分位线')
ax.axvline(ymin=0,ymax=1500,x=1.5,ls='-.',lw=2,color='pink',label='分割线')
for x,y in zip([1.25]*3,np.percentile(values1,[25,50,75])):
ax.text(x,y+10,'%d' %y)
for x,y in zip([2.25]*3,np.percentile(values2,[25,50,75])):
ax.text(x,y+10,'%d' %y)
ax.text(1.5,1400,'我是分割线')
#
for x,y in zip([2.25]*3,np.percentile(values2,[25,50,75])):
ax.annotate(xy=(x-0.1,y),xytext=(x-0.1,y+100),s=int(y),arrowprops=dict(facecolor='black', shrink=0.05),bbox=dict(facecolor='r',alpha=0.2))
ax.legend()
fig.show()
五、综合示例
plt.rcParams['font.sans-serif']='SimHei' #避免中文字体显示乱码
plt.rcParams['axes.unicode_minus']=False #避免坐标轴中文字体显示出现-
x=np.arange(-2*np.pi,2*np.pi,np.pi/180)
y1=np.sin(x)
y2=np.cos(x)
y3=np.sinh(x)
y4=np.cosh(x)
fig=plt.figure(figsize=(15,10))
plt.subplots_adjust(hspace=1,wspace=1)
ax1=plt.subplot2grid((4,6),(0,0),colspan=2,rowspan=2)
ax2=plt.subplot2grid((4,6),(0,2),colspan=2,rowspan=2)
ax3=plt.subplot2grid((4,6),(2,0),colspan=2,rowspan=2)
ax4=plt.subplot2grid((4,6),(2,2),colspan=2,rowspan=2)
ax5=plt.subplot2grid((4,6),(0,4),rowspan=6,colspan=2)
#ax1 折线图
x=np.arange(1,10,0.1)
y=x**2+x*2+3
ax1.plot(x,y,marker='.',ms=1)
#------------------#
ax1.set_xlabel('X坐标轴',fontsize=8)
ax1.set_ylabel('Y坐标轴',fontsize=8)
ax1.set_title('我的第一个折线图',fontsize=12)
#------------------#
ax1.set_xticks(list(range(1,11)))
ax1.set_xticklabels(['第%s天' %i for i in list(range(1,11))],fontsize=8)
for m,n in zip(x[::2],y[::2]):
ax1.text(m,n+2,'%.d' %n,va='bottom', ha='right',wrap=True,fontsize=8)
#ax2 柱状图
left=np.array([1,2,3])
height=np.array([1,2,3])
ax2.bar(left=left-0.1,height=height,width=0.2)
ax2.bar(left=left+0.1,height=height+1,width=0.2)
ax2.set_title('柱状图',fontsize=10)
ax2.set_xticks([1,2,3])
ax2.set_xticklabels(['A','B','C'])
for x,y in zip(left-0.1,height):
ax2.text(x,y,str(y),ha='center',va='bottom')
for x,y in zip(left+0.1,height+1):
ax2.text(x,y,str(y),ha='center',va='bottom')
ax2.set_yticks(np.arange(0,5,1))
#ax3 直方图
data=np.random.randint(0,1000,100)
ax3.set_title('直方图',fontsize=12)
n,bins,patches=ax3.hist(data,bins=10,range=(0,1000),rwidth =1,color='lightblue')
for x,y in zip(bins,n):
ax3.text(x,y,'%d' %y,ha='left',va='bottom')
ax3.set_yticks(np.arange(0,20,5))
ax3.set_xticks(np.arange(0,1100,100))
ax3.grid(axis='x')
#ax4 饼图
labels=['一','二','三','四'] #标签显示
values=[1,2,3,4]
patches,texts,autotexts=ax4.pie(x=values,labels=labels,autopct='%1.2f%%',explode=[0,0,0,0.1],shadow=True,startangle=180,
textprops=dict(fontsize=8)) #显示格式百分比
ax4.axis('equal') #横纵轴大小相同,饼图比例协调
ax4.set_title('饼图',fontsize=12,color='k')
#ax5 箱形图
values1=np.random.randint(1,500,size=1000)+np.random.randint(200,1000,1000)
values2=np.random.randint(1,500,size=1000)+np.random.randint(200,1000,1000)
ax5.boxplot(x=[values1,values2],notch=True,showfliers=True,showcaps=True,labels=['A','B']) #显示格式百分比
ax5.set_title('箱形图',fontsize=12,color='k')
#辅助类
ax5.axhline(xmin=0,xmax=0.45,y=np.median(values1),ls='--',lw=1,color='r',label='A中位线')
ax5.axhline(xmin=0,xmax=0.45,y=np.percentile(values1,75),ls='--',lw=1,color='y',label='B上四分位线')
ax5.axhline(xmin=0,xmax=0.45,y=np.percentile(values1,25),ls='--',lw=1,color='g',label='C下四分位线')
ax5.axhline(xmin=0.55,xmax=1,y=np.median(values2),ls='--',lw=1,color='r',label='B中位线')
ax5.axhline(xmin=0.55,xmax=1,y=np.percentile(values2,75),ls='--',lw=1,color='y',label='B上四分位线')
ax5.axhline(xmin=0.55,xmax=1,y=np.percentile(values2,25),ls='--',lw=1,color='g',label='B下四分位线')
ax5.axvline(ymin=0,ymax=1500,x=1.5,ls='-.',lw=2,color='pink',label='分割线')
for x,y in zip([1.25]*3,np.percentile(values1,[25,50,75])):
ax5.text(x,y+10,'%d' %y)
for x,y in zip([2.25]*3,np.percentile(values2,[25,50,75])):
ax5.text(x,y+10,'%d' %y)
ax5.text(1.5,1400,'我是分割线')
#
for x,y in zip([2.25]*3,np.percentile(values2,[25,50,75])):
ax5.annotate(xy=(x-0.1,y),xytext=(x-0.1,y+100),s=int(y),arrowprops=dict(facecolor='black', shrink=0.05),bbox=dict(facecolor='r',alpha=0.2))
ax5.legend()
六、实际应用举例
bus=['品类A','品类B','品类C','品类D','品类E']
cols=['指标A','指标B','指标C','指标D','指标E','指标F','指标G','指标H']
data=pd.DataFrame(data=np.random.randint(1,100,(5,8))/100,index=bus,columns=cols)
#想通过柱状图显示各群指标对比
fig,axes=plt.subplots(4,2,figsize=(10,9),sharex=False,sharey=True,dpi=100)
index=list(range(len(bus)))
plt.subplots_adjust()
colors=np.random.randint(1,256,(8,3))
for n,ax in enumerate(axes.flatten()):
temp=data[cols[n]]
ax.bar(left=index,height=temp.values,color=colors[n]/256,width=0.3)
ax.set_xticks(index)
ax.set_xticklabels(bus)
ax.set_title(cols[n])
for x,y in zip(index,temp.values):
ax.text(x,y,'%.0f%%' %(y*100),ha='center',va='bottom',fontsize=10)
ax.hlines(xmin=0,xmax=index[-1],linestyles='--',label='各群均值',y=temp.mean(),color=colors[n]/256)
ax.legend()
plt.tight_layout()