组合图形样式
上面演示了单个简单图像的绘制
实际上,我们往往会遇到将几种类型的一样的图放在一张图内显示,也就是组合图的绘制。
其实很简单,你只需要将所需图形的代码放置在一起就可以了,比如绘制一张包含柱形图和折线图的组合图。
x = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19] y_bar = [3, 4, 6, 8, 9, 10, 9, 11, 7, 8] y_line = [2, 3, 5, 7, 8, 9, 8, 10, 6, 7] plt.bar(x, y_bar) plt.plot(x, y_line, '-o', color='y')
图形位置
figure对象
在图形的绘制过程中,你可能需要调整图形的位置,或者把几张单独的图形拼接在一起
此时,我们就需要引入 plt.figure 图形对象了
# 生成数据 x = np.linspace(0, 10, 20) y = x * x + 2 # 新建图形对象 fig = plt.figure() # 控制画布的左, 下, 宽度, 高度 axes = fig.add_axes([0.5, 0.5, 0.8, 0.8]) axes.plot(x, y, 'r')
上面的绘图代码中,你可能会对 figure 和 axes 产生疑问
Matplotlib 的 API 设计的非常符合常理,在这里,figure 相当于绘画用的画板,而 axes 则相当于铺在画板上的画布
我们将图像绘制在画布上,于是就有了 plot,set_xlabel 等操作。
借助于图形对象,我们可以实现大图套小图的效果
# 新建画板 fig = plt.figure() # 大画布 axes1 = fig.add_axes([0.1,0.1,0.8,0.8]) # 小画布 axes2 = fig.add_axes([0.2,0.5,0.4,0.3]) # 大画布 axes1.plot(x,y,'r') # 小画布 axes2.plot(x,y,'g')
上面的绘图代码中,使用了 add_axes() 方法向我们设置的画板 figure 中添加画布 axes
subplots对象
在 Matplotlib 中,还有一种添加画布的方式,那就是 plt.subplots(),它和 axes 都等同于画布
flg,axes = plt.subplots() axes.plot(x,y,'r')
借助于 plt.subplots(),我们就可以实现子图的绘制,也就是将多张图按一定顺序拼接在一起
# 子图为 1 行,2 列 flg,axes = plt.subplots(nrows=1,ncols=2) for ax in axes: ax.plot(x,y,'r')
或者:
x = [1,2,3] y = [1,2,3] flg,axes = plt.subplots(nrows=1,ncols=2) axes[0].plot(x,y,'r') axes[1].plot(x[::-1],y,'r')
通过设置 plt.subplots 的参数,可以实现调节画布尺寸和显示精度
fig, axes = plt.subplots( # 通过 figsize 调节尺寸, dpi 调节显示精度 figsize=(16, 9), dpi=50 ) axes.plot(x, y, 'r')
规范绘图方法
首先,任何图形的绘制,都建议通过 plt.figure() 或者 plt.subplots() 管理一个完整的图形对象
而不是简单使用一条语句,例如 plt.plot(...) 来绘图
管理一个完整的图形对象,有很多好处, 在图形的基础上,给后期添加图例,图形样式,标注等预留了很大的空间, 除此之外代码看起来也更加规范,可读性更强.
接下来,我们就通过几组例子来演示规范的绘图方法.
添加图标题/图例
绘制包含图标题、坐标轴标题以及图例的图形,举例如下:
fig, axes = plt.subplots() # 横轴名称 axes.set_xlabel('x label') axes.set_ylabel('y label') # 图形名称 axes.set_title('title') axes.plot(x, x**2) axes.plot(x, x**3) # 图例 axes.legend(["y = x**2", "y = x**3"], loc=0)
图例中的 loc 参数标记图例位置,1,2,3,4 依次代表:右上角、左上角、左下角,右下角;0 代表自适应
线型、颜色、透明度
在 Matplotlib 中,你可以设置线的颜色、透明度等其他属性
fig,axes = plt.subplots() axes.plot(x, x+1, color="red", alpha=0.5) axes.plot(x, x+2, color="#1155dd") axes.plot(x, x+3, color="#15cc55")
而对于线型而言,除了实线、虚线之外,还有很多丰富的线型可供选择
fig, ax = plt.subplots(figsize=(12, 6)) # 线宽 ax.plot(x, x+1, color="blue", linewidth=0.25) ax.plot(x, x+2, color="blue", linewidth=0.50) ax.plot(x, x+3, color="blue", linewidth=1.00) ax.plot(x, x+4, color="blue", linewidth=2.00) # 虚线类型 ax.plot(x, x+5, color="red", lw=2, linestyle='-') ax.plot(x, x+6, color="red", lw=2, ls='-.') ax.plot(x, x+7, color="red", lw=2, ls=':') # 虚线交错宽度 line, = ax.plot(x, x+8, color="black", lw=1.50) line.set_dashes([5, 10, 15, 10]) # 符号 ax.plot(x, x + 9, color="green", lw=2, ls='--', marker='+') ax.plot(x, x+10, color="green", lw=2, ls='--', marker='o') ax.plot(x, x+11, color="green", lw=2, ls='--', marker='s') ax.plot(x, x+12, color="green", lw=2, ls='--', marker='1') # 符号大小和颜色 ax.plot(x, x+13, color="purple", lw=1, ls='-', marker='o', markersize=2) ax.plot(x, x+14, color="purple", lw=1, ls='-', marker='o', markersize=4) ax.plot(x, x+15, color="purple", lw=1, ls='-', marker='o', markersize=8, markerfacecolor="red") ax.plot(x, x+16, color="purple", lw=1, ls='-', marker='s', markersize=8, markerfacecolor="yellow", markeredgewidth=2, markeredgecolor="blue")
画布网格、坐标轴范围
有些时候,我们可能需要显示画布网格或调整坐标轴范围
设置画布网格和坐标轴范围
这里,我们通过指定 axes[0] 序号,来实现子图的自定义顺序排列
fig, axes = plt.subplots(1, 2, figsize=(10, 5)) # 显示网格 axes[0].plot(x, x**2, x, x**3, lw=2) axes[0].grid(True) # 设置坐标轴范围 axes[1].plot(x, x**2, x, x**3) axes[1].set_ylim([0, 60]) axes[1].set_xlim([2, 5])
除了折线图,Matplotlib 还支持绘制散点图、柱状图等其他常见图形
下面,我们绘制由散点图、梯步图、条形图、面积图构成的子图
n = np.array([0, 1, 2, 3, 4, 5]) fig, axes = plt.subplots(1, 4, figsize=(16, 5)) axes[0].scatter(x, x + 0.25*np.random.randn(len(x))) axes[0].set_title("scatter") axes[1].step(n, n**2, lw=2) axes[1].set_title("step") axes[2].bar(n, n**2, align="center", width=0.5, alpha=0.5) axes[2].set_title("bar") axes[3].fill_between(x, x**2, x**3, color="green", alpha=0.5) axes[3].set_title("fill_between")
图形标注方法
当我们绘制一些较为复杂的图像时,阅读对象往往很难全面理解图像的含义。而此时,图像标注往往会起到画龙点睛的效果
图像标注,就是在画面上添加文字注释、指示箭头、图框等各类标注元素
Matplotlib 中,文字标注的方法由 matplotlib.pyplot.text() 实现
最基本的样式为 matplotlib.pyplot.text(x, y, s),其中 x, y 用于标注位置定位,s 代表标注的字符串
除此之外,你还可以通过 fontsize= , horizontalalignment= 等参数调整标注字体的大小,对齐样式等
下面,我们举一个对柱形图进行文字标注的示例
fig,axes = plt.subplots() # 柱形图横坐标 x_bar = [ 10,20,30,40,50 ] # 柱形图纵坐标 y_bar = [ 0.5,0.6,0.3,0.4,0.8 ] # 绘制柱形图 bars = axes.bar(x_bar,y_bar,color="blue",label=x_bar,width=2) for i,rect in enumerate(bars): # 获取柱形图纵坐标 x_text = rect.get_x() # 获取柱子的高度并增加0.01 y_text = rect.get_height() + 0.01 # 标注文字 plt.text(x_text,y_text,'%.1f' % y_bar[i])
除了文字标注之外,还可以通过 matplotlib.pyplot.annotate() 方法向图像中添加箭头等样式标注
接下来,我们向上面的例子中增添一行增加箭头标记的代码
for i, rect in enumerate(bars): # 获取柱形图纵坐标 x_text = rect.get_x() # 获取柱子的高度并增加0.01 y_text = rect.get_height() + 0.01 # 标注文字 plt.text(x_text, y_text, '%.1f' % y_bar[i]) # 增加箭头标注 plt.annotate( 'Min', xy=(32, 0.3), xytext=(36, 0.3), arrowprops=dict(facecolor='black', width=1, headwidth=7) )
上面的示例中,xy=() 表示标注终点坐标,xytext=() 表示标注起点坐标
在箭头绘制的过程中,arrowprops=() 用于设置箭头样式,facecolor= 设置颜色,width= 设置箭尾宽度,headwidth= 设置箭头宽度,可以通过 arrowstyle= 改变箭头的样式。