Python 我创建的渐变与轴上的值不匹配

Python 我创建的渐变与轴上的值不匹配,python,matplotlib,Python,Matplotlib,我想显示颜色渐变作为matplotlib图表的背景。 我发现这很接近我想要的 但在使用此示例并创建自己的颜色贴图时,我指定的值与轴上的值不匹配 例如,使用上面的示例代码和。。。 在dict中指定我的颜色和值: 注意间隔值为0.8,我希望0-0.8为黑色,0.8到1.0为红色到黑色的渐变 将dict转换为颜色映射: from matplotlib.colors import LinearSegmentedColormap testcm1 = LinearSegmentedColormap('tes

我想显示颜色渐变作为matplotlib图表的背景。 我发现这很接近我想要的

但在使用此示例并创建自己的颜色贴图时,我指定的值与轴上的值不匹配

例如,使用上面的示例代码和。。。 在dict中指定我的颜色和值:

注意间隔值为0.8,我希望0-0.8为黑色,0.8到1.0为红色到黑色的渐变

将dict转换为颜色映射:

from matplotlib.colors import LinearSegmentedColormap
testcm1 = LinearSegmentedColormap('testcm1 ', cdict1)
gradient_image(ax, direction=0, extent=(0, 1, 0, 1), transform=ax.transAxes,
               cmap=testcm1 , cmap_range=(0, 1))
并更改gradient_image的调用以使用我的颜色贴图:

from matplotlib.colors import LinearSegmentedColormap
testcm1 = LinearSegmentedColormap('testcm1 ', cdict1)
gradient_image(ax, direction=0, extent=(0, 1, 0, 1), transform=ax.transAxes,
               cmap=testcm1 , cmap_range=(0, 1))
然而,我的输出显示,红黑梯度大约从0.72开始。

当然,我希望梯度与y轴上的0.8值完全匹配,我不知道这里发生了什么

我的代码:

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

import numpy as np

np.random.seed(19680801)

def gradient_image(ax, extent, direction=0.3, cmap_range=(0, 1), **kwargs):
    """
    Draw a gradient image based on a colormap.

    Parameters
    ----------
    ax : Axes
        The axes to draw on.
    extent
        The extent of the image as (xmin, xmax, ymin, ymax).
        By default, this is in Axes coordinates but may be
        changed using the *transform* kwarg.
    direction : float
        The direction of the gradient. This is a number in
        range 0 (=vertical) to 1 (=horizontal).
    cmap_range : float, float
        The fraction (cmin, cmax) of the colormap that should be
        used for the gradient, where the complete colormap is (0, 1).
    **kwargs
        Other parameters are passed on to `.Axes.imshow()`.
        In particular useful is *cmap*.
    """
    phi = direction * np.pi / 2
    v = np.array([np.cos(phi), np.sin(phi)])
    X = np.array([[v @ [1, 0], v @ [1, 1]],
                  [v @ [0, 0], v @ [0, 1]]])
    a, b = cmap_range
    X = a + (b - a) / X.max() * X
    im = ax.imshow(X, extent=extent, interpolation='bicubic',
                   vmin=0, vmax=1, **kwargs)
    return im


xmin, xmax = xlim = 0, 10
ymin, ymax = ylim = 0, 1

fig, ax = plt.subplots()
ax.set(xlim=xlim, ylim=ylim, autoscale_on=False)

cdict1 = {
    'red': 
        [
            (0.0, 0.0, 0.0),
            (0.8, 0.0, 0.0),
            (0.8, 1.0, 1.0),
            (1.0, 0.0, 0.0)
        ],
    'blue': [(0.0, 0.0, 0.0), (1.0, 0.0, 0.0)],
    'green': [(0.0, 0.0, 0.0), (1.0, 0.0, 0.0)]
 }

testcm1 = LinearSegmentedColormap('testcm1', cdict1)

# background image
gradient_image(ax, direction=0, extent=(0, 1, 0, 1), transform=ax.transAxes,
               cmap=testcm1, cmap_range=(0, 1))

ax.set_aspect('auto')
plt.show()

首先,我想说只有三个定位点,所以颜色词典应该看起来像

'red': 
        [
            (0.0, 0.0, 0.0),
            (0.8, 0.0, 1.0),
            (1.0, 0.0, 0.0)
        ],
但这并不是真正的问题

真正的问题是图像由4个角点组成。双三次插值会产生梯度;当然,你没有足够的分辨率来显示指定的精确梯度。特别是,0.8不是图像数据的一部分

因此,需要定义一个具有足够分辨率的图像来显示不连续性。在下文中,我还使颜色贴图的创建更加直观

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

colors = [(0, "black"),(0.8,"black"),(0.8,"red"),(1.0,"black")]
testcm2 = LinearSegmentedColormap.from_list('testcm2', colors)


fig, ax = plt.subplots()

X = np.repeat(np.linspace(0,1,301),2).reshape(301,2)
im = ax.imshow(X, extent=(0,1,0,1), cmap=testcm2, vmin=0, vmax=1, 
               interpolation="bicubic", origin="lower")

plt.show()

哇,难以置信。甚至比实际matplotlib页面上的示例更简单。你答案中的301只是一个提高分辨率的高数字吗?我将看看我能在多大程度上适应我的实际用例。谢谢你的帮助。是的,301是相当随意的,只要n+1中的任何数字n可以被5整除,就可以确保0.8就是数据的一部分,但是如果这个数字很高,你就看不到任何区别。请注意,matplotlib示例非常复杂,因为它允许旋转渐变。