Python 数据可视化入门:Matplotlib 从基础到实战

摘要

在数据分析与机器学习领域,数据可视化是传递信息的关键环节。Matplotlib 作为 Python 生态中最经典的可视化库,凭借其灵活的定制能力和丰富的图表类型,成为开发者必备工具。本文将从环境搭建开始,逐步讲解 Matplotlib 的核心用法,最终通过实战案例带你掌握数据可视化的实用技巧。

一、环境搭建与基础配置

1.1 安装 Matplotlib

首先确保已安装 Python 环境(建议 3.7 及以上版本),通过 pip 命令快速安装:



# 基础安装


pip install matplotlib


# 若需支持中文显示,建议同时安装中文字体依赖


pip install matplotlib fonttools

1.2 基础配置(解决中文显示问题)

Matplotlib 默认不支持中文,需在代码开头添加配置:



import matplotlib.pyplot as plt


import numpy as np


# 配置中文显示


plt.rcParams['font.sans-serif'] = ['WenQuanYi Zen Hei', 'SimHei', 'Arial Unicode MS']


plt.rcParams['axes.unicode_minus'] = False # 解决负号显示异常

二、Matplotlib 核心概念与基础图表

2.1 核心对象:Figure 与 Axes

Matplotlib 的绘图逻辑基于两大核心对象:

Figure:相当于画布,是所有图表的容器

Axes:相当于画布上的绘图区域,一个 Figure 可包含多个 Axes

创建基础绘图框架的两种方式:



# 方式1:plt.subplots()(推荐,支持多子图)


fig, ax = plt.subplots(figsize=(8, 5)) # figsize指定画布尺寸(宽, 高)


# 方式2:plt.figure() + add_subplot()


fig = plt.figure(figsize=(8, 5))


ax = fig.add_subplot(111) # 1行1列第1个子图

2.2 常用基础图表实战

2.2.1 折线图(Line Plot)

适用于展示数据随时间或连续变量的变化趋势:



# 生成示例数据


x = np.linspace(0, 10, 100) # 0到10之间的100个均匀点


y1 = np.sin(x)


y2 = np.cos(x)


# 创建画布与子图


fig, ax = plt.subplots(figsize=(10, 6))


# 绘制折线图


ax.plot(x, y1, label='sin(x)', color='#FF6B6B', linewidth=2, linestyle='-')


ax.plot(x, y2, label='cos(x)', color='#4ECDC4', linewidth=2, linestyle='--')


# 添加图表元素


ax.set_title('正弦函数与余弦函数曲线', fontsize=14, pad=20) # 标题


ax.set_xlabel('x值', fontsize=12) # x轴标签


ax.set_ylabel('y值', fontsize=12) # y轴标签


ax.legend(fontsize=10) # 图例


ax.grid(True, alpha=0.3) # 网格线(alpha控制透明度)


# 保存图片(dpi控制分辨率,bbox_inches避免标签被截断)


plt.savefig('sin_cos_plot.png', dpi=300, bbox_inches='tight')


plt.show()

2.2.2 柱状图(Bar Plot)

适用于对比不同类别数据的数值大小:



# 示例数据:某产品季度销量


quarters = ['Q1', 'Q2', 'Q3', 'Q4']


sales_2023 = [120, 180, 150, 210]


sales_2024 = [150, 200, 170, 240]


# 创建画布


fig, ax = plt.subplots(figsize=(10, 6))


# 设置柱状图位置(避免重叠)


x = np.arange(len(quarters))


width = 0.35


# 绘制双柱状图


bars1 = ax.bar(x - width/2, sales_2023, width, label='2023年', color='#95E1D3')


bars2 = ax.bar(x + width/2, sales_2024, width, label='2024年', color='#F38BA8')


# 在柱子顶部添加数值标签


def add_value_labels(bars):


for bar in bars:


height = bar.get_height()


ax.text(bar.get_x() + bar.get_width()/2., height + 5,


f'{int(height)}', ha='center', va='bottom', fontsize=10)


add_value_labels(bars1)


add_value_labels(bars2)


# 调整x轴标签


ax.set_xticks(x)


ax.set_xticklabels(quarters)


# 添加其他元素


ax.set_title('某产品2023-2024年季度销量对比', fontsize=14, pad=20)


ax.set_ylabel('销量(件)', fontsize=12)


ax.legend()


ax.grid(True, alpha=0.3, axis='y') # 仅显示y轴网格线


plt.savefig('sales_comparison.png', dpi=300, bbox_inches='tight')


plt.show()

三、进阶技巧:子图布局与样式定制

3.1 多子图布局(Subplot Layout)

通过plt.subplots()的nrows和ncols参数实现多子图排列:



# 创建2行2列的子图布局


fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(12, 10))


# 扁平化axes数组(便于循环操作)


axes = axes.flatten()


# 子图1:散点图


x = np.random.rand(100)


y = np.random.rand(100)


colors = np.random.rand(100)


axes[0].scatter(x, y, c=colors, cmap='viridis', alpha=0.6)


axes[0].set_title('散点图(颜色映射)')


# 子图2:直方图


data = np.random.normal(0, 1, 1000) # 正态分布数据


axes[1].hist(data, bins=30, color='#FFD93D', edgecolor='black')


axes[1].set_title('直方图(正态分布)')


# 子图3:饼图


labels = ['A', 'B', 'C', 'D']


sizes = [30, 25, 20, 25]


colors = ['#6BCF7F', '#4D96FF', '#FF7D00', '#FF5252']


axes[2].pie(sizes, labels=labels, colors=colors, autopct='%1.1f%%', startangle=90)


