当前位置: 首页 > news >正文

Matplotlib 完全指南:从入门到精通

前言

Matplotlib 是 Python 中最基础、最强大的数据可视化库之一。无论你是数据分析师、数据科学家还是研究人员,掌握 Matplotlib 都是必不可少的技能。本文将带你从零开始学习 Matplotlib,帮助你掌握各种图表的绘制方法和高级技巧。
在这里插入图片描述

目录

  1. Matplotlib 简介
  2. 安装与基础配置
  3. 基础绘图
  4. 常用图表类型
  5. 图表样式与美化
  6. 多子图布局
  7. 高级技巧
  8. 实战案例
  9. 常见问题与解决方案
  10. 总结与资源

Matplotlib 简介

Matplotlib 是一个用于创建静态、动态和交互式图表的 Python 库。它由 John D. Hunter 在 2003 年开发,灵感来自于 MATLAB 的绘图功能。

主要特点

  • 功能全面:支持多种图表类型,从简单的线图到复杂的 3D 图表
  • 高度可定制:几乎所有图表元素都可以自定义
  • 跨平台:支持多种输出格式(PNG、PDF、SVG 等)
  • 与其他库的良好集成:特别是 NumPy 和 Pandas
  • 活跃的社区:丰富的文档和示例

安装与基础配置

安装

# 使用 pip 安装
pip install matplotlib# 使用 conda 安装
conda install matplotlib

基础导入

import matplotlib.pyplot as plt
import numpy as np# 设置中文显示(解决中文乱码问题)
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False    # 用来正常显示负号

Jupyter Notebook 配置

# 在 Jupyter Notebook 中显示图片
%matplotlib inline# 使用高清显示
%config InlineBackend.figure_format = 'retina'

基础绘图

第一个图表

# 创建数据
x = np.linspace(0, 10, 100)
y = np.sin(x)# 创建图表
plt.figure(figsize=(8, 6))
plt.plot(x, y)
plt.title('正弦函数图')
plt.xlabel('x 轴')
plt.ylabel('y 轴')
plt.grid(True)
plt.show()

图表的基本组成

一个完整的 Matplotlib 图表包含以下主要组件:

  • Figure(画布):整个图表的容器
  • Axes(坐标系):实际的绘图区域
  • Axis(坐标轴):x 轴和 y 轴
  • Artist(图表元素):所有可见的元素(线条、文本、标记等)
# 面向对象的绘图方式
fig, ax = plt.subplots(figsize=(8, 6))
ax.plot(x, y)
ax.set_title('正弦函数图')
ax.set_xlabel('x 轴')
ax.set_ylabel('y 轴')
ax.grid(True)
plt.show()

常用图表类型

1. 线图(Line Plot)

# 多条线图
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)plt.figure(figsize=(10, 6))
plt.plot(x, y1, label='sin(x)', color='blue', linestyle='-', linewidth=2)
plt.plot(x, y2, label='cos(x)', color='red', linestyle='--', linewidth=2)
plt.title('三角函数图')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()

2. 散点图(Scatter Plot)

# 创建随机数据
np.random.seed(42)
x = np.random.randn(100)
y = 2 * x + 1 + np.random.randn(100) * 0.5plt.figure(figsize=(8, 6))
plt.scatter(x, y, c=x, cmap='viridis', alpha=0.6, s=50)
plt.colorbar(label='x值')
plt.title('散点图示例')
plt.xlabel('x')
plt.ylabel('y')
plt.show()

3. 柱状图(Bar Chart)

# 柱状图
categories = ['A', 'B', 'C', 'D', 'E']
values = [23, 45, 56, 78, 32]plt.figure(figsize=(8, 6))
bars = plt.bar(categories, values, color='skyblue', edgecolor='navy', alpha=0.7)# 在柱子上添加数值
for bar in bars:height = bar.get_height()plt.text(bar.get_x() + bar.get_width()/2., height,f'{height}', ha='center', va='bottom')plt.title('柱状图示例')
plt.xlabel('类别')
plt.ylabel('数值')
plt.grid(True, axis='y', alpha=0.3)
plt.show()

