Matplotlib 色彩映射:掌握 get_cmap 函数的使用技巧
参考:matplotlib colormaps get_cmap
Matplotlib 是 Python 中最流行的数据可视化库之一,它提供了丰富的绘图功能和自定义选项。在数据可视化中,色彩映射(colormap)是一个非常重要的概念,它可以帮助我们更好地展示数据的分布和变化。本文将深入探讨 Matplotlib 中的色彩映射,特别是 get_cmap
函数的使用方法和技巧。
1. 色彩映射的基本概念
色彩映射是将数值数据映射到颜色的过程。在 Matplotlib 中,色彩映射通常用于表示连续数据的变化,如热图、等高线图或散点图中的第三个维度。Matplotlib 提供了多种预定义的色彩映射,同时也允许用户自定义色彩映射。
1.1 内置色彩映射
Matplotlib 提供了许多内置的色彩映射,可以通过 plt.colormaps()
函数查看所有可用的色彩映射名称。以下是一个简单的示例,展示如何查看和使用内置色彩映射:
import matplotlib.pyplot as plt
import numpy as np
# 创建一个简单的数据集
data = np.random.rand(10, 10)
# 使用 'viridis' 色彩映射绘制热图
plt.imshow(data, cmap='viridis')
plt.colorbar()
plt.title('How2matplotlib.com - Viridis Colormap Example')
plt.show()
Output:
在这个例子中,我们使用 imshow
函数绘制了一个热图,并指定了 ‘viridis’ 色彩映射。’viridis’ 是 Matplotlib 的默认色彩映射之一,它在感知上是均匀的,对色盲友好,并且在黑白打印时也能保持良好的可读性。
1.2 get_cmap 函数简介
get_cmap
函数是 Matplotlib 中用于获取色彩映射对象的关键函数。它可以接受色彩映射的名称作为参数,返回相应的色彩映射对象。这个函数非常有用,因为它允许我们在代码中动态地选择和使用不同的色彩映射。
以下是一个使用 get_cmap
函数的简单示例:
import matplotlib.pyplot as plt
import numpy as np
# 创建一个简单的数据集
x = np.linspace(0, 10, 100)
y = np.sin(x)
# 使用 get_cmap 获取 'cool' 色彩映射
cmap = plt.get_cmap('cool')
# 使用 cool 色彩映射绘制彩色线条
plt.scatter(x, y, c=y, cmap=cmap)
plt.colorbar()
plt.title('How2matplotlib.com - Cool Colormap Example')
plt.show()
Output:
在这个例子中,我们使用 get_cmap('cool')
获取了 ‘cool’ 色彩映射,然后将其应用到散点图中。散点的颜色根据 y 值的大小进行映射,形成了一个从蓝色到紫色的渐变效果。
2. get_cmap 函数的高级用法
get_cmap
函数不仅可以获取预定义的色彩映射,还可以用于创建自定义的色彩映射。以下我们将探讨 get_cmap
函数的一些高级用法。
2.1 反转色彩映射
有时我们可能需要反转色彩映射的顺序。Matplotlib 允许我们通过在色彩映射名称后添加 ‘_r’ 后缀来实现这一点。例如:
import matplotlib.pyplot as plt
import numpy as np
# 创建数据
x = np.linspace(0, 10, 100)
y = np.sin(x)
# 获取原始和反转的 'plasma' 色彩映射
cmap_original = plt.get_cmap('plasma')
cmap_reversed = plt.get_cmap('plasma_r')
# 创建子图
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
# 绘制原始色彩映射
scatter1 = ax1.scatter(x, y, c=y, cmap=cmap_original)
ax1.set_title('How2matplotlib.com - Original Plasma')
plt.colorbar(scatter1, ax=ax1)
# 绘制反转色彩映射
scatter2 = ax2.scatter(x, y, c=y, cmap=cmap_reversed)
ax2.set_title('How2matplotlib.com - Reversed Plasma')
plt.colorbar(scatter2, ax=ax2)
plt.tight_layout()
plt.show()
Output:
这个例子展示了如何使用原始的 ‘plasma’ 色彩映射和其反转版本 ‘plasma_r’。通过比较两个子图,我们可以清楚地看到色彩映射反转的效果。
2.2 限制色彩映射的范围
有时我们可能只需要使用色彩映射的一部分。get_cmap
函数允许我们通过传递一个额外的参数来限制色彩映射的范围。这个参数是一个 0 到 1 之间的浮点数,表示我们想要使用的色彩映射的比例。
import matplotlib.pyplot as plt
import numpy as np
# 创建数据
x = np.linspace(0, 10, 100)
y = np.sin(x)
# 获取完整的 'viridis' 色彩映射和其中间 50% 的部分
cmap_full = plt.get_cmap('viridis')
cmap_partial = plt.get_cmap('viridis', 50)
# 创建子图
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
# 绘制完整色彩映射
scatter1 = ax1.scatter(x, y, c=y, cmap=cmap_full)
ax1.set_title('How2matplotlib.com - Full Viridis')
plt.colorbar(scatter1, ax=ax1)
# 绘制部分色彩映射
scatter2 = ax2.scatter(x, y, c=y, cmap=cmap_partial)
ax2.set_title('How2matplotlib.com - Partial Viridis')
plt.colorbar(scatter2, ax=ax2)
plt.tight_layout()
plt.show()
Output:
在这个例子中,我们使用 plt.get_cmap('viridis', 50)
获取了 ‘viridis’ 色彩映射的中间 50% 部分。这种技术在你只需要色彩映射的一部分,或者想要突出显示某个特定范围的数据时非常有用。
2.3 创建离散色彩映射
虽然色彩映射通常用于连续数据,但有时我们可能需要将其应用于离散数据。我们可以使用 get_cmap
函数和 BoundaryNorm
类来创建离散的色彩映射:
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import BoundaryNorm
# 创建数据
x = np.linspace(0, 10, 100)
y = np.sin(x)
# 定义离散区间
bounds = [-1, -0.5, 0, 0.5, 1]
norm = BoundaryNorm(bounds, plt.get_cmap('RdYlBu').N)
# 创建图形
plt.figure(figsize=(10, 6))
scatter = plt.scatter(x, y, c=y, cmap='RdYlBu', norm=norm)
plt.colorbar(scatter, boundaries=bounds, ticks=bounds)
plt.title('How2matplotlib.com - Discrete Colormap Example')
plt.show()
Output:
在这个例子中,我们使用 BoundaryNorm
类定义了四个离散的颜色区间。这样,数据点的颜色将根据其所在的区间而不是连续的值来确定。这种技术在你想要将数据分类或强调特定阈值时非常有用。
3. 自定义色彩映射
除了使用预定义的色彩映射,Matplotlib 还允许我们创建自定义的色彩映射。这在我们需要特定的颜色方案或想要精确控制颜色变化时非常有用。
3.1 使用 LinearSegmentedColormap 创建自定义色彩映射
LinearSegmentedColormap
类允许我们通过定义颜色锚点来创建自定义的色彩映射。以下是一个创建简单的红绿渐变色彩映射的例子:
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import LinearSegmentedColormap
# 定义颜色锚点
colors = ['red', 'green']
n_bins = 100 # 颜色数量
cmap_name = 'red_green'
# 创建自定义色彩映射
cm = LinearSegmentedColormap.from_list(cmap_name, colors, N=n_bins)
# 创建数据
x = np.linspace(0, 10, 100)
y = np.sin(x)
# 绘图
plt.figure(figsize=(10, 6))
scatter = plt.scatter(x, y, c=y, cmap=cm)
plt.colorbar(scatter)
plt.title('How2matplotlib.com - Custom Red-Green Colormap')
plt.show()
Output:
在这个例子中,我们创建了一个从红色到绿色的渐变色彩映射。通过调整颜色锚点和 n_bins
参数,我们可以精确控制色彩映射的外观。
3.2 使用 ListedColormap 创建离散色彩映射
如果我们需要一个完全离散的色彩映射,可以使用 ListedColormap
类。这在处理分类数据时特别有用:
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import ListedColormap
# 定义离散颜色列表
colors = ['red', 'green', 'blue', 'yellow']
cmap_name = 'discrete_colors'
# 创建离散色彩映射
cm = ListedColormap(colors, name=cmap_name)
# 创建示例数据
data = np.random.randint(0, 4, (10, 10))
# 绘图
plt.figure(figsize=(10, 8))
plt.imshow(data, cmap=cm)
plt.colorbar(ticks=range(4), label='Categories')
plt.title('How2matplotlib.com - Discrete Colormap with ListedColormap')
plt.show()
Output:
这个例子创建了一个包含四种颜色的离散色彩映射,并将其应用到一个随机生成的整数数组上。这种方法非常适合表示不同类别或离散状态的数据。
4. 色彩映射的应用场景
色彩映射在数据可视化中有广泛的应用。以下我们将探讨一些常见的应用场景,并展示如何在这些场景中使用 get_cmap
函数。
4.1 热图(Heatmap)
热图是色彩映射最常见的应用之一,它可以直观地展示二维数据的分布情况:
import matplotlib.pyplot as plt
import numpy as np
# 创建示例数据
data = np.random.rand(20, 20)
# 创建热图
plt.figure(figsize=(10, 8))
heatmap = plt.imshow(data, cmap=plt.get_cmap('YlOrRd'))
plt.colorbar(heatmap)
plt.title('How2matplotlib.com - Heatmap Example')
plt.show()
Output:
在这个例子中,我们使用 get_cmap
函数获取了 ‘YlOrRd’(黄-橙-红)色彩映射,并将其应用到热图中。这种色彩映射非常适合表示从低到高的数值变化。
4.2 等高线图(Contour Plot)
等高线图用于展示三维表面的二维投影,色彩映射可以帮助我们更好地理解高度变化:
import matplotlib.pyplot as plt
import numpy as np
# 创建示例数据
x = np.linspace(-3, 3, 100)
y = np.linspace(-3, 3, 100)
X, Y = np.meshgrid(x, y)
Z = np.sin(X) * np.cos(Y)
# 创建等高线图
plt.figure(figsize=(10, 8))
contour = plt.contourf(X, Y, Z, cmap=plt.get_cmap('coolwarm'))
plt.colorbar(contour)
plt.title('How2matplotlib.com - Contour Plot Example')
plt.show()
Output:
这个例子使用 ‘coolwarm’ 色彩映射来表示等高线的高度。冷色调(蓝色)表示较低的值,暖色调(红色)表示较高的值,使得高度变化一目了然。
4.3 散点图中的第三维度
在二维散点图中,我们可以使用色彩映射来表示第三个维度的数据:
import matplotlib.pyplot as plt
import numpy as np
# 创建示例数据
n = 1000
x = np.random.randn(n)
y = np.random.randn(n)
z = x * y
# 创建散点图
plt.figure(figsize=(10, 8))
scatter = plt.scatter(x, y, c=z,cmap=plt.get_cmap('viridis'))
plt.colorbar(scatter)
plt.title('How2matplotlib.com - Scatter Plot with Color-coded Third Dimension')
plt.xlabel('X')
plt.ylabel('Y')
plt.show()
Output:
在这个例子中,我们使用 ‘viridis’ 色彩映射来表示散点的第三个维度(z 值)。这种方法可以在二维平面上有效地展示三维数据的分布情况。
5. 色彩映射的选择原则
选择合适的色彩映射对于有效地传达数据信息至关重要。以下是一些选择色彩映射时应考虑的原则:
5.1 数据类型
- 对于连续数据,选择渐变色彩映射,如 ‘viridis’、’plasma’ 或 ‘coolwarm’。
- 对于离散或分类数据,选择具有明显区分的色彩映射,如 ‘Set1’、’Set2’ 或自定义的离散色彩映射。
5.2 感知均匀性
选择在视觉上感知均匀的色彩映射,以避免对数据的错误解释。例如,’viridis’ 和 ‘plasma’ 是感知均匀的好选择。
5.3 色盲友好
考虑选择对色盲友好的色彩映射,如 ‘viridis’、’cividis’ 或 ‘magma’。这些色彩映射在不同类型的色盲下仍能保持良好的可区分性。
5.4 打印友好
如果你的可视化需要以黑白方式打印,选择在灰度下仍能保持良好对比度的色彩映射,如 ‘viridis’ 或 ‘gray’。
以下是一个比较不同色彩映射的示例:
import matplotlib.pyplot as plt
import numpy as np
# 创建示例数据
data = np.random.rand(10, 10)
# 定义要比较的色彩映射
cmaps = ['viridis', 'plasma', 'inferno', 'magma', 'cividis']
# 创建子图
fig, axes = plt.subplots(2, 3, figsize=(15, 10))
axes = axes.flatten()
# 绘制不同的色彩映射
for i, cmap_name in enumerate(cmaps):
cmap = plt.get_cmap(cmap_name)
im = axes[i].imshow(data, cmap=cmap)
axes[i].set_title(f'How2matplotlib.com - {cmap_name}')
plt.colorbar(im, ax=axes[i])
# 删除多余的子图
for i in range(len(cmaps), len(axes)):
fig.delaxes(axes[i])
plt.tight_layout()
plt.show()
Output:
这个例子展示了几种常用的色彩映射,可以帮助你比较它们的视觉效果并选择最适合你的数据的色彩映射。
6. 色彩映射的高级技巧
除了基本的使用方法,还有一些高级技巧可以帮助你更好地利用色彩映射。
6.1 组合多个色彩映射
有时,我们可能需要将多个色彩映射组合在一起,以创建更复杂的颜色方案:
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import LinearSegmentedColormap
# 定义两个色彩映射
cmap1 = plt.get_cmap('Blues')
cmap2 = plt.get_cmap('Reds')
# 组合色彩映射
colors1 = cmap1(np.linspace(0.2, 0.8, 128))
colors2 = cmap2(np.linspace(0.2, 0.8, 128))
colors = np.vstack((colors1, colors2))
combined_cmap = LinearSegmentedColormap.from_list('BluesReds', colors)
# 创建示例数据
data = np.random.randn(20, 20)
# 绘图
plt.figure(figsize=(10, 8))
im = plt.imshow(data, cmap=combined_cmap)
plt.colorbar(im)
plt.title('How2matplotlib.com - Combined Blues and Reds Colormap')
plt.show()
Output:
这个例子展示了如何将 ‘Blues’ 和 ‘Reds’ 两个色彩映射组合成一个新的色彩映射。这种技术可以用来创建更复杂的颜色方案,或者在一个图中表示两种不同类型的数据。
6.2 使用 LogNorm 处理对数数据
当处理跨越多个数量级的数据时,使用对数色彩映射可能会更有效:
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import LogNorm
# 创建示例数据(指数分布)
data = np.random.exponential(1, size=(20, 20))
# 创建图形
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 6))
# 线性色彩映射
im1 = ax1.imshow(data, cmap='viridis')
ax1.set_title('How2matplotlib.com - Linear Colormap')
plt.colorbar(im1, ax=ax1)
# 对数色彩映射
im2 = ax2.imshow(data, cmap='viridis', norm=LogNorm())
ax2.set_title('How2matplotlib.com - Logarithmic Colormap')
plt.colorbar(im2, ax=ax2)
plt.tight_layout()
plt.show()
Output:
这个例子比较了线性色彩映射和对数色彩映射在处理指数分布数据时的效果。对数色彩映射可以更好地展示跨越多个数量级的数据的细节。
6.3 使用 Diverging 色彩映射
对于既有正值又有负值的数据,使用发散色彩映射(Diverging Colormap)可以更好地展示数据的分布:
import matplotlib.pyplot as plt
import numpy as np
# 创建示例数据
x = np.linspace(-5, 5, 100)
y = np.linspace(-5, 5, 100)
X, Y = np.meshgrid(x, y)
Z = X * np.exp(-X**2 - Y**2)
# 创建图形
plt.figure(figsize=(10, 8))
im = plt.imshow(Z, cmap=plt.get_cmap('RdBu_r'), extent=[-5, 5, -5, 5])
plt.colorbar(im)
plt.title('How2matplotlib.com - Diverging Colormap Example')
plt.xlabel('X')
plt.ylabel('Y')
plt.show()
Output:
在这个例子中,我们使用 ‘RdBu_r’ 色彩映射(红-白-蓝的反转版本)来展示既有正值又有负值的数据。这种色彩映射可以清晰地显示数据的正负变化,中间的白色表示接近零的值。
7. 色彩映射的性能考虑
在处理大型数据集或需要频繁更新的可视化时,色彩映射的性能也是一个需要考虑的因素。
7.1 缓存色彩映射
对于重复使用的色彩映射,可以将其缓存以提高性能:
import matplotlib.pyplot as plt
import numpy as np
# 缓存色彩映射
cmap = plt.get_cmap('viridis')
# 创建大型数据集
data = np.random.rand(1000, 1000)
# 使用缓存的色彩映射
plt.figure(figsize=(10, 8))
im = plt.imshow(data, cmap=cmap)
plt.colorbar(im)
plt.title('How2matplotlib.com - Using Cached Colormap')
plt.show()
Output:
通过预先获取色彩映射并重复使用,可以略微提高大型数据集或需要频繁更新的可视化的性能。
7.2 使用 Normalize 对象
对于需要频繁更新的可视化,使用预先创建的 Normalize
对象可以提高性能:
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import Normalize
# 创建 Normalize 对象
norm = Normalize(vmin=0, vmax=1)
# 创建图形
fig, ax = plt.subplots(figsize=(10, 8))
# 初始数据
data = np.random.rand(20, 20)
# 初始绘图
im = ax.imshow(data, cmap='viridis', norm=norm)
plt.colorbar(im)
ax.set_title('How2matplotlib.com - Using Normalize Object')
# 模拟数据更新
for _ in range(10):
data = np.random.rand(20, 20)
im.set_data(data)
plt.pause(0.5)
plt.show()
Output:
这个例子展示了如何使用预先创建的 Normalize
对象来提高频繁更新数据的可视化性能。通过重用 Normalize
对象,我们避免了在每次更新时重新计算数据范围。
总结
Matplotlib 的色彩映射功能强大而灵活,get_cmap
函数是使用这些色彩映射的关键工具。通过本文的详细介绍和示例,我们探讨了色彩映射的基本概念、get_cmap
函数的高级用法、自定义色彩映射的方法、常见的应用场景、选择原则以及一些高级技巧和性能考虑。
掌握这些知识和技巧,你将能够更有效地使用 Matplotlib 的色彩映射功能,创建更具表现力和信息量的数据可视化。无论是处理科学数据、金融分析还是其他领域的数据可视化需求,色彩映射都是一个强大的工具,可以帮助你更好地理解和展示数据的模式和趋势。
记住,选择合适的色彩映射不仅可以增强数据的可读性,还可以使你的可视化更具美感和专业性。在实践中,多尝试不同的色彩映射,并根据数据的特性和目标受众来选择最合适的方案。随着经验的积累,你将能够更直观地选择和使用色彩映射,创造出既美观又有效的数据可视化作品。