数据可视化之Matplotlib

酥酥 发布于 2022-06-03 312 次阅读


本篇只是对Matplotlib中的一些常用关键点进行了整理,具体使用方法和细节还请参考Matplotlib的官方api

在 Jupyter中使用Matplotlib
				
					import matplotlib.pyplot as plt #导入画图的库matplotlib有很多苦pyplot是展示图的
%matplotlib inline #在notebook中直接显示
				
			

基本的线

				
					plt.plot(X,Y)
				
			

设置x标签,y标签

				
					plt.xlabel("x轴".fontsize=16) fontsize设置字体大小
plt.ylabel("y轴")
				
			
对图形的标记(marker)-线条(line)-颜色(color)的调整可以参考

https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.plot.html#matplotlib.pyplot.plot

支持许多图像画在一个图上,直接把x,y数据对应导入即可

美化、注释、部分

也可以先定义线在定义样式使用plt.step(图,fmt)#fmt是样式参数与plt.plot中一致

如果plt中制定了label那么可以使用plt.legend或者fig(有画布对象时).legend(loc=”指定位置”,bbox_to_anchor,ncol,framealpha)来展示图例可以在图外(x,y>1)图内都可以

也可以自行指定图例位置,可供选择的参数有:

  • upper right 右上

  • upper left 左上

  • lower left 左下

  • lower right 右下

  • right 右边

  • center left 左中

  • center right 右中

  • lower center 中下

  • upper center 中上

  • center 中

注意

matplotlib绘图过程中,可为各个轴的标题 (Lable),图像的标题 title, 图形的图例 legend等元素添加LaTeX风格的公式。

设置图形标题及坐标轴
  • plt.title() 设置图形标题

  • plt.xticks() 设置 x 轴的刻度值 两个等大的数组

  • plt.yticks() 设置 y 轴的刻度值

  • plt.xlim() 设置 x 轴的区间范围

  • plt.ylim() 设置 y 轴的区间范围

  • plt.xlabel() 设置 x 轴的名称

  • plt.ylabel() 设置 y 轴的名称

中文显示copy以下代码
				
					plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
plt.rcParams["axes.titlesize"]=20#标题字体大小设置
				
			
添加网格线
				
					plt.grid(b=None, which=u'major', axis=u'both', **kwargs)
				
			
  • b: 布尔型变量,b=False 不显示网格, b=True 显示网格

  • which:

    • which=’major’: 使用大网格,默认

    • which=’minor’: 使用小网格

    • which = ‘both’: 大网格里套小网格

  • axis:

    • axis=’x’

    • axis=’y’

    • axis=’both’

plt.text() 函数 给图形添加文本注释
  • ha, horizontal alignment 水平对齐的简写,可选参数:

    • center

    • right

    • left

  • va, vertical alignment 垂直对齐的简写,可选参数:

    • center

    • top

    • bottom

    • baseline

    • center_baseline