4. 直方图(Histogram)

# 生成正态分布数据
data = np.random.normal(100, 15, 1000)plt.figure(figsize=(10, 6))
n, bins, patches = plt.hist(data, bins=30, density=True, alpha=0.7, color='green', edgecolor='black')# 添加正态分布曲线
mu, sigma = np.mean(data), np.std(data)
x = np.linspace(data.min(), data.max(), 100)
plt.plot(x, 1/(sigma * np.sqrt(2 * np.pi)) * np.exp(-0.5 * ((x - mu) / sigma) ** 2),'r-', linewidth=2, label='正态分布曲线')plt.title('直方图与正态分布')
plt.xlabel('数值')
plt.ylabel('频率密度')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()

5. 饼图(Pie Chart)

# 饼图数据
sizes = [30, 25, 20, 15, 10]
labels = ['A', 'B', 'C', 'D', 'E']
colors = ['#ff9999', '#66b3ff', '#99ff99', '#ffcc99', '#ff99cc']
explode = (0.05, 0, 0, 0, 0)  # 突出显示第一块plt.figure(figsize=(8, 8))
plt.pie(sizes, explode=explode, labels=labels, colors=colors, autopct='%1.1f%%',shadow=True, startangle=90)
plt.title('饼图示例')
plt.axis('equal')
plt.show()

6. 箱线图(Box Plot)

# 创建多组数据
data = [np.random.normal(0, std, 100) for std in range(1, 5)]plt.figure(figsize=(8, 6))
bp = plt.boxplot(data, patch_artist=True, labels=['A', 'B', 'C', 'D'])# 自定义箱线图颜色
colors = ['lightblue', 'lightgreen', 'lightpink', 'lightyellow']
for patch, color in zip(bp['boxes'], colors):patch.set_facecolor(color)plt.title('箱线图示例')
plt.xlabel('组别')
plt.ylabel('数值')
plt.grid(True, alpha=0.3)
plt.show()

图表样式与美化

1. 使用内置样式

# 查看可用样式
print(plt.style.available)# 使用样式
plt.style.use('seaborn')
# 或者使用临时样式
with plt.style.context('ggplot'):plt.plot(x, y)plt.show()

2. 自定义颜色和样式

# 自定义颜色映射
from matplotlib import cmx = np.linspace(0, 2*np.pi, 100)
fig, ax = plt.subplots(figsize=(10, 6))# 使用不同的颜色和样式
for i in range(5):y = np.sin(x + i*0.5)color = cm.viridis(i/4)  # 使用颜色映射ax.plot(x, y, color=color, linewidth=2, label=f'sin(x + {i*0.5:.1f})')ax.set_title('使用颜色映射的多条曲线')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.legend()
ax.grid(True, alpha=0.3)
plt.show()

3. 添加注释和标记

# 创建数据
x = np.linspace(0, 10, 100)
y = np.sin(x)fig, ax = plt.subplots(figsize=(10, 6))
ax.plot(x, y, 'b-', linewidth=2)# 标记最大值点
max_idx = np.argmax(y)
ax.plot(x[max_idx], y[max_idx], 'ro', markersize=10)# 添加注释
ax.annotate(f'最大值: {y[max_idx]:.2f}', xy=(x[max_idx], y[max_idx]), xytext=(x[max_idx]+1, y[max_idx]+0.1),arrowprops=dict(arrowstyle='->', color='red'),fontsize=12)# 添加文本
ax.text(5, -0.5, '正弦函数', fontsize=16, ha='center',bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.5))ax.set_title('带注释的正弦函数图')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.grid(True, alpha=0.3)
plt.show()

多子图布局

1. 使用 subplot

