首页编程开发Matplotlib【数据可视化(Matplo...

【数据可视化(Matplotlib篇)】30.色彩条colorbar

本系列文章配套代码获取有以下两种途径:

  • 通过百度网盘获取:
链接:https://pan.baidu.com/s/1jG-rGG4QMuZu0t0kEEl7SA?pwd=mnsj 提取码:mnsj
  • 前往GitHub获取
https://github.com/returu/Data_Visualization





色彩条本质上是一个颜色映射标尺,它将图表中的数值与特定颜色建立对应关系,帮助读者快速理解颜色背后的数据含义。在 Matplotlib 中,色彩条colorbar 并非独立存在的图表元素,而是依附于使用了颜色映射colormap的绘图对象(如imshow、contourf、scatter等)。

01

函数语法


色彩条colorbar()的函数语法如下:
plt.colorbar(mappable=None, cax=None, ax=None, **kwargs)
其中,
  • mappable(必选):指定色彩条所关联的绘图对象,通常是使用了颜色映射(colormap)的函数返回值,例如 imshow()、contourf()、scatter() 等的返回对象。默认是现在的图像。
  • shrink:调整色彩条的长度(垂直方向)或宽度(水平方向),取值为 0~1 的浮点数。例如,shrink=0.8 表示色彩条尺寸缩为原图的 80%。
  • aspect控制色彩条的宽高比(仅对垂直方向的色彩条有效),值越大,色彩条越窄,默认值为 20。例如,aspect=30 会使垂直色彩条更窄。
  • orientation设置色彩条的方向,可选值为 ‘vertical’(垂直,默认)或 ‘horizontal’(水平)。
  • label为色彩条添加标签,用于说明颜色对应的物理含义(如 “温度 (℃)”“浓度” 等)。例如,label=’数据值 (MPa)’

  • ticks指定色彩条上的刻度位置,可传入列表或数组。例如,ticks=[0, 25, 50, 75, 100]

  • extend当数据范围超出色彩条的刻度范围时,在色彩条两端添加扩展箭头,可选值为 ‘neither’(默认,无箭头)、‘both’(两端都有)、‘min’(仅最小值端)、‘max’(仅最大值端)。
  • pad控制colorbar与主图之间的间距,单位为英寸。
  • fraction控制colorbar的大小(宽度或高度)相对于主图的大小比例。
  • extendfrac用于控制扩展箭头(extend arrows)大小。当使用extend参数时,extendfrac决定了这些箭头相对于colorbar长度的比例。

  • ax在多子图(subplot)场景中,指定色彩条关联的子图对象,确保色彩条与子图布局协调。
  • cax手动指定色彩条的轴对象(Axes),用于精确控制色彩条的位置和大小(需配合 fig.add_axes() 创建轴)。

要添加 colorbar,只需两步:首先创建一个使用 colormap 的绘图对象,然后调用plt.colorbar()函数即可。

以下是一个基础热力图搭配 colorbar 的示例:

# 生成随机数据(10x10矩阵)
data = np.random.rand(10, 10)

# 创建热力图(使用默认colormap)
im = plt.imshow(data)

# 添加色彩条
plt.colorbar(shrink=0.5 ,               # 将色彩条的长度缩小为原来的50%
             aspect=10 ,                # 设置色彩条的宽高比为10
             orientation='horizontal' , # 将色彩条设置为水平方向(默认是垂直)
             label='Colorbar' ,         # 为色彩条添加标签文本
             ticks=[0.2,0.5,0.8],       # 设置要显示的刻度
             extend='both',             # 在色彩条的两端添加箭头,表示数据可能超出当前显示范围
             pad=0.08,                  # 设置colorbar与主图之间的间距
             fraction=0.3,              # 设置colorbar相对于主图的大小比例
             extendfrac=0.02            # 设置控制扩展箭头的大小
            )
# 显式指定与哪个图像对象关联,当有多个子图时很有用
# plt.colorbar(im)

# 显示图表
plt.title('基础热力图与colorbar示例')
plt.show()

运行上述代码后,将看到一个 10×10 的热力图,右侧附带一个垂直的色彩条。色彩条的上下端分别标注了数据的最大值和最小值,中间的颜色渐变对应数据从低到高的变化,如下图所示:

02

多子图共享colorbar


在绘制多子图(如subplot)时,若多个子图使用相同的颜色映射,共享一个 colorbar 能让图表更简洁、对比更清晰。
实现方法是使用colorbar()函数时,通过 ax 参数设定散点图对象的轴,如果要设定多个轴共享一个色彩条,可以将多个轴打包成列表或元组。例如,若要使用 ax[0] 和 ax[1] 共享色彩条,方法如下:
ax = (ax[0],ax[1])
示例代码:
fig, axes = plt.subplots(2, 2, figsize=(12, 8))

# 绘制四个子图
im1 = axes[0,0].imshow(np.random.rand(10, 10), cmap='viridis')
im2 = axes[0,1].imshow(np.random.rand(10, 10), cmap='viridis')
im3 = axes[1,0].imshow(np.random.rand(10, 10), cmap='viridis')
im4 = axes[1,1].imshow(np.random.rand(10, 10), cmap='viridis')

# 创建共享colorbar
fig.colorbar(im1, 
             ax=axes.ravel().tolist(),  # 将子图数组转换为一维列表,传递给 colorbar,使其与所有子图关联
             shrink=0.8)

# 设置总标题
fig.suptitle('多子图中共享 colorbar 示例', y=0.93, fontsize=16)
# 显示图表
plt.show()

可视化结果如下图所示:

03

控制colorbar位置


在默认情况下,当调用 colorbar() 而不提供 cax参数时,Matplotlib 会执行以下操作:
  • 从当前图形(figure)中“偷”一部分空间。
  • 自动创建一个新的 Axes 对象来容纳颜色条。
  • 将颜色条绘制在这个新创建的 Axes 中。
这个自动过程在大多数简单情况下工作得很好。但是,当需要精确控制颜色条的位置和大小时,自动布局可能无法满足需求。这时,cax参数就派上了用场。需要注意的是,如果同时指定了 ax 和 cax,ax 会被忽略。
  • 手动创建 Axes 并指定 cax:

使用 cax参数的典型工作流程如下:
  • 手动创建 Axes: 首先,使用 fig.add_axes(rect)方法,手动在图形的一个特定位置创建一个 Axes 对象。rect是一个四元列表 [left, bottom, width, height],定义了该 Axes 在 figure 中的相对位置和大小(所有值都在 0 到 1 之间)。
  • 传递 cax参数: 然后,在调用 fig.colorbar()时,将这个预先创建好的 Axes 对象通过 cax参数传递进去。
  • 绘制颜色条: Matplotlib 会将颜色条精确地绘制在指定的这个 Axes 中。
# 创建一些数据
data = np.random.rand(10, 10)

# 创建图形和主图 Axes
fig, ax = plt.subplots(figsize=(6, 5))

# 绘制主图
im = ax.imshow(data, cmap='viridis')

# 1. 为颜色条手动创建一个 Axes
cax_rect = [0.92, 0.1, 0.03, 0.8] # 调整这些值可以精确控制位置和大小
cax = fig.add_axes(cax_rect) # 创建一个新的 Axes 对象

# 2. 将创建好的 cax 传递给 colorbar 函数
cbar = fig.colorbar(im, cax=cax)

# 可选:在颜色条 Axes 上设置标签
cbar.set_label('Value')

ax.set_title("Colorbar with ‘cax‘ Parameter")
plt.show()

可视化结果如下图所示:

  • 结合 GridSpec 精确控制布局:

使用 cax 参数结合 GridSpec 来精确控制图形布局。

GridSpec 是 Matplotlib 中用于精细控制子图布局的强大工具,它允许你创建不规则的子图网格,比普通的 subplot 更灵活。这种布局方式的优势在于可以精确控制每个子图和颜色条的相对大小和位置,避免了自动布局可能带来的不一致性,特别适合需要严格控制图形外观的场景。

以下示例代码创建了一个包含多个子图的图形,每个子图都有自己的颜色条,并且通过 GridSpec 精确控制了它们的布局:
from matplotlib.gridspec import GridSpec

# 创建示例数据
x = np.linspace(0, 10, 100)
y = np.linspace(0, 5, 50)
X, Y = np.meshgrid(x, y)
Z1 = np.sin(X) * np.cos(Y)
Z2 = np.exp(-(X**2 + Y**2) / 20)
Z3 = np.sin(X/2) + np.cos(Y/2)

# 创建图形
fig = plt.figure(figsize=(12, 8))

# 使用GridSpec定义网格布局
# 创建一个3行12列的网格布局,这为我们提供了精细控制每个元素位置的能力
gs = GridSpec(3, 12, figure=fig, wspace=0.3, hspace=0.5)

# 第一个子图及其colorbar
ax1 = fig.add_subplot(gs[0, :10])  # 第1行,前10列用于绘图
im1 = ax1.imshow(Z1, aspect='auto', origin='lower', extent=[0,10,0,5])
ax1.set_title('Sin(X) * Cos(Y)')
cax1 = fig.add_subplot(gs[0, 10:12])  # 第1行,后2列用于colorbar
fig.colorbar(im1, cax=cax1)

# 第二个子图及其colorbar
ax2 = fig.add_subplot(gs[1, 3:12])  # 第2行,后10列用于绘图
im2 = ax2.imshow(Z2, aspect='auto', origin='lower', extent=[0,10,0,5], cmap='viridis')
ax2.set_title('Gaussian Function')
cax2 = fig.add_subplot(gs[1, :2])  # 第2行,前2列用于colorbar
fig.colorbar(im2, cax=cax2)

# 第三个子图及其更窄的colorbar
ax3 = fig.add_subplot(gs[2, :11])  # 第3行,前11列用于绘图
im3 = ax3.imshow(Z3, aspect='auto', origin='lower', extent=[0,10,0,5], cmap='plasma')
ax3.set_title('Sin(X/2) + Cos(Y/2)')
cax3 = fig.add_subplot(gs[2, 11:12])  # 第3行,最后1列用于colorbar
fig.colorbar(im3, cax=cax3)

plt.show()

可视化结果如下图所示:

04

自定义colorbar刻度与标签


有时我们需要调整 colorbar 的刻度位置或添加更详细的标签(如科学计数法、单位换算),可以通过Colorbar对象的set_ticks()和set_ticklabels()方法实现。
# 生成数据(模拟温度分布,范围:-10~30℃)
data = np.random.randint(-10, 31, size=(10, 10))
heatmap = plt.pcolor(data, cmap='coolwarm')  # pcolor返回ScalarMappable对象
cbar = plt.colorbar(heatmap)

# 自定义非连续刻度:突出零下、0℃、室温、高温
cbar.set_ticks([-10, -5, 0, 25, 30])

# 自定义标签:结合文本与符号(如℃)
cbar.set_ticklabels([
    '-10℃ (严寒)'
    '-5℃'
    '0℃ (冰点)'
    '25℃ (室温)'
    '30℃ (高温)'
])

# 调整标签样式
cbar.ax.tick_params(labelsize=10, labelrotation=15)  # 设置颜色条刻度标签的样式:字体大小10,旋转15度
cbar.set_label('温度分布', fontsize=12, fontweight='bold'# 设置颜色条的标题
plt.title('非连续刻度+个性化标签', fontsize=14) # 设置整个图表的标题
plt.show()

可视化结果如下图所示:


更多内容可以前往官网查看

https://matplotlib.org/stable/


本篇文章来源于微信公众号: 码农设计师

RELATED ARTICLES

欢迎留下您的宝贵建议

Please enter your comment!
Please enter your name here

- Advertisment -

Most Popular

Recent Comments