目录

前言

一、 子图布局(Subplot):一图胜千言

二、 散点图(Scatter Plot):探索变量关系

三、 直方图(Histogram):洞察数据分布

四、 箱线图(Box Plot):识别异常值

五、 热力图(Heatmap):展示矩阵数据

六、 特殊坐标系:极坐标图

七、 空间与地形可视化:等高线与填充图

八、 真正的三维绘图(3D Plotting)

九、 极坐标图:雷达图

十、 高级技巧:双Y轴

总结


前言

在学习了 matplotlib 的基础折线图、散点图后,你是否想让你的数据可视化更具表现力和专业度?本文将带你深入 matplotlib 的“军火库”,解锁几种高级图形的绘制方法和核心知识点,让你的图表瞬间脱颖而出。

一、 子图布局(Subplot):一图胜千言

当我们需要对比多个相关图表时,将它们放在同一个画布(Figure)上是非常有效的方式。
核心知识点:
1.plt.subplots():这是创建子图最推荐的方法。它会一次性创建一个画布(fig)和一个包含所有子图轴(ax)的数组。
2.figsize:设置整个画布的大小,单位是英寸。
3.sharex / sharey:设置为 True 可以让子图共享 X 轴或 Y 轴,方便对比。

代码示例:

import matplotlib.pyplot as plt
import numpy as np

# 设置中文字体,避免中文乱码
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 创建数据
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
y3 = np.tan(x)

# 创建 3 行 1 列的子图,共享 X 轴
fig, axs = plt.subplots(3, 1, figsize=(10, 8), sharex=True)

# 在第一个子图上绘图
axs[0].plot(x, y1, 'r-', label='sin(x)')
axs[0].set_title('正弦函数')
axs[0].legend()
axs[0].grid(True)

# 在第二个子图上绘图
axs[1].plot(x, y2, 'g--', label='cos(x)')
axs[1].set_title('余弦函数')
axs[1].legend()
axs[1].grid(True)

# 在第三个子图上绘图
axs[2].plot(x, y3, 'b:', label='tan(x)')
axs[2].set_title('正切函数')
axs[2].set_xlabel('X 轴')
axs[2].legend()
axs[2].grid(True)
axs[2].set_ylim(-3, 3)  # 限制Y轴范围,避免正切函数值过大

# 自动调整子图间距
plt.tight_layout()
plt.show()

二、 散点图(Scatter Plot):探索变量关系

散点图是探索两个变量之间关系的利器,尤其适合展示数据的分布和相关性。
核心知识点:
1.plt.scatter():与 plt.plot() 不同,scatter 可以对每个点进行更精细的控制。
2.c 参数:可以是一个颜色,也可以是一个数据数组,用于根据数值大小映射颜色(颜色条)。
3.s 参数:控制点的大小,也可以是一个数组,实现“气泡图”效果。
4.alpha 参数:设置透明度,用于处理数据点重叠严重的情况。

代码示例:

import matplotlib.pyplot as plt
import numpy as np

# 创建随机数据
np.random.seed(0)
x = np.random.randn(100)
y = np.random.randn(100)
colors = np.random.rand(100)  # 用于颜色映射
sizes = 1000 * np.random.rand(100)  # 用于点的大小

plt.figure(figsize=(8, 6))
scatter = plt.scatter(x, y, c=colors, s=sizes, alpha=0.6, cmap='viridis')

plt.title('高级散点图示例')
plt.xlabel('X 变量')
plt.ylabel('Y 变量')

# 添加颜色条
plt.colorbar(scatter, label='颜色映射值')

plt.show()

三、 直方图(Histogram):洞察数据分布

直方图用于展示连续变量的频率分布,是数据分析中不可或缺的工具。
核心知识点:
1.plt.hist():绘制直方图。
2.bins 参数:控制柱子的数量或具体的分组边界。bins 越多,柱子越细。
3.density 参数:如果设置为 True,Y 轴将显示概率密度而不是频数,所有柱子的面积之和为 1。
4.alpha 和 label:方便在同一张图上叠加多个直方图进行对比。

代码示例:

import matplotlib.pyplot as plt
import numpy as np

# 创建两组正态分布数据
data1 = np.random.randn(1000) * 2 + 5  # 均值为5,标准差为2
data2 = np.random.randn(1000) * 1.5 + 3  # 均值为3,标准差为1.5

plt.figure(figsize=(10, 6))

# 绘制两个重叠的直方图
plt.hist(data1, bins=30, alpha=0.5, label='数据集 A', color='blue', edgecolor='black')
plt.hist(data2, bins=30, alpha=0.5, label='数据集 B', color='red', edgecolor='black')