# 创建 2x2 的子图
fig, axes = plt.subplots(2, 2, figsize=(12, 10))# 数据
x = np.linspace(0, 2*np.pi, 100)# 子图1:正弦函数
axes[0, 0].plot(x, np.sin(x), 'b-')
axes[0, 0].set_title('正弦函数')# 子图2:余弦函数
axes[0, 1].plot(x, np.cos(x), 'r-')
axes[0, 1].set_title('余弦函数')# 子图3:正切函数
axes[1, 0].plot(x, np.tan(x), 'g-')
axes[1, 0].set_ylim(-5, 5)
axes[1, 0].set_title('正切函数')# 子图4:组合
axes[1, 1].plot(x, np.sin(x), 'b-', label='sin(x)')
axes[1, 1].plot(x, np.cos(x), 'r-', label='cos(x)')
axes[1, 1].set_title('组合图')
axes[1, 1].legend()# 调整子图间距
plt.tight_layout()
plt.show()

2. 使用 GridSpec

from matplotlib.gridspec import GridSpecfig = plt.figure(figsize=(12, 8))
gs = GridSpec(3, 3, figure=fig)# 创建不同大小的子图
ax1 = fig.add_subplot(gs[0, :])
ax2 = fig.add_subplot(gs[1, :2])
ax3 = fig.add_subplot(gs[1:, 2])
ax4 = fig.add_subplot(gs[2, 0])
ax5 = fig.add_subplot(gs[2, 1])# 在每个子图中绘制
x = np.linspace(0, 10, 100)
ax1.plot(x, np.sin(x))
ax1.set_title('主图')ax2.bar(['A', 'B', 'C'], [3, 7, 5])
ax2.set_title('柱状图')ax3.scatter(np.random.randn(50), np.random.randn(50))
ax3.set_title('散点图')ax4.pie([30, 70], labels=['A', 'B'])
ax4.set_title('饼图')ax5.hist(np.random.normal(0, 1, 100))
ax5.set_title('直方图')plt.tight_layout()
plt.show()

高级技巧

1. 双坐标轴

# 创建具有两个 y 轴的图表
fig, ax1 = plt.subplots(figsize=(10, 6))x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.exp(x/10)# 第一个 y 轴
color = 'tab:red'
ax1.set_xlabel('x')
ax1.set_ylabel('sin(x)', color=color)
ax1.plot(x, y1, color=color)
ax1.tick_params(axis='y', labelcolor=color)# 第二个 y 轴
ax2 = ax1.twinx()
color = 'tab:blue'
ax2.set_ylabel('exp(x/10)', color=color)
ax2.plot(x, y2, color=color)
ax2.tick_params(axis='y', labelcolor=color)plt.title('双 Y 轴图表')
fig.tight_layout()
plt.show()

2. 3D 图表

from mpl_toolkits.mplot3d import Axes3D# 创建 3D 图表
fig = plt.figure(figsize=(12, 9))
ax = fig.add_subplot(111, projection='3d')# 创建数据
x = np.linspace(-5, 5, 50)
y = np.linspace(-5, 5, 50)
X, Y = np.meshgrid(x, y)
Z = np.sin(np.sqrt(X**2 + Y**2))# 绘制 3D 表面
surf = ax.plot_surface(X, Y, Z, cmap='viridis', alpha=0.8)# 添加轮廓线
contours = ax.contour(X, Y, Z, zdir='z', offset=-2, cmap='viridis')ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_title('3D 表面图')# 添加颜色条
fig.colorbar(surf, shrink=0.5, aspect=5)
plt.show()

3. 动画

from matplotlib.animation import FuncAnimation# 创建动画
fig, ax = plt.subplots(figsize=(8, 6))
ax.set_xlim(0, 2*np.pi)
ax.set_ylim(-1.5, 1.5)x = np.linspace(0, 2*np.pi, 1000)
line, = ax.plot([], [], 'b-')def init():line.set_data([], [])return line,def animate(frame):y = np.sin(x + frame/10)line.set_data(x, y)return line,# 创建动画(这里只展示代码,实际运行需要保存或在支持的环境中显示)
anim = FuncAnimation(fig, animate, init_func=init, frames=100, interval=50, blit=True)# 保存动画
# anim.save('sine_wave.gif', writer='pillow')
plt.show()

实战案例

案例 1:股票价格分析图

