函数式绘图
实际上,matplotlib是受MATLAB的启发构建的。MATLAB是数据绘图领域广泛使用的语言和工具。MATLAB语言是面向过程的(相对于面向对象)。利用函数调用,MATLAB可以轻松地进行数据图形的绘制。 matplotlib有一套完全仿照MATLAB的函数形式的绘图接口,由 matplotlib.pyplot 模块提供。虽然matplotlib的实现还是面向对象,但一般用户只需要使用 matplotlib.pyplot 就可以完成数据图形绘制,不过如果涉及到一些特别细节的调整就不得不去直接调整matplotlib实现的对象了。
为项目设置matplotlib参数
我们有两种方法修改参数:
- 使用参数字典
rcParams
,就像上面我们想要正常显示中文和负号进行的参数设置 - 调用
matplotlib.rc()
命令,通过传入关键字元组来修改参数
比较常见的配置项有:
- axis:设置坐标轴边界和表面的颜色、坐标刻度值大小和网格的显示
- figure: 控制dpi、边界颜色、图形大小、和子区( subplot)设置
- font: 字体集(font family)、字体大小和样式设置
- grid: 设置网格颜色和线性
- legend: 设置图例和其中的文本的显示
- line: 设置线条(颜色、线型、宽度等)和标记
- patch: 是填充2D空间的图形对象,如多边形和圆。控制线宽、颜色和抗锯齿设置等。
- savefig: 可以对保存的图形进行单独设置。例如,设置渲染的文件的背景为白色。
- verbose: 设置matplotlib在执行期间信息输出,如silent、helpful、debug和debug-annoying。
- xticks和yticks: 为x,y轴的主刻度和次刻度设置颜色、大小、方向,以及标签大小。
实际上对于这些,我们不需要背下来,当有相应的需求再去查询文档或者搜索答案即可。
这里只是为了让你知道在matplotlib里有这种能力。而且,默认的这些配置基本上已经能够满足我们的使用,更改它们的情况非常少。
例子
- 正弦和余弦函数
In [1]:
import numpy as np # 从 -nπ 到 nπ 等间隔的256个值 # np.linspace用于生成等差数列,前两个是范围,第三个参数是多好个数,endpoint控制端点是不是一定能取到 X = np.linspace(-np.pi, np.pi, 256, endpoint = True) C = np.cos(X) S = np.sin(X)
- 配置绘图
In [4]:
% matplotlib inline import matplotlib.pyplot as plt plt.plot(X, C) plt.plot(X, S) plt.show()
- 详细解释具体配置项
plt.figure定义了一个图像显示窗口
plt.plot 定义了画线这一行为
plt.show 定义了图像显示这一行为
In [5]:
# 建立一个 8 * 6 点的图,分辨率设为80 plt.figure(figsize = (8, 6), dpi = 80) #创建一个新的 1 * 1 的子图,接下来把图形绘制到第一块子图中 plt.subplot(1, 1, 1) # 绘制余弦曲线,使用蓝色的、连续的、宽度为1个像素的线条 plt.plot(X, C, color='blue', linewidth=1.0, linestyle='-') # 同理画一个正弦曲线 plt.plot(X, S, color='red', linewidth=1.0, linestyle='-') # 设置横轴的范围,设置横轴坐标点 plt.xlim(-4.0, 4.0) plt.xticks(np.linspace(-4, 4, 9, endpoint=True)) # 同理对于y轴 plt.ylim(-1.0, 1.0) plt.yticks(np.linspace(-1, 1, 5, endpoint=True)) plt.show()
- 颜色的粗细和颜色、还有画布宽窄
In [6]:
plt.figure(figsize = (10, 6), dpi = 80) plt.xlim(-4.0, 4.0) plt.xticks(np.linspace(-4, 4, 9, endpoint=True)) plt.ylim(-1.0, 1.0) plt.yticks(np.linspace(-1, 1, 5, endpoint=True)) plt.plot(X, C, color='blue', linewidth=2.5, linestyle='-') plt.plot(X, S, color="red", linewidth=2.5, linestyle="-") plt.show()
- 设置图片边界
In [7]:
plt.figure(figsize = (10, 6), dpi = 80) xmin ,xmax = X.min(), X.max() ymin, ymax = C.min(), C.max() dx = (xmax - xmin) * 0.2 dy = (ymax - ymin) * 0.2 plt.xlim(xmin - dx, xmax + dx) plt.ylim(ymin - dy, ymax + dy) plt.plot(X, C, color='blue', linewidth=2.5, linestyle='-') plt.plot(X, S, color="red", linewidth=2.5, linestyle="-") plt.show()
- 设置人为坐标点
In [8]:
plt.figure(figsize = (10, 6), dpi = 80) xmin ,xmax = X.min(), X.max() ymin, ymax = C.min(), C.max() dx = (xmax - xmin) * 0.2 dy = (ymax - ymin) * 0.2 plt.xlim(xmin - dx, xmax + dx) plt.ylim(ymin - dy, ymax + dy) plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi]) plt.yticks([-1, 0, 1]) plt.plot(X, C, color='blue', linewidth=2.5, linestyle='-') plt.plot(X, S, color="red", linewidth=2.5, linestyle="-") plt.show()
- 用LaTeX设置上图对应坐标点的标签
In [9]:
plt.figure(figsize = (10, 6), dpi = 80) xmin ,xmax = X.min(), X.max() ymin, ymax = C.min(), C.max() dx = (xmax - xmin) * 0.2 dy = (ymax - ymin) * 0.2 plt.xlim(xmin - dx, xmax + dx) plt.ylim(ymin - dy, ymax + dy) 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$']) plt.plot(X, C, color='blue', linewidth=2.5, linestyle='-') plt.plot(X, S, color="red", linewidth=2.5, linestyle="-") plt.show()
- 构建坐标系的脊柱
In [13]:
plt.figure(figsize = (10, 6), dpi = 80) xmin ,xmax = X.min(), X.max() ymin, ymax = C.min(), C.max() dx = (xmax - xmin) * 0.2 dy = (ymax - ymin) * 0.2 plt.xlim(xmin - dx, xmax + dx) plt.ylim(ymin - dy, ymax + dy) 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$']) plt.plot(X, C, color='blue', linewidth=2.5, linestyle='-', label='cosine') plt.plot(X, S, color="red", linewidth=2.5, linestyle="-", label='sine') ax = plt.gca() # 获取当前子图 ax.spines['right'].set_color('none') # 用spines获得右侧的轴 ax.spines['top'].set_color('none') ax.xaxis.set_ticks_position('bottom') # 设置坐标点在轴下侧 ax.yaxis.set_ticks_position('left') # 设置坐标点在轴左侧 ax.spines['bottom'].set_position(('data',0)) # 设置底部轴位置 ax.spines['left'].set_position(('data',0)) # 设置左侧轴位置 plt.legend(loc='upper left') # 顺便添加个图例 plt.show()
- 增加注释
In [14]:
plt.figure(figsize = (10, 6), dpi = 80) xmin ,xmax = X.min(), X.max() ymin, ymax = C.min(), C.max() dx = (xmax - xmin) * 0.2 dy = (ymax - ymin) * 0.2 plt.xlim(xmin - dx, xmax + dx) plt.ylim(ymin - dy, ymax + dy) 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$']) plt.plot(X, C, color='blue', linewidth=2.5, linestyle='-', label='cosine') plt.plot(X, S, color="red", linewidth=2.5, linestyle="-", label='sine') ax = plt.gca() # 获取当前子图 ax.spines['right'].set_color('none') # 用spines获得右侧的轴 ax.spines['top'].set_color('none') ax.xaxis.set_ticks_position('bottom') # 设置坐标点在轴下侧 ax.yaxis.set_ticks_position('left') # 设置坐标点在轴左侧 ax.spines['bottom'].set_position(('data',0)) # 设置底部轴位置 ax.spines['left'].set_position(('data',0)) # 设置左侧轴位置 plt.legend(loc='upper left') # 顺便添加个图例 t = 2*np.pi/3 plt.plot([t,t],[0,np.cos(t)], color ='blue', linewidth=2.5, linestyle="--") plt.scatter([t,],[np.cos(t),], 50, color ='blue') # 余弦的标注点(只有一个点的散点图) plt.annotate(r'$\cos(\frac{2\pi}{3})=-\frac{1}{2}$', xy=(t, np.cos(t)), xycoords='data', xytext=(-90, -50), textcoords='offset points', fontsize=16, arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2")) # 为余弦注释点写注释 plt.plot([t,t],[0,np.sin(t)], color ='red', linewidth=2.5, linestyle="--") # 正弦的垂线 plt.scatter([t,],[np.sin(t),], 50, color ='red') # 正弦的标注点(只有一个点的散点图) plt.annotate(r'$\sin(\frac{2\pi}{3})=\frac{\sqrt{3}}{2}$', xy=(t, np.sin(t)), xycoords='data', xytext=(+10, +30), textcoords='offset points', fontsize=16, arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2")) # 为正弦注释点写注释 plt.show()
- 普通图
In [15]:
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 = 0.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.show() # 保存图像到本地 # plt.savefig('../figures/plot_ex.png', dpi = 48) # 地址为本地的一个目录,可以自己设置图片的格式和像素
- 散点图
In [16]:
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]) # axes的用法和subplot是差不多的,四个参数的话,前 #两个指的是相对于坐标原点的位置,后两个指的是坐标轴的长/宽度 plt.scatter(X, Y, s = 75, c = T, alpha = 0.5) plt.xlim(-1.5, 1.5) plt.xticks([]) plt.ylim(-1.5, 1.5) plt.yticks([]) plt.show()
- 条形图
In [17]:
n = 12 X = np.arange(n) Y1 = (1 - X/float(n)) * np.random.uniform(0.5, 1.0, n) # 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画柱状图,前面正负表示柱状图上下 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.show()
- 等高线图(康托图)
In [27]:
def height(x,y): return (1-x/2+x**5+y**3)*np.exp(-x**2-y**2) n = 300 x = np.linspace(-3, 3, n) y = np.linspace(-3, 3, n) X, Y = np.meshgrid(x, y) # 生成网格点和坐标矩阵 plt.contourf(X, Y, height(X, Y), 8, alpha = 0.75, cmap = plt.cm.hot) C = plt.contour(X, Y, height(X, Y), 8, colors = 'black') plt.clabel(C, inline = True, fontsize = 10) plt.xticks(()) plt.yticks(()) plt.show()
- 灰度图(Imshow)
In [32]:
def im(x,y): return (1-x/2+x**5+y**3)*np.exp(-x**2-y**2) n = 10 x = np.linspace(-3, 3, 4*n) y = np.linspace(-3, 3, 4*n) X, Y = np.meshgrid(x, y) # 生成网格点和坐标矩阵 Z = im(X, Y) plt.imshow(Z,interpolation='nearest', cmap='bone', origin='lower') plt.colorbar(shrink=.92) plt.xticks(()) plt.yticks(()) plt.show()
- 饼图
In [35]:
n = 20 Z = np.ones(n) Z[-1] *= 2 plt.pie(Z, explode=Z*0.05, colors = ['%f' % (i/float(n)) for i in range(n)]) plt.gca().set_aspect('equal') plt.xticks(()) plt.yticks(()) plt.show()
- 量场图
In [36]:
n = 8 X, Y = np.mgrid[0:n, 0:n] T = np.arctan2(Y-n/2.0, X-n/2.0) R = 10+np.sqrt((Y-n/2.0)**2+(X-n/2.0)**2) U,V = R*np.cos(T), R*np.sin(T) plt.quiver(X,Y,U,V,R, alpha=.5) plt.quiver(X,Y,U,V, edgecolor='k', facecolor='None', linewidth=.5) plt.xlim(-1,n), plt.xticks([]) plt.ylim(-1,n), plt.yticks([]) plt.show()
- 网格
In [38]:
ax = plt.axes([0.025,0.025,0.95,0.95]) ax.set_xlim(0,4) ax.set_ylim(0,3) ax.xaxis.set_major_locator(plt.MultipleLocator(1.0)) ax.xaxis.set_minor_locator(plt.MultipleLocator(0.1)) ax.yaxis.set_major_locator(plt.MultipleLocator(1.0)) ax.yaxis.set_minor_locator(plt.MultipleLocator(0.1)) ax.grid(which='major', axis='x', linewidth=0.75, linestyle='-', color='0.75') ax.grid(which='minor', axis='x', linewidth=0.25, linestyle='-', color='0.75') ax.grid(which='major', axis='y', linewidth=0.75, linestyle='-', color='0.75') ax.grid(which='minor', axis='y', linewidth=0.25, linestyle='-', color='0.75') ax.set_xticklabels([]) ax.set_yticklabels([]) # savefig('../figures/grid_ex.png',dpi=48) plt.show()
- 多个网格
In [39]:
fig = plt.figure() fig.subplots_adjust(bottom=0.025, left=0.025, top = 0.975, right=0.975) plt.subplot(2,1,1) plt.xticks([]), plt.yticks([]) plt.subplot(2,3,4) plt.xticks([]), plt.yticks([]) plt.subplot(2,3,5) plt.xticks([]), plt.yticks([]) plt.subplot(2,3,6) plt.xticks([]), plt.yticks([]) # plt.savefig('../figures/multiplot_ex.png',dpi=48) plt.show()
- 极轴图
In [40]:
ax = plt.axes([0.025,0.025,0.95,0.95], polar=True) N = 20 theta = np.arange(0.0, 2*np.pi, 2*np.pi/N) radii = 10*np.random.rand(N) width = np.pi/4*np.random.rand(N) bars = plt.bar(theta, radii, width=width, bottom=0.0) for r,bar in zip(radii, bars): # zip函数 zip函数接受任意多个(包括0个和1个)序列作为参数,返回一个tuple列表 bar.set_facecolor( plt.cm.jet(r/10.)) bar.set_alpha(0.5) ax.set_xticklabels([]) ax.set_yticklabels([]) # savefig('../figures/polar_ex.png',dpi=48) plt.show()
- 3D图
In [41]:
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.cm.hot) ax.contourf(X, Y, Z, zdir='z', offset=-2, cmap=plt.cm.hot) ax.set_zlim(-2,2) # savefig('../figures/plot3d_ex.png',dpi=48) plt.show()
- 云图
In [42]:
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([]) # savefig('../figures/text_ex.png',dpi=48) plt.show()