plt.title('数据分布对比直方图')
plt.xlabel('数值')
plt.ylabel('频数')
plt.legend()
plt.grid(axis='y', alpha=0.75)

plt.show()

四、 箱线图(Box Plot):识别异常值

箱线图能直观地展示数据的五数概括(最小值、下四分位数、中位数、上四分位数、最大值)以及异常值。
核心知识点:
1.plt.boxplot():绘制箱线图。
2.箱体(Box):中间的盒子代表了 50% 的数据(从 25% 分位数到 75% 分位数)。
3.中位线(Median):箱体内的横线是中位数。
4.须(Whiskers):箱体外的线通常延伸到 1.5 倍 IQR(四分位距)范围内的最大/最小值。
5.异常值(Fliers):超出“须”范围的点会被单独标出。

代码示例:

import matplotlib.pyplot as plt
import numpy as np

# 创建三组数据
data = [np.random.normal(0, std, 100) for std in [1, 2, 3]]

plt.figure(figsize=(8, 6))

# 绘制箱线图
plt.boxplot(data, notch=True, patch_artist=True,
            labels=['组 A', '组 B', '组 C'],
            boxprops=dict(facecolor='lightblue'))

plt.title('数据分布箱线图')
plt.ylabel('数值')
plt.grid(axis='y', alpha=0.75)

plt.show()

五、 热力图(Heatmap):展示矩阵数据

热力图通过颜色深浅来表示二维数据矩阵中数值的大小,非常适合展示相关性矩阵或地理数据。
核心知识点:
1.plt.imshow() 或 plt.pcolormesh():都可以用来绘制热力图,imshow 更常用。
2.cmap 参数:颜色映射表,如 'hot', 'cool', 'viridis', 'RdYlGn' 等。
3.plt.colorbar():添加颜色条,解释颜色与数值的对应关系。

代码示例:

import matplotlib.pyplot as plt
import numpy as np

# 创建一个 10x10 的随机矩阵
data = np.random.rand(10, 10)

plt.figure(figsize=(8, 6))

# 使用 imshow 绘制热力图
heatmap = plt.imshow(data, cmap='hot', interpolation='nearest')

plt.title('随机矩阵热力图')
plt.xlabel('列')
plt.ylabel('行')

# 添加颜色条
plt.colorbar(heatmap, label='数值大小')

plt.show()

六、 特殊坐标系:极坐标图

除了常见的直角坐标系(X-Y轴),Matplotlib 还支持极坐标系,常用于绘制雷达图或玫瑰图。
核心知识点:
1.projection='polar':在创建子图时指定投影方式为极坐标。
2.theta:角度(弧度制)。
3.r:半径(距离圆心的距离)。
代码示例(玫瑰图):

import matplotlib.pyplot as plt
import numpy as np

plt.figure(figsize=(6, 6))
ax = plt.subplot(111, projection='polar')

# 生成数据
N = 20
theta = np.linspace(0.0, 2 * np.pi, N, endpoint=False)
radii = 10 * np.random.rand(N)
width = np.pi / 4 * np.random.rand(N) # 扇形的宽度

# 绘制柱状图
bars = ax.bar(theta, radii, width=width, bottom=0.0, alpha=0.7)

# 根据高度设置颜色
for r, bar in zip(radii, bars):
    bar.set_facecolor(plt.cm.viridis(r / 10))

plt.title('极坐标玫瑰图示例', y=1.1)
plt.show()

七、 空间与地形可视化:等高线与填充图

当你需要展示三维地形(如海拔)在二维平面上的分布时,等高线图是必不可少的。
1.plt.contour():绘制线条形式的等高线。
2.plt.contourf():绘制填充颜色的等高线(f 代表 filled),视觉效果更震撼。
3.np.meshgrid():这是一个关键知识点。为了绘制 3D 表面,我们需要将 x 和 y 的一维数组转换为坐标矩阵。

代码示例:

import matplotlib.pyplot as plt
import numpy as np

# 1. 创建网格数据
x = np.linspace(-5, 5, 100)
y = np.linspace(-5, 5, 100)
X, Y = np.meshgrid(x, y) # 核心:生成坐标矩阵

# 2. 定义一个复杂的函数 Z (例如:双曲抛物面)
Z = np.sin(np.sqrt(X**2 + Y**2))

plt.figure(figsize=(8, 6))

