最强总结!十大 Matplotlib 高级绘图技巧 !!

文摘   2024-09-30 14:26   北京  

哈喽,我是小白~

今儿和大家分享Matplotlib的一些高级技巧!~

在机器学习实验中,Matplotlib 的高级绘图技巧对于数据可视化非常的重要,因为它们能够有效地揭示数据之间的关系、分布和趋势,帮助大家快速识别模式和异常点。通过使用多种图形(如子图、散点图、箱线图等),可以清晰展示复杂的数据特征,提高数据分析的效率。

最终,良好的可视化不仅有助于模型选择和结果解释,还能够在与团队和利益相关者沟通时传达更具说服力的分析结果。

涉及到的重要的十个绘图技巧有:

  • 子图布局
  • 共享坐标轴
  • 自定义刻度和网格
  • 使用对数坐标
  • 添加注释
  • 彩色映射
  • 三维绘图
  • 双坐标轴
  • 热力图
  • 自定义图形风格

下面,每个部分做更详细的解释,确保每个技巧都深入讲解,并给大家带有完整代码示例。

1. 子图布局(Subplots Layout)

在可视化多维数据时,你可能希望在同一个窗口中展示多个图表进行对比。这时,使用 plt.subplots() 可以非常轻松地实现多子图布局。你可以灵活控制每个子图的大小、位置,甚至每个子图中的内容。

实现方式

  • plt.subplots(nrows, ncols):创建一个包含 nrows 行和 ncols 列的子图网格。
  • fig 表示整个图形对象(图形容器),axs 是子图对象数组(可以是多维数组)。
  • 使用 axs[row, col] 来访问某个特定子图。

Python 示例

import matplotlib.pyplot as plt
import numpy as np

# 生成数据
x = np.linspace(010100)
y1 = np.sin(x)
y2 = np.cos(x)
y3 = np.tan(x)
y4 = np.exp(x / 3)

# 创建 2x2 的子图布局
fig, axs = plt.subplots(22, figsize=(128))

# 第一个子图
axs[00].plot(x, y1, 'r', label='sin(x)')
axs[00].set_title('Sine Wave')
axs[00].legend()

# 第二个子图
axs[01].plot(x, y2, 'g', label='cos(x)')
axs[01].set_title('Cosine Wave')
axs[01].legend()

# 第三个子图
axs[10].plot(x, y3, 'b', label='tan(x)')
axs[10].set_title('Tangent Wave')
axs[10].legend()

# 第四个子图
axs[11].plot(x, y4, 'm', label='exp(x/3)')
axs[11].set_title('Exponential Function')
axs[11].legend()

# 调整布局
plt.tight_layout()
plt.show()
  • figsize=(12, 8):调整整个画布的大小,确保每个子图有足够的显示空间。
  • plt.tight_layout():自动调整子图间的间距,避免标签、标题等重叠。

2. 共享坐标轴 (Shared Axes)

当绘制多张图时,常常希望图表共享同一个坐标轴,以便方便对比。这种情况下,可以使用 sharex 或 sharey 参数来实现不同子图共享 X 轴或 Y 轴。

实现方式

plt.subplots(nrows, ncols, sharex=True, sharey=True):子图共享同一个 X 轴或 Y 轴。

Python 示例

import matplotlib.pyplot as plt
import numpy as np

# 生成数据
x = np.linspace(010100)
y1 = np.sin(x)
y2 = np.cos(x)

# 创建共享X轴的子图
fig, axs = plt.subplots(21, figsize=(86), sharex=True)

# 上图
axs[0].plot(x, y1, 'r', label='sin(x)')
axs[0].set_title('Sine Wave')
axs[0].legend()

# 下图
axs[1].plot(x, y2, 'b', label='cos(x)')
axs[1].set_title('Cosine Wave')
axs[1].legend()

# 设置共享的x轴标签
plt.xlabel('X Axis')
plt.tight_layout()
plt.show()
  • sharex=True:两个子图共享 X 轴,方便对比。
  • 同样可以设置 sharey=True 来共享 Y 轴。

