【matplotlib】十分钟教程

原英文文档

简介

       matplotlib是一个在python中广泛使用的2-D绘图包。其为python数据的可视化提供了一种非常便捷的方法。

pyplot

       pylot为matplotlib面向对象绘图库提供了一个便利的接口,它的语法和命令和matlab十分类似。

简单绘图

       这一节,我们将会在同一个图像上绘制余弦和正弦曲线,所有的设置比如:figure size,dpi,线宽,颜色,线型,axes,axis以及文字样式等都采用默认参数,在后续的章节我们会让其变得越来越漂亮。

import matplotlib.pyplot as plt
import numpy as np

# X是一个numpy.ndarray,从-π 到+π 包含256
X = np.linspace(-np.pi, np.pi, 256,endpoint=True)

#C,S分别是X中256个值得余弦和正弦值
C,S = np.cos(X), np.sin(X)

plt.plot(X,C)
plt.plot(X,S)

plt.show()

修改参数值

       尝试着去修改可能影响图像外观的参数,来体会下其对最终展现的影响。

# 创建一个8x6大小的图像, 分辨率每英尺80的点
plt.figure(figsize=(8,6), dpi=80)

# 创建一个1*1的子图
plt.subplot(111)

X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
C,S = np.cos(X), np.sin(X)

# 绘制一个蓝色的,线宽为1个像素的连续余弦曲线
plt.plot(X, C, color="blue", linewidth=1.0, linestyle="-")

# 绘制一个绿色的,线宽为1个像素的连续正弦曲线
plt.plot(X, S, color="green", linewidth=1.0, linestyle="-")

# 设置x轴范围
plt.xlim(-4.0,4.0)

# 设置x轴刻度
plt.xticks(np.linspace(-4,4,9,endpoint=True))

# 设置y轴范围
plt.ylim(-1.0,1.0)

# 设置y轴刻度
plt.yticks(np.linspace(-1,1,5,endpoint=True))

# 保存图像,分辨率为72
# plt.savefig("exercice.png",dpi=72)

# 在屏幕上显示结果
plt.show()

改变颜色和线宽

plt.figure(figsize=(10,6), dpi=80)
plt.plot(X, C, color="blue", linewidth=2.5, linestyle="-")
plt.plot(X, S, color="red",  linewidth=2.5, linestyle="-")

设置坐标轴范围

当前图像的坐标轴和图像之间太过紧凑,可以在坐标轴和图像之间增加一些空间。

plt.xlim(X.min()*1.1, X.max()*1.1)
plt.ylim(C.min()*1.1, C.max()*1.1)

设置刻度

对于绘制正弦余弦图像而言,上述图像的坐标表示并不理想,没有标出特殊点的位置比如-π,π ,-π/2 ,π/2等

plt.xticks( [-np.pi, -np.pi/2, 0, np.pi/2, np.pi])
plt.yticks([-1, 0, +1])

设置刻度标签

在设置刻度是,我们还可以指定对应的标签,如果有数学公式还可以使用latex语法。

plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],[r'$-\pi$', r'$-\pi/2$', r'$0$', r'$+\pi/2$', r'$+\pi$'])

plt.yticks([-1, 0, +1],[r'$-1$', r'$0$', r'$+1$'])

移动脊线

脊线其实就是图中边框的四个边(top/bottom/left/right),它可以连接数据刻度,确定数据范围,同样也是可以随意移动的。

ax = plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data',0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data',0))

添加图例

在左上角添加图例,在添加图例前需要在plt.plot中增加label参数

plt.plot(X, C, color="blue", linewidth=2.5, linestyle="-", label=r'$cos(x)$')
plt.plot(X, S, color="red",  linewidth=2.5, linestyle="-", label=r'$sin(x)$')

plt.legend(loc='upper left', frameon=False)
md_8.png

添加注释

给你感兴趣的点添加注释,这里给x=2π/3位置的sin和cos曲线添加注释。

t = 2*np.pi/3

plt.plot([t,t],[0,np.cos(t)],linestyle="--",color='blue',linewidth=1.5)
plt.scatter([t,],[np.cos(t),],50,color='blue')
plt.annotate(r'$\cos(\frac{2\pi}{3}) = -\frac{\sqrt{3}}{2}$',xy=(t,np.cos(t)),xycoords='data',xytext=(-90, -50))

