2012-10-12 92 views
3

我在matplotlib中生成堆栈条形图(在Windows 7上使用Python 2.7)。堆栈matplotlib栏中的替代颜色

由于我想用它来对两个数据集中的数据进行两两比较,所以我想为每个第二栏使用不同的颜色。任何人都可以告诉我如何实现这一目标?

我的条形图基本上是这样的:

import numpy 
import matplotlib.pyplot as plt 


fig = plt.figure() 
ax1 = fig.add_subplot(1,1,1) 

IDs = ["1","A","2","B","3","C","4","D","5","E"] 
N = len(IDs) 

property1 = numpy.array([1,3,4,2,3,5,6,7,3,2]) 
property2 = numpy.array(range(10)) 
property3 = numpy.array(range(10,0,-1)) 

ind = numpy.arange(N) 
width = 0.8 

p1 = ax1.bar(ind, property1, width, color='red') 
p2 = ax1.bar(ind, property2, width, color='blue', bottom=property1) 
p3 = ax1.bar(ind, property3, width, color='green', bottom=property1 + property2) 
plt.xticks(ind+width/2., IDs) 

plt.show() 
plt.close() 

所以我想用一个配色方案用字母标记的酒吧,另一个用于那些用数字标记(因为例如,“1”和“A “形成一对 - 它们代表2种不同实验条件下的同一样品,这就是为什么我希望它们彼此相邻的原因)。理想情况下,如果宽度可以适应一对(但是对之间的差距)的酒吧之间没有差距,那将是非常好的。

但现在,我不知道如何去做这件事,所以任何建议都会很棒!

(我可以单独使用这两种数据的“套”,那是更容易?也许做两个地块同宽的间隙,相互交叉?)

+0

我认为这个问题有一个你想要的例子。 http://stackoverflow.com/questions/12742317/chart-barh-matplotlib-overlap-bars/12747726#12747726 – tacaswell

+0

@tcaswell:我不明白这个问题与我的相关。我不想要一个水平条形图,我知道宽度和高度是如何工作的。这与颜色有什么关系? – Lastalda

+0

更改'barh' - >'bar'和'height' - >'width'。将你的数据和IDS分成两组,一组由数字索引,一组以字母索引。你所做的一件事是,问题所问的代码显示了如何交错两个数据集。 – tacaswell

回答

5

你可以用切片更优雅地做到这一点。一个可能更好的解决方案是去交错你的数据。

IDs = ["1","A","2","B","3","C","4","D","5","E"] 

N = len(IDs) 
fig = plt.figure() 
ax1 = fig.add_subplot(1,1,1) 

set_count = 2 
set_label = np.vstack([j*ones(len(IDs)//set_count) for j in range(set_count)]).T.ravel() 

property1 = numpy.array([1,3,4,2,3,5,6,7,3,2]) 
property2 = numpy.array(range(10)) 
property3 = numpy.array(range(10,0,-1)) 

props = [property1,property2,property3] 

ind = numpy.arange(N/set_count) 
width = 0.9 
b_width = 0.9/set_count 

color_sets = [['red','green','blue'],['black','magenta','yellow']] 

for j in range(set_count): 
    tmp_accum = np.zeros(len(props[0])) 
    for k in range(len(props)): 
     ax1.bar(ind +j*b_width, props[k][set_label==j], width=b_width, color=color_sets[j][k], bottom=tmp_accum[set_label==j]) 
     tmp_accum += props[k] 


lab_ind = [] 
for j in range(set_count): 

    lab_ind.append(ind + (j+.5)*b_width) 

plt.xticks(np.vstack(lab_ind).T.ravel(), IDs) 

它需要一定的完整性检查,但它的工作原理,应该扩展到超过2类和3层以上的属性容易(你只需要确保您的所有长度的同步跟进,利用itertools.cycle的颜色可能有帮助)。

image of results

+0

这很好用,谢谢!我对'numpy'(例如'vstack')并不熟悉,不能完全理解你在那里做了些什么,但我知道它适合我的真实数据,它比我的解决方案更加优雅和适应性强。 (另外,xticks现在放置正确,耶!)感谢您挖掘到这! – Lastalda

1

找到一个可行的办法,但它似乎相当unelegant :

import numpy 
import matplotlib.pyplot as plt 

fig = plt.figure() 
ax1 = fig.add_subplot(1,1,1) 

IDs = ["1","A","2","B","3","C","4","D","5","E"] 

N = len(IDs) 

property1_1 = numpy.array([1,0,4,0,3,0,6,0,3,0]) 
property1_2 = numpy.array([0,3,0,2,0,5,0,7,0,2]) 
property2_1 = numpy.array([1,0,2,0,3,0,4,0,5,0]) 
property2_2 = numpy.array([0,6,0,7,0,8,0,9,0,10]) 
property3_1 = numpy.array([10,0,9,0,8,0,7,0,6,0]) 
property3_2 = numpy.array([0,5,0,4,0,3,0,2,0,1]) 

ind = numpy.arange(N) 
width = 0.8 

p1 = ax1.bar(ind, property1_1, width, color='red') 
p2 = ax1.bar(ind, property2_1, width, color='blue', bottom=property1_1) 
p3 = ax1.bar(ind, property3_1, width, color='green', bottom=property1_1 + property2_1) 

p4 = ax1.bar(ind-0.2, property1_2, width, color='#FF6666') 
p5 = ax1.bar(ind-0.2, property2_2, width, color='#6699FF', bottom=property1_2) 
p6 = ax1.bar(ind-0.2, property3_2, width, color='#33CC33', bottom=property1_2+property2_2) 
plt.xticks(ind+width/2., IDs) 

plt.show() 
plt.close() 

这就是我为了这个问题而做的。我不认为这是最佳的,并会感谢额外的答案。