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

解决使用自定义LinearSegmentedColormap调用plt.set_cmap()时的ValueError

问题:Matplotlib自定义颜色映射用plt.set_cmap报错ValueError?

我尝试在matplotlib中使用自定义颜色映射,写了如下代码:

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

%matplotlib inline   

# color_map = mpl.cm.get_cmap('Spectral') # 获取内置颜色映射
color_map = LinearSegmentedColormap.from_list('custom', 
                                       [(0, '#ff0000'),
                                        (1,   '#00ff00')], N=10)

x = np.array(range(10))
y = np.sin(x) 

plt.set_cmap(color_map)
plt.plot(x, y)

执行后触发了ValueError:

ValueError: 'custom' is not a valid value for name; supported values are 'Accent', 'Accent_r', 'Blues', 'Blues_r', ...(省略部分内置映射名称)

用注释里的内置Spectral颜色映射时就没这个错误,Python版本是3.9.12,请问问题出在哪?

问题原因

  • plt.set_cmap()的作用是设置当前图像的默认颜色映射,但它要求传入的映射必须已经注册到Matplotlib的全局颜色映射字典里。内置的映射比如Spectral都是预先注册好的,所以能直接用;而你自定义的custom只是创建了一个局部对象,没被加入全局字典,内部逻辑尝试通过名称查找时就会报错。
  • 另外,plt.plot()默认是绘制单一颜色的线条,本身并不依赖颜色映射——颜色映射是给scatter、imshow这类需要根据数值映射到不同颜色的绘图函数用的,你这里用plt.set_cmap()属于用错了场景。

解决方案

根据你的需求,分两种情况处理:

情况1:想让plot的线条呈现自定义渐变色彩

如果需要让线条根据数值显示自定义颜色映射的效果,不用plt.set_cmap(),直接在需要的绘图函数里指定cmap参数即可。注意plot本身不支持渐变线条,要实现渐变线条需要用LineCollection,或者用scatter先画点:

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

%matplotlib inline   

color_map = LinearSegmentedColormap.from_list('custom', 
                                       [(0, '#ff0000'),
                                        (1,   '#00ff00')], N=10)

x = np.array(range(10))
y = np.sin(x) 

# 方式1:绘制带颜色渐变的散点
plt.scatter(x, y, c=x, cmap=color_map)
plt.colorbar()

# 方式2:绘制带颜色渐变的线条
points = np.column_stack((x, y))
segments = np.array([points[i:i+2] for i in range(len(points)-1)])
lc = LineCollection(segments, cmap=color_map)
lc.set_array(x)  # 用x值作为颜色映射的依据
plt.gca().add_collection(lc)
plt.colorbar(lc)
plt.xlim(x.min(), x.max())
plt.ylim(y.min(), y.max())

plt.show()

情况2:想让自定义颜色映射全局可用

如果希望自定义映射能像内置映射一样通过名称调用,或者让plt.set_cmap()生效,需要先把它注册到Matplotlib的全局字典中:

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

%matplotlib inline   

# 创建自定义颜色映射并注册到全局
color_map = LinearSegmentedColormap.from_list('custom', 
                                       [(0, '#ff0000'),
                                        (1,   '#00ff00')], N=10)
mpl.colormaps.register(color_map)  # 完成注册

x = np.array(range(10))
y = np.sin(x) 

plt.set_cmap('custom')  # 现在可以直接用名称调用自定义映射
# 用scatter测试颜色映射效果
plt.scatter(x, y, c=x)
plt.colorbar()
plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 16:25:19