plt.plot([t,t],[0,np.sin(t)],linestyle="--",color="red",linewidth=1.5)
plt.scatter([t,],[np.sin(t),],50,color='red')

Figures,Subplot,Axes 和Ticks

到目前为止,我们都在使用默认的Figure和Axes,这对于快速绘图来确实很方便。我们也可以使用figure,subplot,axes显示的控制图像的显示。在matplotlib中一个figure意味着用户界面的整个窗体。在figure中可以是subplot,也可以是axes,subplot只能以规则格网的形式展现,axes用户可以任意的指定放置的位置,你可以根据你的使用目的来选择。当我们绘制图形的时候matplotlib会调用gca()获取当前的Axe,gca会调用gcf获取当前的figure。

Figures

Figures就是GUI中的一个窗体,它有很多参数可以控制Figure的样式

参数 默认值 描述
num 1 figure的索引
figsize figure.figsize 图像大小(宽,高),单位英尺
dpi figure.dpi 每英尺图像的分辨率
facecolor figure.facecolor 背景颜色
edgecolor figure.edgecolor 围绕绘图区域边缘的颜色
frameon True 是否绘制图像框架

subplots

通过子图,你可以合理的布局自己的图像,只需要指定行列书以及当前绘制的图像索引。 gridspec 是一个更为强大的设定字图的工具

plt.subplot(2,1,1)
plt.xticks([]), plt.yticks([])
plt.text(0.5,0.5, 'subplot(2,1,1)',ha='center',va='center',size=24,alpha=.5)

plt.subplot(2,1,2)
plt.xticks([]), yticks([])
plt.text(0.5,0.5, 'subplot(2,1,2)',ha='center',va='center',size=24,alpha=.5)

# plt.savefig('.subplot-horizontal.png', dpi=64)
plt.show()
plt.subplot(1,2,1)
plt.xticks([]), plt.yticks([])
plt.text(0.5,0.5, 'subplot(1,2,1)',ha='center',va='center',size=24,alpha=.5)

plt.subplot(1,2,2)
plt.xticks([]), plt.yticks([])
plt.text(0.5,0.5, 'subplot(1,2,2)',ha='center',va='center',size=24,alpha=.5)

# plt.savefig('subplot-vertical.png', dpi=64)
plt.show()
plt.subplot(2,2,1)
plt.xticks([]), plt.yticks([])
plt.text(0.5,0.5, 'subplot(2,2,1)',ha='center',va='center',size=20,alpha=.5)

plt.subplot(2,2,2)
plt.xticks([]), plt.yticks([])
plt.text(0.5,0.5, 'subplot(2,2,2)',ha='center',va='center',size=20,alpha=.5)

plt.subplot(2,2,3)
plt.xticks([]), plt.yticks([])
plt.text(0.5,0.5, 'subplot(2,2,3)',ha='center',va='center',size=20,alpha=.5)

plt.subplot(2,2,4)
plt.xticks([]), plt.yticks([])
plt.text(0.5,0.5, 'subplot(2,2,4)',ha='center',va='center',size=20,alpha=.5)

# plt.savefig('subplot-grid.png', dpi=64)
plt.show()
 import matplotlib.gridspec as gridspec

G = gridspec.GridSpec(3, 3)

axes_1 = plt.subplot(G[0, :])
plt.xticks([]), plt.yticks([])
plt.text(0.5,0.5, 'Axes 1',ha='center',va='center',size=24,alpha=.5)

axes_2 = plt.subplot(G[1,:-1])
plt.xticks([]),plt.yticks([])
plt.text(0.5,0.5, 'Axes 2',ha='center',va='center',size=24,alpha=.5)

axes_3 = plt.subplot(G[1:, -1])
plt.xticks([]), plt.yticks([])
plt.text(0.5,0.5, 'Axes 3',ha='center',va='center',size=24,alpha=.5)

axes_4 = plt.subplot(G[-1,0])
plt.xticks([]), plt.yticks([])
plt.text(0.5,0.5, 'Axes 4',ha='center',va='center',size=24,alpha=.5)