plt.annotate(string,xy=(X,Y),xytext=(X1,Y1),arrowprops=dict(facecolor=”black”,shrink=0.5,headwidth=10,headlength=10))#X,Y是箭头指向的位置,xytext是文字方式的位置
				
					for x,y in zip(x_coords,y_coords):
	    plt.annotate(’(%s, %s)'%(x, y) , xy=(x, y) , xytext=(0,-15),textcoords = 'offset points', ha='center')
	    plt.show()
				
			
子图的构建:
				
					法一 plt.subplot(211)  #画的图2行1列 现在指定第一幅图
    plt.subplot(212)  #画的图2行1列 现在指定第二幅图
法二 fig,gs=plt.subplots(1,2)  #gs是一个ndarray类型,fig是控制当前图的画布对象
	gs[0].plot([2,3],[4,5])
	gs[1].plot([2,3],[4,5])
	以上方法等同于
	fig,(gs[0],gs[1])=plt.subplots(1,2) #subplots中的维度与前面接收变量的维度要一致
法三 ax1=fig.add_subplot(221)
	ax2=fig.add_subplot(222)    
	ax3=fig.add_subplot(212) #参数与法一一样
法四 ax1=plt.subplot2grid((3,3),(0,0),colspan=3,rowspan=1)#第一个参数表示X*Y个子图单元 第二个参数相当于定位比如0,0对应第1行第1列的子图 colspan表示垮了几行,rowspan表示跨了几列 其实就是第一行的三个子图给了ax1
	ax1.plot([1,2],[1,2])
	ax1.set_title("ax1")	
	ax2=plt.subplot2grid((3,3),(1,0),colspan=2)
	ax3=plt.subplot2grid((3,3),(1,2),rowspan=2)
	ax4=plt.subplot2grid((3,3),(2,0),colspan=1)
	ax5=plt.subplot2grid((3,3),(2,1),colspan=1)
法五 import matplotlib.gridspec as gridspec
	plt.figure()
	gs=gridspec.GridSpec(3,3)#划分大小
	ax6=plt.subplot(gs[0,:])#第1行所有
	ax7=plt.subplot(gs[1,0:2])#第2行跨了两列构成图
	ax8=plt.subplot(gs[1,2:3])#第2行第三列构成图
	ax9=plt.subplot(gs[2,0:1])#第3行第一列构成图
	ax10=plt.subplot(gs[2,1:3])#第4行后两列构成图
				
			

Chapter 风格

				
					plt.style.available()#所有可以调用的风格
plt.style.use(”dark_background“)#使用某一风格
plt.style.use(["ggplot","bmh"])
plt.xkcd()#特色
				
			

条形统计图

				
					#柱状图的绘制
import matplotlib.pyplot as plt
import numpy as np
n=12
X=np.arange(n)
Y1=(1-X/float(n))*np.random.uniform(0.5,1,n)
Y2=(1-X/float(n))*np.random.uniform(0.5,1,n)
plt.bar(X,+Y1,width=1.0,facecolor="#9924ff",edgecolor="#ffffff")
plt.bar(X,-Y1,width=0.7,facecolor="#009828",edgecolor="#113422")
for x,y in zip(X,Y1):
    plt.text(x,y+0.15,'%.2f'%y,ha="center",va="bottom")#horizontal alignment
for x,y in zip(X,Y2):
    plt.text(x,-y-0.15,'-%.2f'%y,ha="center",va="top")#horizontal alignment
plt.xlim(-5,n)
plt.xticks(())
plt.ylim(-1.25,1.25)
plt.yticks(())
plt.show()
#横着画 plt.barh
#参考线 plt.axhline(,color=,linewidth)#横着的
#参考线 plt.axvline(,color=,linewidth)#竖着的
#设置样式用plt.set
import matplotlib.pyplot as plt
import numpy as np
n=12
X=np.arange(n)
Y1=(1-X/float(n))*np.random.uniform(0.5,1,n)
fig,ax=plt.subplots()
ax=plt.bar(X,+Y1,width=1.0,facecolor="#9924ff",edgecolor="#ffffff")
for axx,Y in zip(ax,Y1):
    if(Y<0.25):
        axx.set(color="yellow")
				
			

填充

fill_between(x,y1,[y2],color)在y1,y2中间部分填充

误差棒

plt.bar(yerr)

colormap

				
					import matplotlib.colors as col
import matplotlib.cm as cm
cmap1(cm.ScalarMappable(col.Normalize(左边界,右边界),cm.hot)
bar(color=cmap1.to_rgba())

bar[].set_hatch
#设置内部样式set_hatch 

#cmap参考 
plt.imshow(imgs[i].reshape(28, 28), cmap='binary')
#或如下:也可以达到相同的效果
plt.imshow(imgs[i].reshape(28, 28), cmap=plt.get_cmap('binary'))

color_list = plt.cm.tab20(n)  # 其中n代表你要使用tab20的前n个颜色
				
			

盒图

Q1,Q3为第一、三四分位数 IQR=Q3-Q1
五点作盒图 Q1-1.5IQR Q1 median(中位数) Q3 Q3+1.5IQR

plt.boxplot(x,notch,sym=””,vert,patch_artist) x可以是一维/二维数组 notch是样式选择bool,sym是离群点的表示方法,vert表示横着还是竖着,patch_artist是否允许填充

				
					# 样式设置
for components in bplot.keys():#bplot是boxplot对象
	for lines in bplot[components]:
		line.set_color("black")#设置边界颜色
colors=['pink','lightblue','lightgreen']
for pathch,color in zip(bplot["boxes"],colors): #导入bplox参数
	pathch.set_facecolor(color)#设置填充颜色
				
			

轴的设置

				
					fig=plt.pca()#取轴对象
fig.axes.get_xaxis(),set_visible(False)#选x轴设置不可见
fig.axes.get_yaxis(),set_visible(False)#选y轴设置不可见


#移动坐标轴
ax=plt.gca()#ax也可以是图对象ax=plt.subplot(111)
ax.spines["top"].set_color("None")
ax.spines["right"].set_color("None")#右轴无颜色
ax.tick_params(bottom="off",top,left,right)#表示指定方向有没有刻度标记
ax.xaxis.set_ticks_position("bottom")
labels=ax1.set_xticklabels(['one','two','three','four','five'],rotation = 30,fontsize = 'small',horizentalalignment=“对齐方式”) # 设置刻度标签
ax.spines["bottom"].set_position(("axes",1))#axes,outward,data 放在bottom的1处axes百分比
plt.show()
				
			

直方图与散点图

				
					import numpy as np 
import matplotlib.pyplot as plt 

mu = 100
sigma = 15
x = mu + sigma * np.random.randn(200)
num_bins = 25#划分为几个区间,也可以是等差数列
plt.figure(figsize=(9, 6), dpi=100)

n,bins,patches = plt.hist(x, num_bins, 
                          color="w", edgecolor="k",
                          hatch=r'ooo',
                          density = 1,
                          label = '频率',
                          histtype  = 'barstacked'
                          )

y = ((1 / (np.sqrt(2 * np.pi) * sigma)) *
     np.exp(-0.5 * (1 / sigma * (bins - mu))**2))
 
plt.plot(bins, y, '--',label='概率密度函数')
plt.rcParams['font.sans-serif']=['SimHei']
plt.xlabel('聪明度')
plt.ylabel('概率密度')
plt.title('IQ直方图:$\mu=100$,$\sigma=15$')

plt.legend()
plt.show()      
				
			

附带有特别说明的条形图

				
					import matplotlib.pyplot as plt 
import numpy as np 
np.random.seed(0)
x = np.random.normal(0, 1, 5000) # 生成符合正态分布的5000个随机样本
plt.figure(figsize=(14,7)) #设置图片大小 14x7 inch
plt.style.use('seaborn-whitegrid') # 设置绘图风格
n, bins, patches = plt.hist(x, bins=90, facecolor = '#2ab0ff', 
                            edgecolor='#169acf', linewidth=0.5)
n = n.astype('int') # 返回值n必须是整型
# 设置显式中文的字体
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False   # 显式负号'-'
#为每个条形图设置颜色
for i in range(len(patches)):
    patches[i].set_facecolor(plt.cm.viridis(n[i]/max(n)))
#对某个特定条形(如第70个)做特别说明   
patches[49].set_fc('red') # 设置颜色
patches[49].set_alpha(1) # 设置透明度
#添加注释
plt.annotate('这是一个重要条形!', xy=(0.5, 160), xytext=(1.5, 130), fontsize=15, 
             arrowprops={'width':0.4,'headwidth':5,'color':'#333333'})
# 设置X和Y轴标题和字体大小
plt.title('正态分布', fontsize=12)
plt.xlabel('不同的间隔(bins)', fontsize=10)
plt.ylabel('频度大小', fontsize=10)
plt.show()
				
			
散点图
				
					import matplotlib.pyplot as plt
import numpy as np

nbPoints = 50
x = np.random.standard_normal(nbPoints)
y = np.random.standard_normal(nbPoints)

np.random.seed(20210615)
colors = np.random.rand(nbPoints)

area = (30*np.random.rand(nbPoints))**2
plt.scatter(x, y, s=area, c=colors, alpha=0.5)
plt.show()
				
			

3D图

				
					#3D图像
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
fig=plt.figure()
ax=Axes3D(fig)
X=np.arange(-4,4,0.25)
Y=np.arange(-4,4,0.25)
X,Y=np.meshgrid(X,Y)
R=np.sqrt(X**2+Y**2)
Z=np.sin(R)
ax.plot_surface(X,Y,Z,rstride=1,cstride=1,cmap=plt.get_cmap("rainbow"))#stride是跨度,密集度
ax.contourf(X,Y,Z,zdir='z',offset=-2,cmap="rainbow")
plt.show()

#ax=plt.subplot(111,projection="3d")也可
ax.view_init()
				
			

饼图

				
					import matplotlib.pyplot as plt
# 为在Matplotlib中显示中文,设置特殊字体
plt.rcParams['font.sans-serif']=['SimHei']
#为图片设置大小和分辨率
plt.figure(figsize = (9, 6), dpi = 100)
x = [217,743,426]
labels = ['走路去','自行车','公交车']
explode = [0,0.05,0]

_, _, autotexts = plt.pie(x = x,labels = labels,shadow = 1,
                          autopct = '%.1f%%',explode = explode)#第一个是图对象,第二个参数是外部字,第三个参数是内部字
#将饼状图中的字体改成白色
for autotext in autotexts:
    autotext.set_color('white')

plt.title('3种去学校的方式')
plt.show()
				
			

图中图

				
					fig = plt.figure()

left1, bottom1, width1, height1 =  0.1, 0.1, 0.8, 0.8

axes_1 = fig.add_axes([left1, bottom1, width1, height1])
axes_1.scatter(x,y)
axes_1.set_xlabel('x')
axes_1.set_ylabel('y')
axes_1.set_title('title') 


left2, bottom2, width2, height2 = 0.6, 0.6, 0.25, 0.25
axes2 = fig.add_axes([left2, bottom2, width2, height2])
axes2.plot(x,y)
axes2.set_title('title inside')

plt.show()


法二:用内布库工具
import matplot1ib. pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
top10_arrivals_countries = ['CANADA’,'MEXICO', ' UNITED \nKINGDOM’, 
’JAPAN’,'CHINA’,’GERMANY’,'SOUTH\nKOREA’,l’FRANCE’,’BRAZIL’,’AUSTRALIA’]
top10_arrivals_values = [16.625687,15.378026,3.934508,2.999718,1
2.618737,1.769498,1.628563,1.419409,11.393710,1.136974]
arrivals_countries = [’WESTERN\nEUROPE’,'ASIA', ' SOUTH\nAMERICA,’OCEANIA’, 'CARIBBEAN’, 'MIDDLE\nEAST’,l’CENTRAL\nAMERICA’, 'EASTERN\nEUROPE’,’AFRICA’]
arrivals_percent = [36.9,30.4,13.8,4.4,4.0,3.6,2.9,2.6,1.5]
fig,ax1 = plt.subplots(figsize=(20,12))
ax1.bar(range(10),top10_arrivals_values,color=' blue')
ax2 = inset_axes(ax1, width = 6, height = 6,1oc = 5)
explode = (0.08,0.08,0.05,0.05,0.05,0.05,0.05,0.05,0.05)
ax2.pie(arrivals_percent, 1abe1s=top10_arrivals_countries, autopct='%1.1f%', explode=exp1ode)