2013-01-11 88 views
28

如何在matplotlib中繪製多個酒吧,當我試圖多次調用酒吧功能,他們重疊,並看到下圖所示的最高值紅色只能看到。 如何繪製x軸上日期的多個小節?蟒蛇matplotlib多個酒吧

到目前爲止,我想這:

import matplotlib.pyplot as plt 
    import datetime 

    x = [datetime.datetime(2011, 1, 4, 0, 0), 
     datetime.datetime(2011, 1, 5, 0, 0), 
     datetime.datetime(2011, 1, 6, 0, 0)] 
    y = [4, 9, 2] 
    z=[1,2,3] 
    k=[11,12,13] 

    ax = plt.subplot(111)![enter image description here][1] 
    ax.bar(x, y,width=0.5,color='b',align='center') 
    ax.bar(x, z,width=0.5,color='g',align='center') 
    ax.bar(x, k,width=0.5,color='r',align='center') 
    ax.xaxis_date() 

    plt.show() 

我得到這個: enter image description here

的結果應該是這樣的,但是隨着日期是在x軸和酒吧旁邊的每個其他: enter image description here

+0

您需要更改x值 – jterrace

+0

你是什麼意思? X值是日期... –

回答

38
import matplotlib.pyplot as plt 
from matplotlib.dates import date2num 
import datetime 

x = [datetime.datetime(2011, 1, 4, 0, 0), 
    datetime.datetime(2011, 1, 5, 0, 0), 
    datetime.datetime(2011, 1, 6, 0, 0)] 
x = date2num(x) 

y = [4, 9, 2] 
z=[1,2,3] 
k=[11,12,13] 

ax = plt.subplot(111) 
ax.bar(x-0.2, y,width=0.2,color='b',align='center') 
ax.bar(x, z,width=0.2,color='g',align='center') 
ax.bar(x+0.2, k,width=0.2,color='r',align='center') 
ax.xaxis_date() 

plt.show() 

enter image description here

我不知道什麼是 「Y值也重疊」 的意思,它下面的代碼解決問題了嗎?

ax = plt.subplot(111) 
w = 0.3 
ax.bar(x-w, y,width=w,color='b',align='center') 
ax.bar(x, z,width=w,color='g',align='center') 
ax.bar(x+w, k,width=w,color='r',align='center') 
ax.xaxis_date() 
ax.autoscale(tight=True) 

plt.show() 

enter image description here

+0

謝謝,但如果我有3個酒吧,它看起來不錯。當我嘗試像40個酒吧時,它會混亂起來。你能否更新你的解決方案,以便更具擴展性? –

+0

定義「彌補」?X標籤重疊可以通過使用autofmt_xdate()來修復,該自動旋轉標籤。 – jozzas

+0

問題不是重疊X標籤,問題是y值也重疊。如何解決它? –

17

使用日期作爲x值的麻煩是,如果你想要一張條形圖像你的第二張照片一樣,他們將是錯誤的。您應該使用堆疊的條形圖(顏色在彼此之上)或按日期分組(x軸上的「假」日期,基本上只是對數據點進行分組)。

import numpy as np 
import matplotlib.pyplot as plt 

N = 3 
ind = np.arange(N) # the x locations for the groups 
width = 0.27  # the width of the bars 

fig = plt.figure() 
ax = fig.add_subplot(111) 

yvals = [4, 9, 2] 
rects1 = ax.bar(ind, yvals, width, color='r') 
zvals = [1,2,3] 
rects2 = ax.bar(ind+width, zvals, width, color='g') 
kvals = [11,12,13] 
rects3 = ax.bar(ind+width*2, kvals, width, color='b') 

ax.set_ylabel('Scores') 
ax.set_xticks(ind+width) 
ax.set_xticklabels(('2011-Jan-4', '2011-Jan-5', '2011-Jan-6')) 
ax.legend((rects1[0], rects2[0], rects3[0]), ('y', 'z', 'k')) 

def autolabel(rects): 
    for rect in rects: 
     h = rect.get_height() 
     ax.text(rect.get_x()+rect.get_width()/2., 1.05*h, '%d'%int(h), 
       ha='center', va='bottom') 

autolabel(rects1) 
autolabel(rects2) 
autolabel(rects3) 

plt.show() 

enter image description here

+0

如果我想在x軸上顯示100天,你如何適應它們? –

+0

您可以很容易地生成numpy的'datetime64'所需的日期:例如一個月價值:'np.arange('2012-02','2012-03',dtype ='datetime64 [D]')'。如果您擁有超過100天的40個數據集(根據其他評論),則可能需要更加努力地考慮表示此數據的最佳方式。 – jozzas

+0

你能用建議的解決方案更新你的代碼嗎? –

0

或者您可以使用二維數據結構,讓matplotlib處理您的欄間距:

import numpy as np 
import matplotlib.pyplot as plt 

x = np.random.randn(1000, 3) 
bins = np.arange(-4.5, 4.5, 1) 
colors = ['red', 'tan', 'lime'] 

plt.hist(x, bins=bins, color=colors, label=colors) 
plt.legend() 
plt.xticks(bins + 0.5, ['bin ' + str(int(x)) for x in (bins + 0.5)]) 
plt.show() 

添加rwidth = 1是要在酒吧之間移除任何空間。

enter image description here

Source