axes_5 = plt.subplot(G[-1,-2])
plt.xticks([]), plt.yticks([])
plt.text(0.5,0.5, 'Axes 5',ha='center',va='center',size=24,alpha=.5)

#plt.savefig('gridspec.png', dpi=64)
plt.show()

Axes

Axes和subplot非常类似,不同的是,用户可以任意设定Axes在Figures中的位置。

plt.axes([0.1,0.1,.8,.8])
plt.xticks([]), plt.yticks([])
plt.text(0.6,0.6, 'axes([0.1,0.1,.8,.8])',ha='center',va='center',size=20,alpha=.5)

plt.axes([0.2,0.2,.3,.3])
plt.xticks([]), plt.yticks([])
plt.text(0.5,0.5, 'axes([0.2,0.2,.3,.3])',ha='center',va='center',size=16,alpha=.5)

plt.show()
plt.axes([0.1,0.1,.5,.5])
plt.xticks([]), plt.yticks([])
plt.text(0.1,0.1, 'axes([0.1,0.1,.8,.8])',ha='left',va='center',size=16,alpha=.5)

plt.axes([0.2,0.2,.5,.5])
plt.xticks([]), plt.yticks([])
plt.text(0.1,0.1, 'axes([0.2,0.2,.5,.5])',ha='left',va='center',size=16,alpha=.5)

plt.axes([0.3,0.3,.5,.5])
plt.xticks([]), plt.yticks([])
plt.text(0.1,0.1, 'axes([0.3,0.3,.5,.5])',ha='left',va='center',size=16,alpha=.5)

plt.axes([0.4,0.4,.5,.5])
plt.xticks([]), plt.yticks([])
plt.text(0.1,0.1, 'axes([0.4,0.4,.5,.5])',ha='left',va='center',size=16,alpha=.5)

# plt.savefig("axes-2.png",dpi=64)
plt.show()

Ticks

合理的刻度是图像展示的重要组成部分

其它类型的图像

常规绘图

n = 256
X = np.linspace(-np.pi,np.pi,n,endpoint=True)
Y = np.sin(2*X)

plt.axes([0.025,0.025,0.95,0.95])

plt.plot (X, Y+1, color='blue', alpha=1.00)
plt.fill_between(X, 1, Y+1, color='blue', alpha=.25)

plt.plot (X, Y-1, color='blue', alpha=1.00)
plt.fill_between(X, -1, Y-1, (Y-1) > -1, color='blue', alpha=.25)
plt.fill_between(X, -1, Y-1, (Y-1) < -1, color='red',  alpha=.25)

plt.xlim(-np.pi,np.pi), plt.xticks([])
plt.ylim(-2.5,2.5), plt.yticks([])
# plt.savefig('plot_ex.png',dpi=48)
plt.show()

散点图

n = 1024
X = np.random.normal(0,1,n)
Y = np.random.normal(0,1,n)
T = np.arctan2(Y,X)

plt.axes([0.025,0.025,0.95,0.95])
plt.scatter(X,Y, s=75, c=T, alpha=.5)

plt.xlim(-1.5,1.5), plt.xticks([])
plt.ylim(-1.5,1.5), plt.yticks([])
# plt.savefig('scatter_ex.png',dpi=48)
plt.show()

柱状图

n = 12
X = np.arange(n)
Y1 = (1-X/float(n)) * np.random.uniform(0.5,1.0,n)
Y2 = (1-X/float(n)) * np.random.uniform(0.5,1.0,n)

plt.axes([0.025,0.025,0.95,0.95])
plt.bar(X, +Y1, facecolor='#9999ff', edgecolor='white')
plt.bar(X, -Y2, facecolor='#ff9999', edgecolor='white')

for x,y in zip(X,Y1):
    plt.text(x+0.4, y+0.05, '%.2f' % y, ha='center', va= 'bottom')

for x,y in zip(X,Y2):
    plt.text(x+0.4, -y-0.05, '%.2f' % y, ha='center', va= 'top')

plt.xlim(-.5,n), plt.xticks([])
plt.ylim(-1.25,+1.25), plt.yticks([])

# plt.savefig('bar_ex.png', dpi=48)
plt.show()

等值线图

