Python的matplotlib提供了pyplot隐式方法和显式Axes方法,这让很多人在选择时感到困惑。本文用9000字彻底解析两种方法的区别与适用场景,节选自👉Python matplotlib保姆级教程
matplotlib隐式绘图方法(pyplot)
matplotlib隐式绘图方法(请结合上文章节“4.3.1.1 Python隐式”学习),类似MATLAB,是一种基于函数调用的方法,这类方法的工具都位于matplotlib的pyplot中(下文以pyplot代指matplotlib隐式方法),pyplot中代码有4000+行(matplotlib/lib/matplotlib/pyplot.py at v3.9.2 · matplotlib/matplotlib · GitHub),代码里面有大量def定义的函数方法,绘图时就是调用pyplot中的函数方法,
如果使用 pyplot方法
,它帮你自动创建Figure、准备好你需要的Axes,你只需要告诉pyplot你要画什么,它就会自动完成其他一切。
举个绘制两个子图的代码例子,
## 4.3.2.1_01
import matplotlib.pyplot as plt
import numpy as npplt.figure(figsize=(10, 5)) # 隐式创建一个Figure
# 在隐式接口中,虽然没有返回具体的Figure对象,但pyplot会自动管理当前Figureplt.subplot(1, 2, 1) # 激活第1个子图,隐式创建子图(axes),准备在此子图上绘制heatmap图
# 每个subplot调用会创建一个新的axes(子图)对象,但该对象是隐式管理的data = np.random.random((10, 10))
plt.imshow(data, cmap='viridis')
plt.colorbar()
plt.title('Heatmap')plt.subplot(1, 2, 2) # 激活第2个子图,隐式创建一个新的axes,并在其中绘制Pie图
plt.pie([30, 40, 30], labels=['A', 'B', 'C'], autopct='%1.1f%%')
plt.title('Pie Chart')plt.show()
该类方法中,通过plt.figure和plt.subplot自动隐式的创建Figure和axes子图,绘图函数直接作用于当前激活的Figure和axes子图,持续跟踪“当前的”Figure和axes,Figure和axes具有“实效性”,见下图文字。
再通过一个复杂例子介绍matplotlib pyplot方法中如何设置常用的绘图元素,
# 添加画布Figure,图中红框包围的部分为一个Figure
fig = plt.figure(figsize=(9, 8), facecolor='1', dpi=150)# 为Figure添加标题
fig.suptitle('Matplotlib-pyplot法', x=0.46, fontsize=20, ha='right')# 设置子图Axes背景色等
plt.axes([marg, marg, 1 - 1.8 * marg, 1 - 1.8 * marg],aspect=1,facecolor='0.9')# 同一个axes上绘图
plt.plot(X, Y1, c='orange', lw=1, label="Orange signal", zorder=10)
plt.plot(X[::3],Y3[::3],linewidth=0,markersize=6,marker='*',markerfacecolor='none',markeredgecolor='black',markeredgewidth=1)# 设置子图标题
plt.title("Matplotlib图形元素", fontsize=15, verticalalignment='bottom')# 设置图例
plt.legend(loc="upper right", fontsize=10)# 设置坐标轴标题
plt.xlabel("x轴标题", fontsize=12)
plt.ylabel("y轴标题", fontsize=12)# 设置x,y轴刻度间隔
plt.gca().xaxis.set_major_locator(MultipleLocator(1.000)) # x轴主刻度间隔
plt.gca().xaxis.set_minor_locator(AutoMinorLocator(4)) # x轴副刻度间隔plt.gca().yaxis.set_major_locator(MultipleLocator(1.000))
plt.gca().yaxis.set_minor_locator(AutoMinorLocator(4))# 设置x轴副刻度格式,小数点后位数
plt.gca().xaxis.set_minor_formatter(minor_tick)# 设置x,y轴刻度范围
plt.xlim(0, 4)
plt.ylim(0, 4)# 设置x,y轴刻度字号、颜色等
plt.tick_params(which='major', width=1.0, labelsize=12)
plt.tick_params(which='major', length=10, labelsize=12)
plt.tick_params(which='minor', width=1.0, labelsize=10)
plt.tick_params(which='minor', length=5, labelsize=6, labelcolor='0.5')# 设置网格线
plt.grid(linestyle="--", linewidth=0.5, color='.25', zorder=-10)# 文本、箭头
plt.annotate("",xy=(4, 4),xytext=(4.2, 2.2),color=(0.25, 0.25, 1.00),weight="regular",arrowprops=dict(arrowstyle="->", connectionstyle="arc3", color="black"),
)plt.annotate("",xy=(4, 0),xytext=(4.2, 1.8),color=(0.25, 0.25, 1.00),weight="regular",arrowprops=dict(arrowstyle="->", connectionstyle="arc3", color="black"),
)
plt.show()
上图中蓝色字体部分展示如何利用matplotlib pyplot中的方法设置绘图元素:
Figure部分:
- 通过plt.figure添加Figure,通过figsize设置Figure的长宽,通过facecolor设置背景色,通过dpi设置分辨率;
- 通过plt.figure.suptitle添加Figure的标题为“Matplotlib-pyplot法”,通过x设置标题与y轴的距离,通过fontsize设置标题字号;
- 通过plt.figure.add_artist添加Figure的红色外框;
Axes部分:
- 通过plt.axes设置子图的属性,[marg, marg, 1 - 1.8 * marg, 1 - 1.8 * marg]四个值依次为[坐标轴离图形左边的距离,坐标轴离图形底部的距离,x坐标轴的长度,y坐标轴的长度],aspect设置xy坐标轴的长度比例,facecolor设置子图背景色;
- 通过第一个plt.plot在子图上绘制折线图;
- 通过第二个plt.plot在子图上绘制折线图,linewidth=0隐藏折线,marker='*'添加标记;
- 通过plt.title设置子图标题;
Axis部分:
- 通过plt.gca().xaxis取出x坐标轴并进一步设置;
- 通过plt.xlabel设置x坐标轴标题;
- 通过plt.xlim设置x坐标轴范围;
- 通过plt.gca().xaxis.set_major_locator(MultipleLocator(1.000)) 设置x坐标轴主刻度间隔;
- 通过plt.gca().xaxis.set_minor_locator(AutoMinorLocator(4)) 设置x坐标轴副刻度间隔;
- 通过plt.gca().yaxis取出y坐标轴并进一步设置;
- 通过plt.ylabel设置y轴标题;
- 通过plt.ylim设置y坐标轴范围;
- 通过plt.gca().yaxis.set_major_locator(MultipleLocator(1.000))设置y坐标轴主刻度间隔;
- 通过plt.gca().yaxis.set_minor_locator(AutoMinorLocator(4))设置y坐标轴副刻度间隔;
其它Aritst部分
- 通过plt.legend设置图例;
- 通过plt.grid设置网格线;
- 通过plt.annotate设置标记,如图中箭头,常用于标注数据点;
- 通过plt.text设置文本标签,如图中的蓝色文字说明;
在python社区默认通过“import matplotlib.pyplot as plt”将matplotlib.pyplot简写为plt,这种方法通过plt.+对应元素名称调用方法(例如,plt.title设置子图标题)。
这么多元素方法名称,记不住怎么办,没关系,因为matplotlib设计之初,大部分都设置了默认值,不用一个个设定,比如,你绘制一个line图,
## 4.3.2.1_03
import matplotlib.pyplot as plt
plt.plot([1, 2, 3, 4], [10, 20, 25, 30])
plt.show()
当然,你也可以通过python dir函数查看元素的所有方法名称,例如查看x坐标轴中的元素方法,
## 4.3.2.1_04
print(dir(plt.gca().xaxis)) #查看x坐标轴中所有元素方法
展示部分结果
['get_major_ticks', 'get_majorticklabels', 'get_majorticklines', 'get_majorticklocs', 'get_minorticklocs', 'get_minpos', 'get_mouseover', 'get_offset_text', 'get_path_effects', .......'get_units', 'get_url', 'get_view_interval', 'get_visible', 'get_window_extent', 'get_zorder', 'grid', 'have_units']
这里简单介绍,后续章节详细介绍主要元素方法的使用。
matplotlib显式绘图方法(axes )
matplotlib显式方法(请结合上文章节“4.3.1.2 Python显式”学习),是一种基于面向对象的方法(object-oriented),这类方法的工具都位于matplotlib的Figure和Axes接口中(下文以axes代指matplotlib显式方法)。
如果使用 axes
方法,
你需要自己创建Figure,然后创建子图axes,并且每一步都需要明确指定。
举个绘制两个子图的代码例子,
##4.3.2.2_01
import matplotlib.pyplot as plt
import numpy as np# 显式创建一个figure对象fig;
# 显式创建两个子图(axes)对象,ax1和ax2
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))# 在子图ax1上创建Heatmap图
data = np.random.random((10, 10))
im = ax1.imshow(data, cmap='viridis') # 在ax1子图上绘制heatmap,并使用'viridis'颜色映射
ax1.set_title('Heatmap')# 为heatmap添加颜色条,指定fig管理该颜色条,并将其与ax1关联
fig.colorbar(im, ax=ax1)# 在子图ax2上创建Pie图
ax2.pie([30, 40, 30], labels=['A', 'B', 'C'], autopct='%1.1f%%')
ax2.set_title('Pie Chart')plt.show()
该方法中,通过 fig, (ax1, ax2)
的形式直接创建Figure和axes子图,代码结构化,易于管理和扩展手动管理,ax1
和 ax2
分别代表两个子图(heatmap 和 pie)。
该方法中,画图函数不再受到当前“活动”的Figure和axes的限制,而变成了显式的 Figure 和 Axes 的方法,你可以直接随处对它们进行操作,Figure和axes不具有“实效性”,见下图文字。
这里也再通过一个复杂例子介绍matplotlib axes方法中如何设置常用的绘图元素,
# 为Figure添加标题
fig.suptitle('Matplotlib面向对象法', x=0.46, fontsize=20, ha='right')# 在Figure上添加子图Axes
marg = 0.15
ax = fig.add_axes([marg, marg, 1 - 1.8 * marg, 1 - 1.8 * marg],aspect=1,facecolor='0.9')# 同一个axes上绘图
ax.plot(X, Y1, c='orange', lw=1, label="Orange signal", zorder=10)
ax.plot(X[::3],Y3[::3],linewidth=0,markersize=6,marker='*',markerfacecolor='none',markeredgecolor='black',markeredgewidth=1)# 设置子图标题
ax.set_title("Matplotlib图形元素", fontsize=15, verticalalignment='bottom')# 设置图例
ax.legend(loc="upper right", fontsize=10)# 设置坐标轴标题
ax.set_xlabel("x轴标题", fontsize=12)
ax.set_ylabel("y轴标题", fontsize=12)# 设置x,y轴刻度间隔
ax.xaxis.set_major_locator(MultipleLocator(1.000)) # x轴主刻度间隔
ax.xaxis.set_minor_locator(AutoMinorLocator(4)) # x轴副刻度间隔ax.yaxis.set_major_locator(MultipleLocator(1.000))
ax.yaxis.set_minor_locator(AutoMinorLocator(4))# 设置x轴副刻度格式
ax.xaxis.set_minor_formatter(minor_tick)# 设置x,y轴刻度范围
ax.set_xlim(0, 4)
ax.set_ylim(0, 4)# 设置x,y轴刻度字号、颜色等
ax.tick_params(which='major', width=1.0, labelsize=12)
ax.tick_params(which='major', length=10, labelsize=12)
ax.tick_params(which='minor', width=1.0, labelsize=10)
ax.tick_params(which='minor', length=5, labelsize=6, labelcolor='0.5')# 设置网格线
ax.grid(linestyle="--", linewidth=0.5, color='.25', zorder=-10)# 文本、箭头
ax.annotate("",xy=(4, 4),xytext=(4.2, 2.2),color=(0.25, 0.25, 1.00),weight="regular",arrowprops=dict(arrowstyle="->", connectionstyle="arc3", color="black"),
)ax.annotate("",xy=(4, 0),xytext=(4.2, 1.8),color=(0.25, 0.25, 1.00),weight="regular",arrowprops=dict(arrowstyle="->", connectionstyle="arc3", color="black"),
)# 矩形外框
fig.add_artist(Rectangle((0, 0),width=1,height=1,facecolor='none',edgecolor='red',linewidth=1.0))
上图中蓝色字体部分展示如何利用matplotlib axes中的方法设置绘图元素:
Figure部分:
- 通过plt.figure添加Figure,通过figsize设置Figure的长宽,通过facecolor设置背景色,通过dpi设置分辨率;
- 通过plt.figure.suptitle添加Figure的标题为“Matplotlib面向对象法”,通过x设置标题与y轴的距离,通过fontsize设置标题字号;
- 通过plt.figure.add_artist添加Figure的红色外框;
在Figure部分两种方法类似。
Axes部分:
- 通过plt.figure.add_axes添加子图ax,并设置子图的属性,[marg, marg, 1 - 1.8 * marg, 1 - 1.8 * marg]四个值依次为[坐标轴离图形左边的距离,坐标轴离图形底部的距离,x坐标轴的长度,y坐标轴的长度],aspect设置xy坐标轴的长度比例,facecolor设置子图背景色;
- 通过第一个ax.plot在子图上绘制折线图;
- 通过第二个ax.plot在子图上绘制折线图,linewidth=0隐藏折线,marker='*'添加标记;
- 通过ax.set_title设置子图标题;
Axis部分:
- 通过ax.xaxis取出x坐标轴并进一步设置;
- 通过ax.set_xlabel设置x坐标轴标题;
- 通过ax.set_xlim设置x坐标轴范围;
- 通过ax.xaxis.set_major_locator(MultipleLocator(1.000))设置x坐标轴主刻度间隔;
- 通过ax.xaxis.set_minor_locator(AutoMinorLocator(4))设置x坐标轴副刻度间隔;
- 通过ax.yaxis取出y坐标轴并进一步设置;
- 通过ax.set_ylabel设置y轴标题;
- 通过ax.set_ylim设置y坐标轴范围;
- 通过ax.yaxis.set_major_locator(MultipleLocator(1.000))设置y坐标轴主刻度间隔;
- 通过ax.yaxis.set_minor_locator(AutoMinorLocator(4))设置y坐标轴副刻度间隔;
其它Aritst部分
- 通过ax.legend设置图例;
- 通过ax.grid设置网格线;
- 通过ax.annotate设置标记,如图中箭头,常用于标注数据点;
- 通过ax.text设置文本标签,如图中的蓝色文字说明;
一般将matplotlib面向对象方法中子图简写为ax,这种方法通过ax.+对应元素名称调用方法(例如,ax.title设置子图标题)。
这么多元素方法名称,记不住怎么办,没关系,因为matplotlib设计之初,大部分都设置了默认值,不用一个个设定,比如,你绘制一个line图,
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot([1, 2, 3, 4], [10, 20, 25, 30])
plt.show()
以上使用默认设置作图。
当然,你也可以通过python dir函数查看元素的所有方法名称,例如查看子图中的元素方法,
##4.3.2.2_04
print(dir(ax)) #输出子图axes中的所有元素方法名称
结果为一个python列表,以下展示部分 ,
['set_facecolor', 'set_fc', 'set_figure', 'set_frame_on', 'set_gid', 'set_in_layout', .......'xcorr', 'yaxis', 'yaxis_date', 'yaxis_inverted', 'zorder']
这里简单介绍,后续章节详细介绍主要元素方法的使用。
matplotlib隐式 VS 显式方法
简单总结两种绘图方法异同,便于取舍。
绘制简单图形时,两种方法类似,复杂图形中后者优势明显。
- matplotlib隐式方法(pyplot)
适用于快速绘制简单图形,代码简洁易懂,但在需要精细控制和复杂布局时可能不够灵活。
- matplotlib显式方法(axes)
适用于需要精确控制和复杂布局图形的场景,提供更高的灵活性和可维护性。
两种方法优缺点比较
特性 | matplotlib显式方法(axes) | matplotlib隐式方法(pyplot) |
---|---|---|
优点 | ||
控制和灵活性 | 1. 提供精确的控制和灵活性,适用于复杂布局和定制 | 1. 代码简洁,适合快速绘图 |
代码结构 | 2. 代码结构清晰,易于维护和扩展 | 2. 易于上手,初学者友好 |
兼容性 | 3. 更好地与其他库(如seaborn、pandas)兼容 | 3. 适用于简单情境 |
支持复杂布局 | 4. 支持复杂的图形布局,如gridspec和subplots | |
缺点 | ||
代码复杂度 | 1. 代码较为繁琐,尤其是在简单图形中 | 1. 控制和灵活性较差,难以进行复杂自定义 |
学习曲线 | 2. 学习曲线较陡,需要理解和掌握 Axes 对象的使用 | 2. 难以管理多个图形和子图对象 |
管理多个图形 | 3. 对于复杂图形和多个图形的管理较为复杂 | 3. 代码在复杂任务中可能难以维护快速上手,一个案例 |
两种方法使用层面比较
详细见章节“4.3.2.1 matplotlib隐式绘图方法(pyplot)”和章节“4.3.2.2 matplotlib显式绘图方法(axes )”。也可以通过比较下图中蓝色字体部分,了解两种方法的使用差异。
根据上一章节的介绍,后续重点通过matplotlib显式方法介绍matplotlib的使用。