Python 使用从颜色图中获取的颜色绘制直方图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23061657/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 02:12:04  来源:igfitidea点击:

Plot histogram with colors taken from colormap

pythonmatplotlibhistogram

提问by Gabriel

I want to plot a simple 1D histogram where the bars should follow the color-coding of a given colormap.

我想绘制一个简单的一维直方图,其中条形图应遵循给定颜色图的颜色编码。

Here's an MWE:

这是一个MWE

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()

which outputs this:

输出这个:

enter image description here

enter image description here

Instead of the color being greenfor the entire histogram, I'd like the columns to follow a color-coding given by the colormap defined in cmand the values of the bins. This would mean that bins closer to zero (notin height but in position) should look bluer and those closer to one redder, according to the chosen colormap RdYlBu_r.

而不是green整个直方图的颜色,我希望列遵循由中定义的颜色图cmbins. 这意味着根据所选的颜色图,接近于零(不是高度而是位置)的箱看起来更蓝,接近 1 的箱看起来更红RdYlBu_r

Since plt.histodoesn't take a cmapargument I don't know how to tell it to use the colormap defined in cm.

由于plt.histo不接受cmap参数,我不知道如何告诉它使用cm.

采纳答案by Bas Swinckels

The histcommand returns a list of patches, so you can iterate over them and set their color like so:

hist命令返回一个补丁列表,因此您可以迭代它们并像这样设置它们的颜色:

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()

To get the colors, you need to call the colormap with a value between 0 and 1. Resulting figure:

要获取颜色,您需要使用介于 0 和 1 之间的值调用颜色图。结果图:

enter image description here

enter image description here

回答by Hooked

An alternative approach is to use plt.barwhich takes in a list of colors. To determine the widths and heights you can use numpy.histogram. Your colormap can be used by finding the range of the x-values and scaling them from 0 to 1.

另一种方法是使用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

enter image description here

回答by Alnilam

While it isn't what you asked for, if someone else stumbles across this (like I did) looking for the way to do the coloration by height of the bins instead of order, the following code based on Bas's answer would work:

虽然这不是您所要求的,但如果其他人偶然发现了这一点(就像我一样),正在寻找按垃圾箱的高度而不是顺序进行着色的方法,以下基于 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()

enter image description here

enter image description here

回答by Veiga

I like Bas Swinckels answer, but given that the colormap cm take as parameter a value between 0 and 1, a simpler algorithm would be like this

我喜欢 Bas Swinkels 的回答,但考虑到颜色图 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()