3. 自定义刻度和网格 (Custom Ticks and Grids)

默认的刻度和网格线可能并不适合所有数据。通过自定义,可以让图表变得更清晰和专业。

实现方式

  • ax.set_xticks() 和 ax.set_yticks() 用于设置 X 轴和 Y 轴刻度。
  • ax.grid() 控制网格线的显示。

Python 示例

import matplotlib.pyplot as plt
import numpy as np

# 生成数据
x = np.linspace(010100)
y = np.sin(x)

fig, ax = plt.subplots(figsize=(86))

# 绘制基本图形
ax.plot(x, y)

# 自定义 X 轴刻度和网格
ax.set_xticks([0246810])
ax.set_xticklabels(['Zero''Two''Four''Six''Eight''Ten'], fontsize=12)

# 设置网格线
ax.grid(True, which='both', linestyle='--', linewidth=0.7)

plt.show()
  • set_xticks:设置自定义 X 轴刻度位置。
  • set_xticklabels:为 X 轴刻度设置标签。
  • grid(True, which='both'):显示主、副网格线,linestyle 设置网格线样式。

4. 使用对数坐标 (Logarithmic Scales)

对于指数增长或幂律分布的数据,线性坐标系可能无法准确显示趋势。对数坐标可以让变化更为直观。

实现方式

  • 使用 ax.set_xscale('log') 或 ax.set_yscale('log') 来设置对数坐标。

Python 示例

# 生成数据
x = np.linspace(11000100)
y = x ** 2

fig, ax = plt.subplots(figsize=(86))

# 绘制对数坐标图
ax.plot(x, y)
ax.set_xscale('log')
ax.set_yscale('log')

# 设置标签
ax.set_xlabel('Log X')
ax.set_ylabel('Log Y')

plt.show()
  • set_xscale('log'):X 轴使用对数坐标。
  • set_yscale('log'):Y 轴使用对数坐标。适用于处理大范围数值。

5. 添加注释 (Annotations)

在展示复杂数据时,添加注释可以突出某些关键点,帮助观众更好地理解图表。

实现方式

  • 使用 ax.annotate() 函数在图中标注特定位置的注释信息。

Python 示例

# 生成数据
x = np.linspace(010100)
y = np.sin(x)

fig, ax = plt.subplots(figsize=(86))

# 绘制基本图形
ax.plot(x, y)

# 添加注释
ax.annotate('Local Max', xy=(1.571), xytext=(31.5),
            arrowprops=dict(facecolor='black', shrink=0.05))

plt.show()
  • annotate('text', xy=(x, y), xytext=(x_text, y_text)):在 xy 坐标处添加注释,xytext 为文本的实际位置。
  • arrowprops 设置箭头样式。

6. 彩色映射 (Colormaps)

在展示多维数据时,使用彩色映射(colormap)可以通过颜色强度来表示数据的不同取值。

实现方式

  • 使用 plt.scatter() 或 plt.imshow() 并结合 cmap 参数来应用彩色映射。

Python 示例

# 生成数据
x = np.random.randn(1000)
y = np.random.randn(1000)
colors = np.sqrt(x**2 + y**2)

# 使用彩色映射绘制散点图
plt.scatter(x, y, c=colors, cmap='viridis', s=50)
plt.colorbar()  # 显示色条
plt.show()
  • cmap='viridis':使用预定义的彩色映射方案(如 'viridis')。
  • colorbar():添加颜色条,表示数值对应的颜色强度。

7. 三维绘图 (3D Plotting)

Matplotlib 支持三维绘图,可以帮助可视化三维数据。

实现方式

  • 使用 mpl_toolkits.mplot3d 提供的 Axes3D 创建三维坐标系。

Python 示例

from mpl_toolkits.mplot3d import Axes3D

# 生成数据
x = np.linspace(-55100)
y = np.linspace(-55100)
X

