Гистограмма сюжетов с цветами, взятыми из цветовой карты
Я хочу построить простую 1D-гистограмму, где бары должны следовать цветовому кодированию заданной цветовой схемы.
Здесь 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()
который выводит это:
![enter image description here]()
Вместо того, чтобы цвет был green
для всей гистограммы, я хотел бы, чтобы столбцы следовали цветовому кодированию, указанному в цветовой палитре, определенной в cm
, и значениях bins
. Это означало бы, что ячейки ближе к нулю (не по высоте, а по положению) должны выглядеть более синими, а те, которые ближе к одному красному, в соответствии с выбранной цветовой палитрой RdYlBu_r
.
Так как plt.histo
не принимает аргумент cmap
, я не знаю, как сказать ему использовать colormap, определенный в cm
.
Ответы
Ответ 1
Команда 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()
Чтобы получить цвета, вам нужно вызвать цветовой код со значением от 0 до 1. Результат:
![enter image description here]()
Ответ 2
Альтернативный подход заключается в использовании 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]()
Ответ 3
Пока это не то, о чем вы просили, если кто-то другой натыкается на это (как и я), ища способ сделать окраску по высоте бункеров вместо порядка, следующий код, основанный на ответе Баса, будет работать
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()
![введите описание изображения здесь]()
Ответ 4
Мне нравится Bas Swinckels ответить, но учитывая, что colormap 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()