Matplotlib是Python中最经典的数据可视化库,被誉为Python数据可视化的“基石”。本文将全面总结Matplotlib的核心知识点,帮助您快速掌握这一强大工具。

一、Matplotlib简介与安装

Matplotlib是一个Python的2D绘图库,可以生成高质量的图表和图形。

python

# 安装Matplotlib
pip install matplotlib

# 导入Matplotlib
import matplotlib.pyplot as plt
import numpy as np

# 设置中文字体(解决中文显示问题)
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题

二、基础绘图

2.1 基本绘图流程

python

# 创建数据
x = np.linspace(0, 10, 100)
y = np.sin(x)

# 创建图形和坐标轴
fig, ax = plt.subplots()

# 绘制线图
ax.plot(x, y, label='sin(x)')

# 添加标签和标题
ax.set_xlabel('X轴')
ax.set_ylabel('Y轴')
ax.set_title('正弦函数图像')
ax.legend()

# 显示图形
plt.show()

# 保存图形
plt.savefig('sine_plot.png', dpi=300, bbox_inches='tight')

2.2 多种图形绘制

python

# 创建数据
x = np.arange(10)
y1 = x ** 2
y2 = 2 * x + 3
categories = ['A', 'B', 'C', 'D', 'E']
values = [23, 45, 56, 78, 33]

# 创建子图
fig, axes = plt.subplots(2, 2, figsize=(10, 8))

# 线图
axes[0, 0].plot(x, y1, 'r-', linewidth=2, label='x²')
axes[0, 0].plot(x, y2, 'b--', label='2x+3')
axes[0, 0].set_title('线图')
axes[0, 0].legend()

# 散点图
axes[0, 1].scatter(x, y1, color='red', s=50, alpha=0.6, label='数据点')
axes[0, 1].set_title('散点图')
axes[0, 1].legend()

# 柱状图
axes[1, 0].bar(categories, values, color=['red', 'blue', 'green', 'orange', 'purple'])
axes[1, 0].set_title('柱状图')

# 直方图
data = np.random.randn(1000)
axes[1, 1].hist(data, bins=30, alpha=0.7, edgecolor='black')
axes[1, 1].set_title('直方图')

plt.tight_layout()
plt.show()

三、样式与美化

3.1 颜色、线型和标记

python

x = np.linspace(0, 2*np.pi, 50)

# 不同样式组合
fig, ax = plt.subplots(figsize=(10, 6))

# 颜色、线型和标记的多种组合
ax.plot(x, np.sin(x), 'r-', label='红色实线')  # 红色实线
ax.plot(x, np.cos(x), 'b--', label='蓝色虚线')  # 蓝色虚线
ax.plot(x, np.sin(x)*0.5, 'g-.', label='绿色点划线')  # 绿色点划线
ax.plot(x, np.cos(x)*0.5, 'yo-', label='黄色圆圈标记')  # 黄色圆圈标记
ax.plot(x, x/np.pi, 'ms:', label='品红方块虚线')  # 品红色方块标记虚线

ax.set_title('不同线型和颜色的比较')
ax.legend()
ax.grid(True, linestyle='--', alpha=0.5)
plt.show()

3.2 样式表和主题

python

# 查看所有可用样式
print(plt.style.available)

# 使用不同样式
fig, axes = plt.subplots(2, 3, figsize=(15, 8))
styles = ['default', 'ggplot', 'seaborn', 'fivethirtyeight', 'dark_background', 'grayscale']

for ax, style in zip(axes.flat, styles):
    plt.style.use(style)
    x = np.linspace(0, 10, 100)
    ax.plot(x, np.sin(x), label='sin(x)')
    ax.plot(x, np.cos(x), label='cos(x)')
    ax.set_title(style)
    ax.legend()

plt.tight_layout()
plt.show()

# 恢复到默认样式
plt.style.use('default')

四、子图和多图形布局

4.1 子图创建方法

python

# 方法1:使用subplots创建网格子图
fig, axes = plt.subplots(2, 3, figsize=(12, 8))
fig.suptitle('2x3网格子图', fontsize=16)

for i in range(2):
    for j in range(3):
        ax = axes[i, j]
        ax.plot(np.random.randn(50))
        ax.set_title(f'子图 ({i+1},{j+1})')

plt.tight_layout()
plt.show()

# 方法2:使用add_subplot创建不规则子图
fig = plt.figure(figsize=(10, 6))