, Y = np.meshgrid(x, y)
Z = np.sin(np.sqrt(X**2 + Y**2))

fig = plt.figure(figsize=(107))
ax = fig.add_subplot(111, projection='3d')

# 绘制3D图形
ax.plot_surface(X, Y, Z, cmap='inferno')
plt.show()
  • projection='3d':指定三维绘图。
  • plot_surface() 绘制三维表面,cmap 用于控制颜色映射。

8. 双坐标轴 (Twin Axes)

有时你可能需要在同一张图中展示两组不同单位的数据,双坐标轴可以有效解决这个问题。

实现方式

  • 使用 ax.twinx() 创建第二个 Y 轴。

Python 示例

x = np.linspace(010100)
y1 = np.sin(x)
y2 = np.log(x + 1)

fig, ax1 = plt.subplots()

# 第一个坐标轴
ax1.plot(x, y1, 'g-')
ax1.set_ylabel('sin(x)', color='g')

# 第二个坐标轴
ax2 = ax1.twinx()
ax2.plot(x, y2, 'b-')
ax2.set_ylabel('log(x+1)', color='b')

plt.show()
  • ax.twinx():创建第二个 Y 轴,适合对比两组不同单位的数据。

9. 热力图 (Heatmaps)

热力图是一种非常直观的二维数据展示方式,通常用于相关性分析或矩阵数据可视化。

实现方式

  • 使用 plt.imshow() 来绘制二维矩阵的热力图。

Python 示例

data = np.random.rand(1010)

plt.imshow(data, cmap='hot', interpolation='nearest')
plt.colorbar()
plt.show()
  • imshow():直接绘制二维数据的热力图。
  • cmap='hot':指定热力图的颜色映射方案。

10. 自定义图形风格 (Custom Styles)

Matplotlib 提供了一些预设风格,比如 seaborn 或 ggplot 风格,你可以根据需要自定义图形的整体风格,让图表更美观。

实现方式

  • 使用 plt.style.use() 来应用不同的风格。

Python 示例

plt.style.use('seaborn-darkgrid')

# 生成数据
x = np.linspace(010100)
y = np.sin(x)

plt.plot(x, y)
plt.show()
  • plt.style.use():应用预定义的绘图风格(如 seaborn-darkgrid)。

下面,咱们实现一个比较综合的案例,展示多个图形(折线图、散点图、直方图和箱线图),并结合颜色映射和共享轴的技巧。此案例适合用于同时分析多个特征之间的关系,揭示不同变量的分布、趋势和异常点。

案例描述:

我们将创建一个虚拟数据集,其中包含三组不同的数据:

  • A:具有正态分布的随机数,表示某个特征的测量值。
  • B:通过对 A 进行一些变换得到,表示另一个相关特征。
  • C:随机生成的离散类别数据,用于展示离散变量的分布。

在这个图中,我们将通过以下图形展示不同特征之间的关系:

  1. 折线图展示特征 A 和 B 之间的关系。
  2. 散点图展示特征 B 和 A 之间的相关性,同时用颜色区分不同类别。
  3. 直方图展示特征 A 和 B 的分布。
  4. 箱线图展示不同类别的数据分布和离群点。

完整 Python 代码:

import matplotlib.pyplot as plt
import numpy as np

# 生成虚拟数据集
np.random.seed(42)
n = 1000
A = np.random.normal(loc=50, scale=10, size=n)  # 特征 A,正态分布
B = A + np.random.normal(loc=0, scale=5, size=n)  # 特征 B,与 A 相关联
C = np.random.randint(03, size=n)  # 特征 C,离散类别数据 (0, 1, 2)

# 创建一个图形,包含 2x2 的子图布局
fig, axs = plt.subplots(22, figsize=(1210))
fig.suptitle('Data Analysis: Feature A, B, and C', fontsize=16)

