Matplotlib与Pandas绘图差异解析及2×2子图绘制指南
Matplotlib与Pandas绘图差异及2×2子图实现方案
一、核心差异梳理
1. 调用形式区别
- Matplotlib是函数式+面向对象双接口:
plt.method()是快捷函数调用,默认复用当前活跃的轴对象;Pandas的df.method()是基于Matplotlib做的高层封装,直接绑定DataFrame的列数据,省去手动提取数据的步骤,适合快速可视化表格数据。 - 本质:Pandas绘图是“偷懒版”Matplotlib,底层还是调用Matplotlib的绘图逻辑,但帮你做了数据适配;Matplotlib则更灵活,能精细控制从画布到坐标轴的每一个元素。
2. 何时用fig, ax = plt.subplots()
只要涉及以下场景,就必须显式创建画布(fig)和轴(ax)对象:
- 需要多子图布局(比如你要的2×2子图)
- 需要单独控制某一个子图的标题、坐标轴、样式
- 要自定义画布的大小、分辨率、背景等参数
如果只是画单张简单图表,用plt.hist()或df.hist()都可以不用显式创建,但复杂场景下显式管理轴对象会让代码逻辑更清晰。
二、三种方式实现2×2直方图子图
假设你的DataFrame名为df,包含col1、col2、col3、col4四列数据,以下是三种实现方式:
1. 纯Matplotlib方式
手动提取每列数据,逐个绑定到子图:
import matplotlib.pyplot as plt import pandas as pd # 创建2×2的画布和轴对象 fig, axes = plt.subplots(2, 2, figsize=(10, 8)) # 把2维轴数组转成一维,方便遍历 axes = axes.flatten() cols = ['col1', 'col2', 'col3', 'col4'] for ax, col in zip(axes, cols): # 手动提取列数据,调用Matplotlib的hist方法 ax.hist(df[col], bins=15, edgecolor='black') ax.set_title(f'{col} 直方图') ax.set_xlabel(col) ax.set_ylabel('频数') # 自动调整子图间距,避免重叠 plt.tight_layout() plt.show()
2. 纯Pandas方式
利用Pandas内置的hist方法自动处理子图布局:
import pandas as pd import matplotlib.pyplot as plt # 直接调用DataFrame的hist方法,指定布局参数 fig, axes = df[['col1', 'col2', 'col3', 'col4']].hist( bins=15, edgecolor='black', figsize=(10, 8), layout=(2, 2) ) # 可选:遍历轴对象修改标题 for ax, col in zip(axes.flatten(), cols): ax.set_title(f'{col} 直方图') plt.tight_layout() plt.show()
说明:Pandas的hist()会自动创建画布和轴,你也可以提前创建后通过ax参数指定,但纯Pandas方式就是让它自动处理布局逻辑。
3. 混合方式
手动创建画布和轴,用Pandas的绘图方法绑定到指定子图:
import matplotlib.pyplot as plt import pandas as pd fig, axes = plt.subplots(2, 2, figsize=(10, 8)) axes = axes.flatten() cols = ['col1', 'col2', 'col3', 'col4'] for ax, col in zip(axes, cols): # 用Pandas的hist方法,通过ax参数绑定到指定子图 df[col].hist(bins=15, edgecolor='black', ax=ax) ax.set_title(f'{col} 直方图') ax.set_xlabel(col) plt.tight_layout() plt.show()
这种方式兼顾Pandas的便捷性(不用手动提取数据)和Matplotlib的布局可控性。
三、Seaborn是否更易用?
绝对是。Seaborn是基于Matplotlib的统计可视化专用封装,语法更简洁,默认样式更专业,处理多变量、子图布局的效率极高,尤其适合ISLP这类统计教材的习题场景。
比如实现同样的2×2直方图,Seaborn的代码是:
import seaborn as sns import pandas as pd # 先把宽格式DataFrame转成长格式(Seaborn偏好的输入格式) df_long = df.melt(value_vars=['col1', 'col2', 'col3', 'col4'], var_name='列名', value_name='数值') # 一行代码生成2×2子图直方图 sns.displot( data=df_long, x='数值', col='列名', col_wrap=2, kind='hist', bins=15, edgecolor='black', height=4, aspect=1.2 ) plt.tight_layout() plt.show()
优势:
- 不用手动遍历轴对象,通过
col_wrap参数自动控制子图数量 - 自动生成统一的标题、坐标轴标签
- 默认样式比Matplotlib/Pandas的原生样式美观得多,不用额外调整
- 统计可视化功能更丰富,比如加核密度曲线、分组对比等都很方便
内容的提问来源于stack exchange,提问作者GT87
相关产品推荐
相关产品推荐

