gpt4 book ai didi

python - 在 matplotlib 中合并颜色图

转载 作者:行者123 更新时间:2023-12-01 02:40:17 36 4
gpt4 key购买 nike

我想合并两个颜色图以生成 imshow 绘图。我想使用“RdBu”的范围 -0.4 到 0.4,然后从 0.4 到最大值(比如 1.5)我想使用从相同的蓝色到另一种颜色(例如绿色)的渐变。

我怎样才能做到这一点?

这是我到目前为止所取得的进展:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as colors
from matplotlib.mlab import bivariate_normal

N = 100
'''
Custom Norm: An example with a customized normalization. This one
uses the example above, and normalizes the negative data differently
from the positive.
'''
X, Y = np.mgrid[-3:3:complex(0, N), -2:2:complex(0, N)]
Z1 = (bivariate_normal(X, Y, 1., 1., 1.0, 1.0))**2 \
- 0.4 * (bivariate_normal(X, Y, 1.0, 1.0, -1.0, 0.0))**2
Z1 = Z1/0.03

# Example of making your own norm. Also see matplotlib.colors.
# From Joe Kington: This one gives two different linear ramps:

class MidpointNormalize(colors.Normalize):
def __init__(self, vmin=None, vmax=None, midpoint=None, clip=False):
self.midpoint = midpoint
colors.Normalize.__init__(self, vmin, vmax, clip)

def __call__(self, value, clip=None):
# I'm ignoring masked values and all kinds of edge cases to make a
# simple example...
x, y = [self.vmin, self.midpoint, self.vmax], [0, 0.5, 1]
return np.ma.masked_array(np.interp(value, x, y))

fig, ax = plt.subplots(1, 1)

minValue = Z1.min()
maxValue = 0.4

pcm = ax.imshow(Z1,
norm=MidpointNormalize(midpoint=0.),
vmin=minValue, vmax=maxValue,
cmap='RdBu',
origin='lower',
aspect=1.0,
interpolation='none')
cbar = fig.colorbar(pcm, ax=ax, extend='both', ticks=[minValue, 0.0, maxValue])

fig.tight_layout()

plt.show()

enter image description here

最佳答案

目的是创建一个颜色映射,它有几个预定义的值。颜色图的开始位置应为 vmin,白色(位于“RdBu”颜色图的中间)应位于 0,另一个预定义点 (0.4 )应为RdBu颜色图的上端,然后颜色将向某个末端颜色褪色。

为此目的,我们需要两件事。 (a) 包含所有这些颜色的颜色图和(b) 标准化,允许将中间点映射到相应的颜色。

(a) 创建颜色图

颜色图的范围在 0 和 1 之间。我们可以创建颜色图,使“RdBu”颜色图的颜色延伸到所需颜色图的前半部分,这样 0 是红色,0.25 是白色,0.5 是蓝色。然后,颜色图的后半部分的范围从 0.5(相同的蓝色)到 0.75 的一些中间绿松石色到 1 的绿色。(选择中间绿松石色是因为从蓝色到绿色的直接过渡会导致中间出现一些涂抹的棕蓝色) ,这可能是不希望的。)这些步骤是通过以下代码完成的

colors = plt.cm.RdBu(np.linspace(0,1.,128)) 
colors = zip(np.linspace(0,0.5,128),colors)
colors += [ (0.75,"#1fa187"),(1., "#76d154")]
cmap = matplotlib.colors.LinearSegmentedColormap.from_list('mycmap', colors)

这样 cmap 就是所需的颜色图。

(b) 创建标准化

MidpointNormalization 不同,它有一个中间点,我们现在需要两个中间点:一个是值为 0 的白色,一个是颜色图前半部分的末尾。因此,我们可以在自定义标准化中使用两个值(此处称为 lowup),这样插值范围总共超过 4 个点,并且 low对应于颜色图的 0.25 值,up 对应于 0.5 值。

x, y = [self.vmin, self.low, self.up, self.vmax], [0, 0.25, 0.5, 1]

完整代码:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors
from matplotlib.mlab import bivariate_normal

N = 100
X, Y = np.mgrid[-3:3:complex(0, N), -2:2:complex(0, N)]
Z1 = (bivariate_normal(X, Y, 1., 1., 1.0, 1.0))**2 \
- 0.4 * (bivariate_normal(X, Y, 1.0, 1.0, -1.0, 0.0))**2
Z1 = Z1/0.03


class TwoInnerPointsNormalize(matplotlib.colors.Normalize):
def __init__(self, vmin=None, vmax=None, low=None, up=None, clip=False):
self.low = low
self.up = up
matplotlib.colors.Normalize.__init__(self, vmin, vmax, clip)

def __call__(self, value, clip=None):
x, y = [self.vmin, self.low, self.up, self.vmax], [0, 0.25, 0.5, 1]
return np.ma.masked_array(np.interp(value, x, y))

colors = plt.cm.RdBu(np.linspace(0,1.,128))
colors = zip(np.linspace(0,0.5,128),colors)
colors += [ (0.75,"#1fa187"),(1., "#76d154")]
cmap = matplotlib.colors.LinearSegmentedColormap.from_list('mycmap', colors)


fig, ax = plt.subplots(1, 1)

norm = TwoInnerPointsNormalize(vmin=-0.4, vmax=1.5, low=0., up=0.4)
pcm = ax.imshow(Z1, norm=norm, cmap=cmap,
origin='lower', aspect=1.0, interpolation='none')
cbar = fig.colorbar(pcm, ax=ax, ticks=[-0.4,0.0, 0.4,1.5])

fig.tight_layout()
plt.show()

enter image description here

关于python - 在 matplotlib 中合并颜色图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45784299/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com