# 模拟股票数据
dates = pd.date_range('2023-01-01', periods=100)
stock_price = 100 + np.cumsum(np.random.randn(100) * 2)
volume = np.random.randint(1000000, 5000000, 100)fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 8), sharex=True)# 价格图
ax1.plot(dates, stock_price, 'b-', linewidth=2)
ax1.fill_between(dates, stock_price, alpha=0.3)
ax1.set_ylabel('价格 (元)')
ax1.set_title('股票价格走势图')
ax1.grid(True, alpha=0.3)# 成交量图
ax2.bar(dates, volume, color='gray', alpha=0.7)
ax2.set_ylabel('成交量')
ax2.set_xlabel('日期')
ax2.grid(True, alpha=0.3)plt.tight_layout()
plt.show()

案例 2:数据分析仪表盘

# 创建仪表盘布局
fig = plt.figure(figsize=(15, 10))
gs = GridSpec(3, 3, figure=fig, hspace=0.3, wspace=0.3)# 数据准备
np.random.seed(42)
categories = ['产品A', '产品B', '产品C', '产品D', '产品E']
sales = np.random.randint(50, 200, 5)
months = ['1月', '2月', '3月', '4月', '5月', '6月']
monthly_sales = np.random.randint(100, 500, (6, 5))# 1. 总销售额饼图
ax1 = fig.add_subplot(gs[0, :2])
ax1.pie(sales, labels=categories, autopct='%1.1f%%', startangle=90)
ax1.set_title('产品销售占比')# 2. 月度销售趋势
ax2 = fig.add_subplot(gs[0, 2])
for i, product in enumerate(categories):ax2.plot(months, monthly_sales[:, i], marker='o', label=product)ax2.set_title('月度销售趋势')ax2.legend(fontsize=8)ax2.grid(True, alpha=0.3)# 3. 销售额柱状图ax3 = fig.add_subplot(gs[1, :])x = np.arange(len(categories))width = 0.15for i, month in enumerate(months[:4]):ax3.bar(x + i*width, monthly_sales[i], width, label=month)ax3.set_xlabel('产品')ax3.set_ylabel('销售额')ax3.set_title('各产品月度销售对比')ax3.set_xticks(x + width * 1.5)ax3.set_xticklabels(categories)ax3.legend()ax3.grid(True, axis='y', alpha=0.3)# 4. 销售额热力图ax4 = fig.add_subplot(gs[2, :2])im = ax4.imshow(monthly_sales, cmap='YlOrRd', aspect='auto')ax4.set_xticks(np.arange(len(categories)))ax4.set_yticks(np.arange(len(months)))ax4.set_xticklabels(categories)ax4.set_yticklabels(months)ax4.set_title('销售额热力图')# 在热力图上显示数值for i in range(len(months)):for j in range(len(categories)):text = ax4.text(j, i, monthly_sales[i, j],ha="center", va="center", color="black")# 5. KPI 指标ax5 = fig.add_subplot(gs[2, 2])ax5.text(0.5, 0.7, '总销售额', ha='center', va='center', fontsize=14)ax5.text(0.5, 0.5, f'{np.sum(monthly_sales):,}', ha='center', va='center', fontsize=24, fontweight='bold', color='red')ax5.text(0.5, 0.3, '同比增长 +23.5%', ha='center', va='center', fontsize=12, color='green')ax5.set_xlim(0, 1)ax5.set_ylim(0, 1)ax5.axis('off')plt.suptitle('销售数据分析仪表盘', fontsize=16)plt.show()

常见问题与解决方案

1. 中文显示问题

# 解决方案1:设置字体
plt.rcParams['font.sans-serif'] = ['SimHei']  # Windows
# plt.rcParams['font.sans-serif'] = ['Arial Unicode MS']  # macOS
plt.rcParams['axes.unicode_minus'] = False# 解决方案2:使用 FontProperties
from matplotlib.font_manager import FontProperties
font = FontProperties(fname='path/to/font.ttf')
plt.title('中文标题', fontproperties=font)

2. 图表大小和分辨率

