2014-04-14 14 views
27

Ich möchte ein einfaches 1D-Histogramm zeichnen, in dem die Balken der Farbcodierung einer bestimmten Farbpalette folgen sollten.Plot-Histogramm mit Farben aus Colormap

Hier ist ein 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() 

, die diese Ausgänge:

enter image description here

Anstelle der Farbe green für das gesamte Histogramm zu sein, ich die Spalten möchte eine farb- folgen Codierung durch die in cm definierte Farbkarte und die Werte der bins. Dies würde bedeuten, dass Behälter näher bei Null (nicht in Höhe, aber in Position) blauer und diejenigen näher an einem röter, nach der gewählten Farbkarte RdYlBu_r aussehen sollten.

Da plt.histo kein cmap Argument dauert, weiß ich nicht, wie man es anweist, die colormap zu verwenden, die in cm definiert wird.

Antwort

28

Der hist Befehl gibt eine Liste der Patches, so können Sie über sie iterieren und ihre Farbe gesetzt wie so:

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

die Farben zu erhalten, müssen Sie call the colormap with a value between 0 and 1. Daraus resultierendes Bild:

enter image description here

+0

würde ich es Ihnen nichts ausmacht hoffen - wird Imgur _not_ blockiert bei meine Arbeit, also ging ich weiter und fügte dein Bild hinzu. Ich denke, beide Ansätze sind gute Lösungen für diese Frage! – Hooked

+0

Mmm, wenn das Bild korrekt ist, tut der Code nicht, was ich brauche. Die Farbcodierung ist mit den Balken _höhe_ verbunden und ich muss sie mit dem _bins-Wert_ verknüpfen. Siehe @Hooked Antwort, um zu sehen, was ich meine. – Gabriel

+0

Ich habe die Frage bearbeitet, um dies deutlicher zu machen. – Gabriel

12

Ein alternativer Ansatz ist plt.bar zu verwenden, die in einer Liste von Farben nehmen. Um die Breiten und Höhen zu bestimmen, können Sie numpy.histogram verwenden. Ihre colormap können durch Auffinden des Bereichs der x-Werte und Skalierung sie von 0 bis 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

1

verwendet werden, während es nicht das, was Sie gefragt, wenn jemand anderes stolpert über diese (wie ich) für die Art und Weise suchen, um die Färbung durch die Höhe der Fächer statt zu tun, um der folgende Code basiert auf Bas Antwort funktionieren würde:

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

0

Ich mag Bas Swinckels Antwort, aber wenn man bedenkt, dass die colormap cm Wert als Parameter zwischen 0 und 1 annehmen, ein einfacher Algorithmus wie diese

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