# 子图 1: A 和 B 的折线图
axs[00].plot(A, label='Feature A', color='red', linewidth=2)
axs[00].plot(B, label='Feature B', color='blue', linestyle='--', linewidth=2)
axs[00].set_title('Line Plot of Feature A and B')
axs[00].set_xlabel('Index')
axs[00].set_ylabel('Value')
axs[00].legend()
axs[00].grid(True)

# 子图 2: A 和 B 的散点图,C 作为颜色映射
scatter = axs[01].scatter(A, B, c=C, cmap='plasma', s=100, edgecolor='k', alpha=0.8)
axs[01].set_title('Scatter Plot of Feature A vs Feature B (Colored by Feature C)')
axs[01].set_xlabel('Feature A')
axs[01].set_ylabel('Feature B')
# 添加颜色条
cbar = fig.colorbar(scatter, ax=axs[01])
cbar.set_label('Feature C Categories')

# 子图 3: A 和 B 的直方图
axs[10].hist(A, bins=15, color='green', alpha=0.7, label='Feature A')
axs[10].hist(B, bins=15, color='orange', alpha=0.7, label='Feature B')
axs[10].set_title('Histogram of Feature A and B')
axs[10].set_xlabel('Value')
axs[10].set_ylabel('Frequency')
axs[10].legend()
axs[10].grid(True)

# 子图 4: 箱线图,展示不同类别 C 的数据分布 (针对 A 和 B)
axs[11].boxplot([A[C == 0], A[C == 1], A[C == 2]], positions=[123], widths=0.6, patch_artist=True,
                  boxprops=dict(facecolor='cyan', color='black'),
                  medianprops=dict(color='black'))
axs[11].boxplot([B[C == 0], B[C == 1], B[C == 2]], positions=[456], widths=0.6, patch_artist=True,
                  boxprops=dict(facecolor='pink', color='black'),
                  medianprops=dict(color='black'))
axs[11].set_title('Boxplot of Feature A and B Grouped by Feature C')
axs[11].set_xticks([1.54.5])
axs[11].set_xticklabels(['Feature A''Feature B'])
axs[11].set_ylabel('Value')

# 调整子图之间的布局
plt.tight_layout(rect=[0010.95])

# 显示图形
plt.show()

虚拟数据集

  • A 是一个正态分布的随机数据,代表特征 A。
  • B 是基于 A 的变换(加上噪声),代表另一个相关特征 B。
  • C 是一个离散的类别数据,取值为 0、1 和 2。

  • 折线图:展示特征 A 和 B 的随时间变化的趋势,红色表示 A,蓝色虚线表示 B。该图可以帮助观察两个特征之间的变化趋势,特别是它们的相关性。
  • 散点图:A 和 B 的相关性,用颜色区分不同的类别(C),并通过颜色条解释类别信息。图中颜色的变化可以帮助我们识别不同类别之间的分布差异。
  • 直方图:显示 A 和 B 的频率分布,绿色表示 A,橙色表示 B。该图帮助我们理解两个特征的分布形态及其重叠部分。
  • 箱线图:展示不同类别的 A 和 B 的分布,帮助我们发现不同类别的特征分布差异,并识别潜在的离群点。

其中:

  • 特征 A 和 B 之间的相关性:从折线图和散点图可以观察到特征 A 和 B 之间的强相关性,虽然 B 带有噪声,但总体趋势与 A 非常相似。
  • 类别 C 对 A 和 B 的影响:散点图通过颜色展示了不同类别的数据分布情况,可以看到不同类别的数据分布在 A 和 B 上有一定差异。箱线图进一步揭示了这些类别的分布差异以及可能的离群点。
  • 特征 A 和 B 的分布:直方图帮助我们理解特征 A 和 B 的分布形态,从中可以看到两者的分布范围和频率。

这个案例展示了如何通过多种图形方式对数据进行深入分析,适合用于多维数据的探索性分析(EDA)。

最后

以上就是今天所有的内容了。
如果对你来说比较有用,记得点赞、收藏,慢慢学习~
下期会有更多干货等着你!~


Python和机器学习初学者
Python和机器学习分享,只写干货,一起学习~
 最新文章