用颜色图绘制直方图

46 投票
4 回答
60230 浏览
提问于 2025-04-18 02:40

我想画一个简单的一维直方图,直方图的颜色应该按照给定的颜色映射来显示。

这里有一个简单的例子:

import numpy as n
import matplotlib.pyplot as plt

# Random gaussian data.
Ntotal = 1000
data = 0.05 * n.random.randn(Ntotal) + 0.5

# This is  the colormap I'd like to use.
cm = plt.cm.get_cmap('RdYlBu_r')

# Plot histogram.
n, bins, patches = plt.hist(data, 25, normed=1, color='green')

plt.show()

这个例子输出了这个效果:

在这里输入图片描述

我希望直方图的颜色不是整个都是绿色,而是每个柱子的颜色能根据cm中定义的颜色映射和bins的值来变化。也就是说,离零更近的柱子(不是指高度,而是位置)应该看起来更蓝,而离一更近的柱子应该更红,这样就能符合选择的颜色映射RdYlBu_r

因为plt.histo这个函数不接受cmap参数,所以我不知道怎么告诉它使用cm中定义的颜色映射。

4 个回答

2

我喜欢Bas Swinckels的回答,但考虑到颜色映射cm需要一个在0到1之间的值,下面这个算法会更简单一些。

import matplotlib.pyplot as plt

Ntotal = 1000
data = 0.05 * n.random.randn(Ntotal) + 0.5

cm = plt.cm.RdBu_r

n, bins, patches = plt.hist(data, 25, normed=1, color='green')
for i, p in enumerate(patches):
    plt.setp(p, 'facecolor', cm(i/25)) # notice the i/25

plt.show()
17

虽然这不是你问的内容,但如果其他人像我一样,想要找到根据箱子的高度来上色的方法,而不是按照顺序,下面这段代码是基于Bas的回答,可以用来实现这个功能:

import numpy as np
import matplotlib.pyplot as plt

Ntotal = 1000
data = 0.05 * np.random.randn(Ntotal) + 0.5
cm = plt.cm.get_cmap('RdYlBu_r')

n, bins, patches = plt.hist(data, 25, normed=1, color='green')
# To normalize your values
col = (n-n.min())/(n.max()-n.min())
for c, p in zip(col, patches):
    plt.setp(p, 'facecolor', cm(c))
plt.show()

在这里输入图片描述

19

另一种方法是使用 plt.bar,这个方法可以接收一个颜色列表。要确定条形的宽度和高度,你可以使用 numpy.histogram。你的颜色映射可以通过找到x值的范围,然后将它们缩放到0到1之间来实现。

import numpy as n
import matplotlib.pyplot as plt

# Random gaussian data.
Ntotal = 1000
data = 0.05 * n.random.randn(Ntotal) + 0.5

# This is  the colormap I'd like to use.
cm = plt.cm.get_cmap('RdYlBu_r')

# Get the histogramp
Y,X = n.histogram(data, 25, normed=1)
x_span = X.max()-X.min()
C = [cm(((x-X.min())/x_span)) for x in X]

plt.bar(X[:-1],Y,color=C,width=X[1]-X[0])
plt.show()

enter image description here

53

hist命令会返回一个补丁(patch)的列表,这样你就可以逐个遍历这些补丁,并设置它们的颜色,方法如下:

import numpy as n
import matplotlib.pyplot as plt

# Random gaussian data.
Ntotal = 1000
data = 0.05 * n.random.randn(Ntotal) + 0.5

# This is  the colormap I'd like to use.
cm = plt.cm.get_cmap('RdYlBu_r')

# Plot histogram.
n, bins, patches = plt.hist(data, 25, normed=1, color='green')
bin_centers = 0.5 * (bins[:-1] + bins[1:])

# scale values to interval [0,1]
col = bin_centers - min(bin_centers)
col /= max(col)

for c, p in zip(col, patches):
    plt.setp(p, 'facecolor', cm(c))

plt.show()

要获取颜色,你需要调用色图,并传入一个介于0到1之间的值。得到的图形如下:

enter image description here

撰写回答