# 3. 绘制填充等高线图
# cmap='RdYlBu_r' 设置红黄蓝反转色系,levels设置等高线的层数
contour = plt.contourf(X, Y, Z, levels=20, cmap='RdYlBu_r')

# 4. 叠加一层黑色线条等高线,增加立体感
plt.contour(X, Y, Z, levels=20, colors='black', linewidths=0.5)

plt.colorbar(contour, label='高度 Z')
plt.title('高级地形可视化:填充等高线图')
plt.xlabel('X 轴')
plt.ylabel('Y 轴')
plt.show()

八、 真正的三维绘图(3D Plotting)

Matplotlib 其实内置了一个 mplot3d 工具包,可以直接绘制 3D 图形。这在展示函数曲面时非常有用。
1.核心知识点:projection='3d'。
2.常用图形:3D 散点图、3D 曲面图、3D 柱状图。

代码示例:

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D # 必须导入这个才能激活3D绘图
import numpy as np

fig = plt.figure(figsize=(10, 7))
ax = fig.add_subplot(111, projection='3d') # 开启3D投影

# 生成数据
x = np.random.standard_normal(100)
y = np.random.standard_normal(100)
z = np.random.standard_normal(100)

# 绘制 3D 散点图
# c=z 表示颜色随Z轴变化,cmap='viridis'是配色方案
sc = ax.scatter(x, y, z, c=z, cmap='viridis', marker='o', s=50)

ax.set_title('3D 散点图展示')
ax.set_xlabel('X轴')
ax.set_ylabel('Y轴')
ax.set_zlabel('Z轴')

# 添加颜色条
fig.colorbar(sc)
plt.show()

九、 极坐标图:雷达图

雷达图(Radar Chart)常用于展示多维数据(如球员能力值、产品各项性能评分)。它本质上是在极坐标系下绘制的折线图。
1.核心知识点:polar=True。
2.技巧:为了让雷达图闭合,数据的首尾必须相连。

代码示例:

import matplotlib.pyplot as plt
import numpy as np

# 1. 准备数据 (5个维度:攻击、防御、速度、技巧、耐力)
labels = np.array(['攻击', '防御', '速度', '技巧', '耐力'])
stats = np.array([8, 5, 7, 9, 6])

# 为了闭合图形,需要将第一个数据拼接到最后
angles = np.linspace(0, 2 * np.pi, len(labels), endpoint=False).tolist()
stats = np.concatenate((stats,[stats[0]]))
angles += angles[:1]

fig, ax = plt.subplots(figsize=(6, 6), subplot_kw=dict(polar=True))

# 2. 绘图
ax.plot(angles, stats, linewidth=2, linestyle='solid', label='选手A')
ax.fill(angles, stats, color='red', alpha=0.25) # 填充颜色

# 3. 设置标签
ax.set_xticks(angles[:-1])
ax.set_xticklabels(labels, fontsize=12)

plt.title('选手能力雷达图', size=20, y=1.1)
plt.legend(loc='upper right', bbox_to_anchor=(1.3, 1.0))
plt.show()

十、 高级技巧:双Y轴

当你在同一张图上需要对比两个量纲完全不同的数据时(例如:气温和降雨量,或者股价和成交量),双Y轴是标准解决方案。
1.核心方法:ax.twinx()。这会创建一个共享 X 轴但拥有独立 Y 轴的“镜像”坐标轴。

代码示例:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y1 = np.sin(x) * 100  # 数据1:数值较大
y2 = np.cos(x)        # 数据2:数值较小 (-1到1)

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

# 绘制第一条线 (左边Y轴)
color = 'tab:red'
ax1.set_xlabel('时间')
ax1.set_ylabel('销售额 (万元)', color=color)
ax1.plot(x, y1, color=color, linewidth=2, label='销售额')
ax1.tick_params(axis='y', labelcolor=color)

# 创建共享X轴的第二个Y轴
ax2 = ax1.twinx()
color = 'tab:blue'
ax2.set_ylabel('满意度评分', color=color)
ax2.plot(x, y2, color=color, linestyle='--', linewidth=2, label='满意度')
ax2.tick_params(axis='y', labelcolor=color)

plt.title('双Y轴:销售额与满意度对比')
fig.tight_layout() # 自动调整布局防止遮挡
plt.show()

总结

这篇文章我们从基础的子图布局开始,进阶到展示多维数据,深入统计学的直方图与箱线图,最后挑战了3D绘图、等高线、雷达图以及双Y轴技术。
掌握这些图形,你将不再受限于简单的 Excel 图表,能够应对绝大多数复杂的科研和商业数据可视化需求。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