axes[2].set_title('饼图(类别占比)')


# 子图4:箱线图


data = [np.random.normal(i, 1, 100) for i in range(4)]


axes[3].boxplot(data, labels=['组1', '组2', '组3', '组4'], patch_artist=True,


boxprops=dict(facecolor='#E8F4FD'))


axes[3].set_title('箱线图(数据分布)')


# 调整子图间距(避免标签重叠)


plt.tight_layout()


plt.savefig('multi_subplots.png', dpi=300, bbox_inches='tight')


plt.show()

3.2 样式定制(Style)

Matplotlib 提供多种预设样式,也支持自定义:



# 查看所有预设样式


print(plt.style.available)


# 使用预设样式


plt.style.use('seaborn-v0_8-talk') # 高对比度样式,适合演示


# 自定义样式(通过rcParams)


plt.rcParams.update({


'axes.backgroundcolor': '#F8F9FA',


'axes.titlecolor': '#2D3436',


'xtick.color': '#636E72',


'ytick.color': '#636E72',


'font.size': 11,


'legend.frameon': True,


'legend.framealpha': 0.9


})

四、实战案例:鸢尾花数据集可视化分析

结合 sklearn 的鸢尾花数据集,展示多维度可视化分析流程:



from sklearn.datasets import load_iris


# 加载数据


iris = load_iris()


X = iris.data # 特征:花萼长度、花萼宽度、花瓣长度、花瓣宽度


y = iris.target # 标签:0=山鸢尾,1=变色鸢尾,2=维吉尼亚鸢尾


feature_names = iris.feature_names


target_names = iris.target_names


# 创建画布(2行2列子图,分析特征间相关性)


fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(14, 12))


axes = axes.flatten()


# 定义颜色与标记


colors = ['#FF6B6B', '#4ECDC4', '#45B7D1']


markers = ['o', 's', '^']


# 子图1:花萼长度 vs 花萼宽度


for i in range(3):


mask = y == i


axes[0].scatter(X[mask, 0], X[mask, 1], c=colors[i], marker=markers[i],


label=target_names[i], s=60, alpha=0.7)


axes[0].set_xlabel(feature_names[0])


axes[0].set_ylabel(feature_names[1])


axes[0].set_title('花萼长度 vs 花萼宽度')


axes[0].legend()


axes[0].grid(True, alpha=0.3)


# 子图2:花瓣长度 vs 花瓣宽度


for i in range(3):


mask = y == i


axes[1].scatter(X[mask, 2], X[mask, 3], c=colors[i], marker=markers[i],


label=target_names[i], s=60, alpha=0.7)


axes[1].set_xlabel(feature_names[2])


axes[1].set_ylabel(feature_names[3])


axes[1].set_title('花瓣长度 vs 花瓣宽度')


axes[1].legend()


axes[1].grid(True, alpha=0.3)


# 子图3:特征分布箱线图


X_T = X.T # 转置后按特征分组


bp = axes[2].boxplot(X_T, labels=[name.replace(' (cm)', '') for name in feature_names],


patch_artist=True)


for patch, color in zip(bp['boxes'], ['#FFEAA7', '#81ECEC', '#FD79A8', '#FDCB6E']):


patch.set_facecolor(color)


axes[2].set_title('各特征分布箱线图')


axes[2].set_ylabel('特征值(cm)')


# 子图4:特征相关性热力图


corr = np.corrcoef(X.T)


im = axes[3].imshow(corr, cmap='RdYlBu_r', vmin=-1, vmax=1)


# 添加数值标签


for i in range(len(feature_names)):


for j in range(len(feature_names)):


axes[3].text(j, i, f'{corr[i, j]:.2f}', ha='center', va='center',


color='white' if abs(corr[i, j]) > 0.5 else 'black')


# 设置坐标轴标签


short_names = [name.split(' ')[0] + '
' + name.split(' ')[1] for name in feature_names]


axes[3].set_xticks(range(len(feature_names)))


axes[3].set_yticks(range(len(feature_names)))


axes[3].set_xticklabels(short_names)


axes[3].set_yticklabels(short_names)


axes[3].set_title('特征相关性热力图')


# 添加颜色条


cbar = plt.colorbar(im, ax=axes[3], shrink=0.8)


cbar.set_label('相关系数', rotation=270, labelpad=15)


plt.tight_layout()


plt.savefig('iris_visualization.png', dpi=300, bbox_inches='tight')


plt.show()

五、常见问题与解决方案

中文显示乱码:参考 1.2 节配置中文字体,若仍有问题,检查字体是否安装(如 Windows 的 “SimHei”、Linux 的 “WenQuanYi Zen Hei”)。

图片保存后标签被截断:plt.savefig()中添加bbox_inches='tight'参数。

子图间距过小:使用plt.tight_layout()或fig.subplots_adjust(left=0.1, right=0.9, top=0.9, bottom=0.1)手动调整。

图表样式不统一:通过plt.rcParams或plt.style.use()预设全局样式。

总结

Matplotlib 的核心优势在于高度可定制性,从基础的折线图、柱状图到复杂的多子图布局,都能满足不同场景的可视化需求。本文通过 “基础配置→核心图表→进阶技巧→实战案例” 的流程,带你快速上手 Matplotlib。建议在实际项目中结合具体数据场景,灵活调整图表类型与样式,让数据可视化真正成为数据分析的 “利器”。

如果本文对你有帮助,欢迎点赞、收藏,也欢迎在评论区分享你的 Matplotlib 使用技巧或问题!

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容