def f(x,y):
    return (1-x/2+x**5+y**3)*np.exp(-x**2-y**2)

n = 256
x = np.linspace(-3,3,n)
y = np.linspace(-3,3,n)
X,Y = np.meshgrid(x,y)

plt.axes([0.025,0.025,0.95,0.95])

plt.contourf(X, Y, f(X,Y), 8, alpha=.75, cmap=plt.cm.hot)
C = plt.contour(X, Y, f(X,Y), 8, colors='black', linewidth=.5)
plt.clabel(C, inline=1, fontsize=10)

plt.xticks([]), plt.yticks([])
plt.show()

显示图像

def f(x,y):
    return (1-x/2+x**5+y**3)*np.exp(-x**2-y**2)

n = 10
x = np.linspace(-3,3,3.5*n)
y = np.linspace(-3,3,3.0*n)
X,Y = np.meshgrid(x,y)
Z = f(X,Y)

plt.axes([0.025,0.025,0.95,0.95])
plt.imshow(Z,interpolation='nearest', cmap='bone', origin='lower')
plt.colorbar(shrink=.92)

plt.xticks([]), plt.yticks([])
plt.show()

饼状图

n = 20
Z = np.ones(n)
Z[-1] *= 2

plt.axes([0.025,0.025,0.95,0.95])

plt.pie(Z, explode=Z*.05, colors = ['%f' % (i/float(n)) for i in range(n)])
plt.gca().set_aspect('equal')
plt.xticks([]), plt.yticks([])

plt.show()

绘制格网

axe = plt.gca()
axe.set_xlim(0,4)
axe.set_ylim(0,3)

axe.xaxis.set_major_locator(plt.MultipleLocator(1.0))
axe.xaxis.set_minor_locator(plt.MultipleLocator(0.1))
axe.yaxis.set_major_locator(plt.MultipleLocator(1.0))
axe.yaxis.set_minor_locator(plt.MultipleLocator(0.1))
axe.grid(which='major',axis='x',linewidth=0.75, linestyle='-', color='0.75')
axe.grid(which='minor', axis='x', linewidth=0.25, linestyle='-', color='0.75')
axe.grid(which='major',axis='y',linewidth=0.75, linestyle='-', color='0.75')
axe.grid(which='minor', axis='y', linewidth=0.25, linestyle='-', color='0.75')
axes.set_xticklabels([])
axes.set_yticklabels([])

plt.show()

3D图像

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='hot')
ax.contourf(X, Y, Z, zdir='z', offset=-2, cmap=plt.cm.hot)
ax.set_zlim(-2,2)

plt.show()

绘制文本

eqs = []

eqs.append((r"$W^{3\beta}_{\delta_1 \rho_1 \sigma_2} = U^{3\beta}_{\delta_1 \rho_1} + \frac{1}{8 \pi 2} \int^{\alpha_2}_{\alpha_2} d \alpha^\prime_2 \left[\frac{ U^{2\beta}_{\delta_1 \rho_1} - \alpha^\prime_2U^{1\beta}_{\rho_1 \sigma_2} }{U^{0\beta}_{\rho_1 \sigma_2}}\right]$"))
eqs.append((r"$\frac{d\rho}{d t} + \rho \vec{v}\cdot\nabla\vec{v} = -\nabla p + \mu\nabla^2 \vec{v} + \rho \vec{g}$"))
eqs.append((r"$\int_{-\infty}^\infty e^{-x^2}dx=\sqrt{\pi}$"))
eqs.append((r"$E = mc^2 = \sqrt{{m_0}^2c^4 + p^2c^2}$"))
eqs.append((r"$F_G = G\frac{m_1m_2}{r^2}$"))

plt.axes([0.025,0.025,0.95,0.95])

for i in range(24):
    index = np.random.randint(0,len(eqs))
    eq = eqs[index]
    size = np.random.uniform(12,32)
    x,y = np.random.uniform(0,1,2)
    alpha = np.random.uniform(0.25,.75)
    plt.text(x, y, eq, ha='center', va='center', color="#11557c", alpha=alpha,
             transform=plt.gca().transAxes, fontsize=size, clip_on=True)

plt.xticks([]), plt.yticks([])
plt.show()

推荐阅读更多精彩内容