# 创建2x2网格中的前三个
ax1 = fig.add_subplot(2, 2, 1)  # 第一行第一列
ax1.plot(np.random.randn(50))
ax1.set_title('子图1')

ax2 = fig.add_subplot(2, 2, 2)  # 第一行第二列
ax2.scatter(np.random.randn(50), np.random.randn(50))
ax2.set_title('子图2')

# 创建占据整行的子图
ax3 = fig.add_subplot(2, 1, 2)  # 第二行整行
ax3.hist(np.random.randn(1000), bins=30)
ax3.set_title('直方图(整行)')

plt.tight_layout()
plt.show()

4.2 GridSpec高级布局

python

import matplotlib.gridspec as gridspec

# 创建复杂的布局
fig = plt.figure(figsize=(12, 8))
gs = gridspec.GridSpec(3, 3, figure=fig)

# 创建不同大小的子图
ax1 = fig.add_subplot(gs[0, :])  # 第一行整行
ax1.plot(np.random.randn(100))
ax1.set_title('第一行整行')

ax2 = fig.add_subplot(gs[1, :-1])  # 第二行前两列
ax2.scatter(np.random.randn(50), np.random.randn(50))
ax2.set_title('第二行前两列')

ax3 = fig.add_subplot(gs[1:, -1])  # 第二三行最后一列
ax3.hist(np.random.randn(1000), bins=30, orientation='horizontal')
ax3.set_title('第二三行最后一列')

ax4 = fig.add_subplot(gs[-1, 0])  # 第三行第一列
ax4.pie([30, 25, 20, 25], labels=['A', 'B', 'C', 'D'])
ax4.set_title('饼图')

ax5 = fig.add_subplot(gs[-1, -2])  # 第三行第二列
ax5.bar(['A', 'B', 'C', 'D'], [25, 30, 35, 20])
ax5.set_title('柱状图')

plt.tight_layout()
plt.show()

五、高级图表类型

5.1 特殊图表

python

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

# 饼图
sizes = [15, 30, 45, 10]
labels = ['A', 'B', 'C', 'D']
colors = ['#ff9999', '#66b3ff', '#99ff99', '#ffcc99']
axes[0, 0].pie(sizes, labels=labels, colors=colors, autopct='%1.1f%%', startangle=90)
axes[0, 0].set_title('饼图')

# 箱线图
data = [np.random.normal(0, std, 100) for std in range(1, 4)]
axes[0, 1].boxplot(data, labels=['数据集1', '数据集2', '数据集3'])
axes[0, 1].set_title('箱线图')

# 面积图
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
axes[1, 0].fill_between(x, y1, y2, alpha=0.3)
axes[1, 0].plot(x, y1, 'b-', linewidth=2)
axes[1, 0].plot(x, y2, 'r-', linewidth=2)
axes[1, 0].set_title('面积图')

# 等高线图
x = np.linspace(-5, 5, 100)
y = np.linspace(-5, 5, 100)
X, Y = np.meshgrid(x, y)
Z = np.sin(np.sqrt(X**2 + Y**2))
contour = axes[1, 1].contourf(X, Y, Z, 20, cmap='RdYlBu')
fig.colorbar(contour, ax=axes[1, 1])
axes[1, 1].set_title('等高线图')

plt.tight_layout()
plt.show()

5.2 3D图形

python

from mpl_toolkits.mplot3d import Axes3D

# 创建3D图形
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')

# 生成数据
x = np.linspace(-5, 5, 100)
y = np.linspace(-5, 5, 100)
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)
fig.colorbar(surf, ax=ax, shrink=0.5, aspect=5)

ax.set_xlabel('X轴')
ax.set_ylabel('Y轴')
ax.set_zlabel('Z轴')
ax.set_title('3D曲面图')

plt.show()

六、文本和注释

python

# 创建基础图形
fig, ax = plt.subplots(figsize=(10, 6))
x = np.linspace(0, 10, 100)
y = np.sin(x)

ax.plot(x, y, 'b-', linewidth=2, label='正弦波')

# 添加文本注释
ax.text(5, 0.5, '最大值区域', fontsize=12, 
        bbox=dict(boxstyle='round', facecolor='yellow', alpha=0.5))

# 添加箭头注释
ax.annotate('最小值点', xy=(7.5, -1), xytext=(8, 0.5),
            arrowprops=dict(arrowstyle='->', connectionstyle='arc3', color='red'),
            fontsize=12)

# 添加数学公式
ax.text(1, 0.8, r'$f(x) = \sin(x)$', fontsize=14)

