Matplotlib 如何用颜色渐变填充直方图,其中一个固定点表示颜色贴图的中间

Matplotlib 如何用颜色渐变填充直方图,其中一个固定点表示颜色贴图的中间,matplotlib,histogram,Matplotlib,Histogram,此代码 import numpy as np import matplotlib.pyplot as plt def randn(n, sigma, mu): return sigma * np.random.randn(n) + mu x = randn(1000, 40., -100.) cm = plt.cm.get_cmap("seismic") fig = plt.figure() ax = fig.add_subplot(1,1,1) _, bins, patches

此代码

import numpy as np
import matplotlib.pyplot as plt

def randn(n, sigma, mu):
    return sigma * np.random.randn(n) + mu

x = randn(1000, 40., -100.)

cm = plt.cm.get_cmap("seismic")
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
_, bins, patches = ax.hist(x,color="r",bins=30)
bin_centers = 0.5*(bins[:-1]+bins[1:])
col = bin_centers - min(bin_centers)
col /= max(col)

for c, p in zip(col, patches):
    plt.setp(p, "facecolor", cm(c))
plt.savefig("b.png", dpi=300, bbox_inches="tight")
生成以下直方图


我想使用发散彩色贴图
seismic
,希望所有表示负数出现的条带蓝色,所有表示正数的条带红色。在零度左右,条形图应始终为白色。因此,第一个图形应该大部分为红色,最后一个图形应该大部分为蓝色。如何实现这一点?

< P>如果这只是关于视觉外观,你可以将你的颜色标准化到最大绝对值与其负对应的范围内,这样零点总是在中间(<代码>马克斯宾斯< /代码>)。

对于不同的用例,我有一个备选答案。我想让发散颜色贴图中的不同颜色动态映射到发散点两侧各自的“宽度”。另外,我想显式地设置分歧点(在我的例子中是1)

我通过修改@ImportanceofBeingErnest的答案实现了这一点,尽管最后我不需要做任何标准化,我只是在同一个图形上使用了两个图,并选择了连续的颜色贴图,当端到端放置时,重新形成了目标发散颜色贴图

def hist2(x, vmin, vmax, cmmap_name, ax=None,):

    cm = plt.cm.get_cmap(cmmap_name)
    ax = ax or plt.gca()
    _, bins, patches = ax.hist(x,color="r",bins=50)

    bin_centers = 0.5*(bins[:-1]+bins[1:])
    norm = plt.Normalize(vmin, vmax)

    for c, p in zip(bin_centers, patches):
        plt.setp(p, "facecolor", cm(norm(c)))

data = <YOUR DATA>
left_data = [i for i in data if i < <YOUR DIVERGENCE POINT>]
right_data = [i for i in data if i >= <YOUR DIVERGENCE POINT>]

fig, ax = plt.subplots(nrows=1)
hist2(left_data, min(left_data), max(left_data), "YlOrRd_r", ax=ax)
hist2(right_data, min(right_data), max(right_data), "YlGn", ax=ax)
plt.show()
def hist2(x,vmin,vmax,cmmap_名称,ax=None,):
cm=plt.cm.get\u cmap(cmmap\u名称)
ax=ax或plt.gca()
_,存储箱,补丁=ax.hist(x,color=“r”,存储箱=50)
垃圾箱中心=0.5*(垃圾箱[:-1]+垃圾箱[1:])
norm=plt.Normalize(vmin,vmax)
对于c,p-in-zip(bin_中心,补丁):
plt.setp(p,“脸色”,cm(标准(c)))
数据=
左_数据=[i表示数据中的i,如果i<]
right_data=[i表示数据中的i,如果i>=]
图,ax=plt子批次(nrows=1)
hist2(左侧数据,最小值(左侧数据),最大值(左侧数据),“YlOrRd\u r”,ax=ax
hist2(右数据,最小值(右数据),最大值(右数据),“YlGn”,ax=ax
plt.show()
我的一些结果:


只需在hist中指定存储箱,而不是指定多个存储箱。我刚刚意识到,该解决方案只适用于大数量的存储箱。在这种情况下,数字从-200到200。如果我测试你的解决方案的较小的数字,比如-1到1,直方图几乎是白色的。几乎看不到蓝色或红色。你如何改变这一点?对于较小的数字,结果看起来像。
def hist2(x, vmin, vmax, cmmap_name, ax=None,):

    cm = plt.cm.get_cmap(cmmap_name)
    ax = ax or plt.gca()
    _, bins, patches = ax.hist(x,color="r",bins=50)

    bin_centers = 0.5*(bins[:-1]+bins[1:])
    norm = plt.Normalize(vmin, vmax)

    for c, p in zip(bin_centers, patches):
        plt.setp(p, "facecolor", cm(norm(c)))

data = <YOUR DATA>
left_data = [i for i in data if i < <YOUR DIVERGENCE POINT>]
right_data = [i for i in data if i >= <YOUR DIVERGENCE POINT>]

fig, ax = plt.subplots(nrows=1)
hist2(left_data, min(left_data), max(left_data), "YlOrRd_r", ax=ax)
hist2(right_data, min(right_data), max(right_data), "YlGn", ax=ax)
plt.show()