You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解决plt.imshow+cmap绘图的边缘重叠与分段配色不连续问题

问题描述

需要基于y轴划分4个区域,通过cmap与plt.imshow实现从红色到绿色的连续平滑配色:

  • 第一段:恒定红色(cmap的首个颜色)
  • 第二段:从红色平滑过渡至黄色
  • 第三段:从黄色平滑过渡至绿色
  • 第四段:恒定绿色

现有代码运行后出现两个问题:

  1. 分段边缘存在重叠/线条
  2. 黄到绿的过渡不符合预期(先呈现深绿色,再变为浅绿色)

原代码如下:

import numpy as np
import matplotlib.pyplot as plt


plt.rcParams["figure.figsize"] = (19.2, 9.6)

Diam_P = 0.4
ylim = 7

plt.imshow(np.interp(np.linspace(0, 3 * Diam_P, 1), [0, 1], [0, 0]).reshape(-1, 1),
           cmap='hsv', vmin=0, vmax=1, extent=[0, 180, 0, 3 * Diam_P], origin='lower',
           interpolation='bilinear', aspect='auto', zorder=-1, alpha=0.7)
plt.imshow(np.interp(np.linspace(3 * Diam_P, 2, 10000), [3 * Diam_P, 2], [0, 0.15]).reshape(-1, 1),
           cmap='hsv', vmin=0, vmax=1, extent=[0, 180, 3 * Diam_P, 2], origin='lower',
           interpolation='bilinear', aspect='auto', zorder=-1, alpha=0.7)
plt.imshow(np.interp(np.linspace(2, 3, 20000), [2, 3], [0.15, 0.24]).reshape(-1, 1),
           cmap='hsv', vmin=0, vmax=1, extent=[0, 180, 2, 3], origin='lower',
           interpolation='bilinear', aspect='auto', zorder=-1, alpha=0.7)
plt.imshow(np.interp(np.linspace(3, ylim, 1), [3, ylim], [0.24, 0.24]).reshape(-1, 1),
           cmap='hsv', vmin=0, vmax=1, extent=[0, 180, 3, ylim], origin='lower',
           interpolation='bilinear', aspect='auto', zorder=-1, alpha=0.7)

plt.xlim(0, 70)
plt.ylim(0, ylim)
plt.savefig("test2.png", dpi=600)
plt.show()

问题效果图:
整体图
细节图

解决方案

问题根源

  1. 分段边缘异常:多次调用plt.imshow绘制不同区域,即使设置了extent边界,渲染和插值过程中仍会出现边界衔接误差;部分区域仅用1个采样点,进一步加剧了边缘异常。
  2. 颜色过渡错误:hsv色彩空间中,色相值0.15到0.24并非对应黄到绿的平滑区间——黄色色相约为0.166,绿色约为0.333,原区间未覆盖正确范围,导致颜色跳变。

修改后代码

直接生成全y轴的颜色映射数组,单次调用imshow避免边界问题,同时自定义符合需求的红-黄-绿渐变:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap

plt.rcParams["figure.figsize"] = (19.2, 9.6)

Diam_P = 0.4
ylim = 7
# 定义四个区域的y轴边界
y_bounds = [0, 3*Diam_P, 2, 3, ylim]

# 自定义颜色节点:对应四个区域的颜色变化
color_nodes = [
    (1, 0, 0),       # 恒定红色(第一段)
    (1, 0, 0),       # 红色(第二段起始)
    (1, 1, 0),       # 黄色(第二段结束/第三段起始)
    (0, 1, 0),       # 绿色(第三段结束/第四段恒定)
    (0, 1, 0)        # 恒定绿色(第四段)
]
# 创建连续自定义色图
custom_cmap = LinearSegmentedColormap.from_list("red_yellow_green", color_nodes)

# 生成y轴采样点与对应的颜色索引
y_samples = np.linspace(0, ylim, 10000)  # 足够采样点保证平滑
color_indices = np.interp(y_samples, y_bounds, [0, 0, 1, 2, 2])

# 转为2D数组供imshow使用
color_array = color_indices.reshape(-1, 1)

# 单次绘制整个背景
plt.imshow(color_array, 
           cmap=custom_cmap, 
           vmin=0, vmax=2, 
           extent=[0, 180, 0, ylim], 
           origin='lower',
           interpolation='bilinear', 
           aspect='auto', 
           zorder=-1, 
           alpha=0.7)

plt.xlim(0, 70)
plt.ylim(0, ylim)
plt.savefig("test2.png", dpi=600)
plt.show()

核心改进点

  • 单次绘制替代分段绘制:生成完整的y轴颜色数组,彻底消除多段imshow的边界衔接问题。
  • 自定义色图:基于RGB直接定义红-黄-绿的渐变路径,完全匹配需求的颜色过渡逻辑,避开HSV的色彩空间局限。
  • 高采样密度:10000个采样点确保过渡区域的平滑性,避免色块断层。

内容的提问来源于stack exchange,提问作者Ali_Sh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 16:44:55