# 设置坐标轴格式
ax.set_xlabel('时间 (s)', fontsize=12)
ax.set_ylabel('振幅', fontsize=12)
ax.set_title('带注释的正弦波', fontsize=16)

ax.legend()
ax.grid(True, alpha=0.3)
plt.show()

七、实战案例:数据可视化分析

python

def data_visualization_analysis():
    # 创建模拟数据集
    np.random.seed(42)
    
    # 销售数据
    months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 
              'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
    sales_2023 = np.random.randint(100, 500, 12)
    sales_2024 = np.random.randint(150, 600, 12)
    
    # 用户评分分布
    ratings = np.random.normal(4.2, 0.5, 1000)
    
    # 产品占比
    products = ['电子产品', '服装', '食品', '图书', '其他']
    market_share = [35, 25, 20, 10, 10]
    
    # 创建仪表板
    fig = plt.figure(figsize=(15, 10))
    
    # 1. 月度销售对比(柱状图)
    ax1 = plt.subplot(2, 2, 1)
    x = np.arange(len(months))
    width = 0.35
    ax1.bar(x - width/2, sales_2023, width, label='2023', alpha=0.7)
    ax1.bar(x + width/2, sales_2024, width, label='2024', alpha=0.7)
    ax1.set_xlabel('月份')
    ax1.set_ylabel('销售额(万)')
    ax1.set_title('月度销售对比')
    ax1.set_xticks(x)
    ax1.set_xticklabels(months, rotation=45)
    ax1.legend()
    ax1.grid(True, alpha=0.3)
    
    # 2. 用户评分分布(直方图+密度曲线)
    ax2 = plt.subplot(2, 2, 2)
    ax2.hist(ratings, bins=30, density=True, alpha=0.7, edgecolor='black')
    ax2.set_xlabel('评分')
    ax2.set_ylabel('频率')
    ax2.set_title('用户评分分布')
    
    # 添加密度曲线
    from scipy.stats import gaussian_kde
    kde = gaussian_kde(ratings)
    x_range = np.linspace(min(ratings), max(ratings), 100)
    ax2.plot(x_range, kde(x_range), 'r-', linewidth=2)
    ax2.axvline(np.mean(ratings), color='green', linestyle='--', label='平均分')
    ax2.legend()
    ax2.grid(True, alpha=0.3)
    
    # 3. 产品市场份额(饼图)
    ax3 = plt.subplot(2, 2, 3)
    colors = ['#ff9999', '#66b3ff', '#99ff99', '#ffcc99', '#c2c2f0']
    explode = (0.1, 0, 0, 0, 0)  # 突出显示第一部分
    ax3.pie(market_share, labels=products, colors=colors, explode=explode,
            autopct='%1.1f%%', startangle=90)
    ax3.set_title('产品市场份额')
    
    # 4. 销售趋势(折线图)
    ax4 = plt.subplot(2, 2, 4)
    ax4.plot(months, sales_2023, 'b-o', label='2023', linewidth=2)
    ax4.plot(months, sales_2024, 'r-s', label='2024', linewidth=2)
    ax4.set_xlabel('月份')
    ax4.set_ylabel('销售额(万)')
    ax4.set_title('销售趋势分析')
    ax4.set_xticklabels(months, rotation=45)
    ax4.legend()
    ax4.grid(True, alpha=0.3)
    
    # 添加总标题
    plt.suptitle('2024年销售数据分析仪表板', fontsize=16, y=1.02)
    
    plt.tight_layout()
    plt.show()
    
    # 保存仪表板
    plt.savefig('sales_dashboard.png', dpi=300, bbox_inches='tight')

# 运行分析
data_visualization_analysis()

总结

Matplotlib的核心要点总结:

  1. 基础三步曲:创建图形和坐标轴 → 绘制数据 → 添加标签和样式

  2. 图形类型丰富:线图、散点图、柱状图、直方图、饼图、箱线图等

  3. 样式可定制:通过样式表、颜色、线型、标记等美化图表

  4. 布局灵活:使用subplot、GridSpec实现复杂布局

  5. 支持高级功能:3D绘图、数学公式、文本注释等

最佳实践建议

  • 从简单图形开始,逐步增加复杂度

  • 使用样式表保持图表风格一致

  • 添加足够的标签和标题提高可读性

  • 适当使用子图展示多维度数据

  • 及时保存高质量图表用于报告和展示

掌握Matplotlib后,您可以轻松创建专业级的数据可视化图表,为数据分析和报告提供有力支持。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