Matplotlib中ax.fill_between的cmap参数无效,如何实现渐变填充?
问题:Matplotlib fill_between 设置cmap无法实现渐变填充
尝试使用Matplotlib的ax.fill_between绘图函数的cmap参数实现曲线下区域的渐变填充,但设置后无任何效果,始终得到纯色填充结果。
尝试的代码
第一种写法:
import matplotlib.pyplot as plt x = [0, 1, 2, 3, 4, 5] y = [2, 4, 1, 3, 0.5, 2] fig, ax = plt.subplots( figsize=(10,6), facecolor="white" ) ax.fill_between( x=x, y1=y, cmap="cool" )
第二种写法:
ax.fill_between( x=x, y1=y, cmap=plt.get_cmap("cool") )
尝试将cmap应用到color或facecolor属性时会抛出错误,最终结果始终为纯色填充:
原因分析
fill_between的cmap参数并非用于直接实现区域渐变填充——该参数仅在结合where条件与数组类型的color时才会生效,但默认情况下fill_between会将整个填充区域视为单一图形对象,无法直接应用渐变色。
解决方案
要实现曲线下区域的渐变填充,可采用以下几种方法:
方法1:分段填充+颜色映射
将x轴拆分为大量微小分段,为每个分段的填充区域分配对应颜色映射的颜色:
import matplotlib.pyplot as plt import numpy as np x = np.linspace(0, 5, 100) # 细分x轴,提升渐变平滑度 y = np.array([2, 4, 1, 3, 0.5, 2]) y_smooth = np.interp(x, [0,1,2,3,4,5], y) # 插值得到平滑y值 fig, ax = plt.subplots(figsize=(10,6), facecolor="white") cmap = plt.get_cmap("cool") norm = plt.Normalize(y_smooth.min(), y_smooth.max()) # 遍历每个小段填充对应颜色 for i in range(len(x)-1): x_segment = [x[i], x[i+1], x[i+1], x[i]] y_segment = [0, 0, y_smooth[i+1], y_smooth[i]] avg_y = (y_smooth[i] + y_smooth[i+1])/2 ax.fill(x_segment, y_segment, color=cmap(norm(avg_y))) ax.plot(x, y_smooth, color='black') plt.show()
方法2:imshow+蒙版
创建渐变背景,用曲线下区域作为蒙版显示渐变:
import matplotlib.pyplot as plt import numpy as np x = np.linspace(0,5,100) y = np.interp(x, [0,1,2,3,4,5], [2,4,1,3,0.5,2]) fig, ax = plt.subplots(figsize=(10,6), facecolor="white") # 创建渐变图像 im = ax.imshow( np.linspace(0,1,100).reshape(1,-1), extent=[x.min(),x.max(),0,y.max()], aspect='auto', cmap='cool', origin='lower' ) # 生成蒙版:仅保留曲线下方区域 y_mask = np.linspace(0, y.max(), 100).reshape(-1,1) mask = y_mask <= y im.set_data(np.where(mask, np.linspace(0,1,100), np.nan)) ax.plot(x, y, color='black') plt.show()
方法3:PolyCollection创建渐变多边形集合
将曲线下区域转换为可应用颜色映射的多边形集合:
import matplotlib.pyplot as plt import numpy as np from matplotlib.collections import PolyCollection x = np.linspace(0,5,100) y = np.interp(x, [0,1,2,3,4,5], [2,4,1,3,0.5,2]) fig, ax = plt.subplots(figsize=(10,6), facecolor="white") # 构建每个分段的多边形顶点 verts = [] for i in range(len(x)-1): verts.append([(x[i],0), (x[i], y[i]), (x[i+1], y[i+1]), (x[i+1],0)]) # 创建多边形集合并应用颜色映射 poly = PolyCollection(verts, cmap='cool', norm=plt.Normalize(y.min(), y.max())) poly.set_array(np.array([(y[i]+y[i+1])/2 for i in range(len(x)-1)])) ax.add_collection(poly) ax.plot(x, y, color='black') ax.set_xlim(x.min(), x.max()) ax.set_ylim(0, y.max()) plt.colorbar(poly) plt.show()
内容的提问来源于stack exchange,提问作者pawjast
相关产品推荐
相关产品推荐