# 设置图表大小
plt.figure(figsize=(12, 8))# 设置 DPI(分辨率)
plt.figure(dpi=150)# 保存高分辨率图片
plt.savefig('figure.png', dpi=300, bbox_inches='tight')

3. 图例位置调整

# 自动调整位置
plt.legend(loc='best')# 指定位置
plt.legend(loc='upper right')# 放在图表外部
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left')

4. 坐标轴范围和刻度

# 设置坐标轴范围
plt.xlim(0, 10)
plt.ylim(-1, 1)# 设置刻度
plt.xticks(np.arange(0, 11, 2))
plt.yticks([-1, -0.5, 0, 0.5, 1])# 旋转刻度标签
plt.xticks(rotation=45)

总结与资源

学习要点回顾

  1. 基础概念:理解 Figure、Axes、Axis 等核心概念
  2. 绘图方式:掌握函数式和面向对象两种绘图方式
  3. 图表类型:熟练使用各种常见图表类型
  4. 样式美化:学会自定义图表样式和颜色
  5. 布局技巧:掌握多子图和复杂布局
  6. 高级功能:了解 3D 绘图、动画等高级特性

推荐资源

  1. 官方文档:matplotlib.org
  2. 示例库:Matplotlib Gallery
  3. 教程:
    • Matplotlib Tutorial
    • Python Data Science Handbook
  4. 相关库:
    • Seaborn:基于 Matplotlib 的统计图表库
    • Plotly:交互式图表库
    • Bokeh:Web 交互式可视化

最佳实践

  1. 选择合适的图表类型:根据数据特点和展示目的选择
  2. 保持简洁:避免过度装饰,突出数据本身
  3. 使用有意义的标签:确保轴标签、标题清晰明了
  4. 选择合适的颜色:考虑色盲用户,使用对比度高的配色
  5. 添加必要的说明:使用图例、注释等帮助理解

结语

Matplotlib 是 Python 数据可视化的基石,掌握它将为你的数据分析工作提供强大支持。通过本文的学习,相信你已经对 Matplotlib 有了全面的了解。记住,最好的学习方式是实践,多动手尝试不同的图表和参数,逐步提升你的可视化技能。

Happy plotting! 🎨📊

相关文章:

  • 负载均衡 ELB 在 zkmall开源商城高流量场景下的算法优化
  • 高并发内存池(三):TLS无锁访问以及Central Cache结构设计
  • [ARM][汇编] 01.基础概念
  • CentOS 和 RHEL
  • Java学习手册:服务网关与路由
  • 电子电器架构 --- 借力第五代架构,驱动汽车产业创新引擎
  • 关于mac配置hdc(鸿蒙)
  • 【25软考网工】第六章(4)VPN虚拟专用网 L2TP、PPTP、PPP认证方式;IPSec、GRE
  • MacOS 上构建 gem5
  • 算法模型部署后_python脚本API测试指南-记录3
  • 四、STM32 HAL库API完全指南:从功能分类到实战示例
  • 微信小程序仿淘宝拍照/照片点位识图、点位裁剪生图、图片裁剪组件、图片点位框选、裁剪生成图片,canvasToImg
  • Parasoft C++Test软件单元测试_实例讲解(指针类型的处理)
  • Spring MVC 根据请求头 (如 Accept) 怎么返回 JSON 或 XML 数据?
  • WebFlux vs WebMVC vs Servlet 对比
  • 【SSM-SpringMVC(二)】Spring接入Web环境!本篇开始研究SpringMVC的使用!SpringMVC数据响应和获取请求数据
  • Spring MVC参数传递
  • tensorflow-cpu
  • tabs切换#
  • git|gitee仓库同步到github
  • 新闻1+1丨婚姻登记服务,如何跑出幸福加速度?
  • 对话郑永年:我们谈判也是为世界争公义
  • 上海国际电影节特设“今日亚洲”单元
  • 1至4月我国汽车产销量首次双超千万辆
  • “应急侠”上线,应急管理部正式发布应急科普IP形象
  • 做街坊们的“健康管家”,她把专科护理服务送上门