2012-04-04 90 views
13

我在Ubuntu 10.0.4上使用matplotlib 1.2.x和Python 2.6.5。我正嘗試創建一個由頂部陰謀和底部陰謀組成的單一陰謀。matplotlib:使用共享X軸創建兩個(堆疊)子圖但是分離Y軸值

X軸是時間序列的日期。頂部圖包含數據的燭臺圖,底部圖應由條形圖組成 - 具有其自己的Y軸(也在左側 - 與頂部圖相同)。這兩塊地塊不應重疊。

這是我迄今爲止所做的一個片段。

datafile = r'/var/tmp/trz12.csv' 
r = mlab.csv2rec(datafile, delimiter=',', names=('dt', 'op', 'hi', 'lo', 'cl', 'vol', 'oi')) 

mask = (r["dt"] >= datetime.date(startdate)) & (r["dt"] <= datetime.date(enddate)) 
selected = r[mask] 
plotdata = zip(date2num(selected['dt']), selected['op'], selected['cl'], selected['hi'], selected['lo'], selected['vol'], selected['oi']) 

# Setup charting 
mondays = WeekdayLocator(MONDAY)  # major ticks on the mondays 
alldays = DayLocator()    # minor ticks on the days 
weekFormatter = DateFormatter('%b %d') # Eg, Jan 12 
dayFormatter = DateFormatter('%d')  # Eg, 12 
monthFormatter = DateFormatter('%b %y') 

# every Nth month 
months = MonthLocator(range(1,13), bymonthday=1, interval=1) 

fig = pylab.figure() 
fig.subplots_adjust(bottom=0.1) 
ax = fig.add_subplot(111) 
ax.xaxis.set_major_locator(months)#mondays 
ax.xaxis.set_major_formatter(monthFormatter) #weekFormatter 
ax.format_xdata = mdates.DateFormatter('%Y-%m-%d') 
ax.format_ydata = price 
ax.grid(True) 

candlestick(ax, plotdata, width=0.5, colorup='g', colordown='r', alpha=0.85) 

ax.xaxis_date() 
ax.autoscale_view() 
pylab.setp(pylab.gca().get_xticklabels(), rotation=45, horizontalalignment='right') 

# Add volume data 
# Note: the code below OVERWRITES the bottom part of the first plot 
# it should be plotted UNDERNEATH the first plot - but somehow, that's not happening 
fig.subplots_adjust(hspace=0.15) 
ay = fig.add_subplot(212) 
volumes = [ x[-2] for x in plotdata] 
ay.bar(range(len(plotdata)), volumes, 0.05) 

pylab.show() 

我已成功使用上面的代碼,以顯示兩個圖,但是,有兩個問題與底部曲線:

  1. 它完全覆蓋第一(頂部)的底部部分情節 - 幾乎就好像第二個情節與第一個情節一樣繪製在同一個「畫布」上 - 我看不到發生在哪裏/爲什麼。

  2. 它用自己的指令覆蓋現有的X軸,X軸值(日期)應該在兩個圖之間共享。

我在做什麼錯在我的代碼?是否有人可以發現是什麼導致第二個(底部)情節覆蓋第一個(頂部)情節 - 我該如何解決這個問題?

這裏是由上面的代碼中創建的情節的屏幕截圖:

faulty plot

[[編輯]]

修改代碼由hwlau建議之後,這是新的情節。它比在這兩個圖是分開的第一更好,然而,以下問題仍然:

  1. X軸應該由兩個圖可以共享(即,X軸應該顯示僅用於第二[底部]圖)

  2. 的第二圖中的Y值似乎是正確formmated

partly correct plot

我覺得這些問題s應該很容易解決,但是我的matplotlib fu目前並不好,因爲我最近纔開始用matplotlib編程。任何幫助都感激不盡。

回答

10

似乎有成爲一對夫婦與您的代碼的問題:

  1. 如果您正在使用figure.add_subplotssubplot(nrows, ncols, plotNum)全 簽名可能有 被越來越明顯的是,你的第一個情節要求1排 和1列,第二個圖是要求2行和 1列。因此,你的第一個陰謀是填補整個數字。 而不是fig.add_subplot(111)其次fig.add_subplot(212) 使用fig.add_subplot(211)其次是fig.add_subplot(212)

    import matplotlib.pyplot as plt 
    import matplotlib.ticker as mticker 
    import matplotlib.dates as mdates 
    
    
    import datetime as dt 
    
    
    n_pts = 10 
    dates = [dt.datetime.now() + dt.timedelta(days=i) for i in range(n_pts)] 
    
    ax1 = plt.subplot(2, 1, 1) 
    ax1.plot(dates, range(10)) 
    
    ax2 = plt.subplot(2, 1, 2, sharex=ax1) 
    ax2.bar(dates, range(10, 20)) 
    
    # Now format the x axis. This *MUST* be done after all sharex commands are run. 
    
    # put no more than 10 ticks on the date axis. 
    ax1.xaxis.set_major_locator(mticker.MaxNLocator(10)) 
    # format the date in our own way. 
    ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d')) 
    
    # rotate the labels on both date axes 
    for label in ax1.xaxis.get_ticklabels(): 
        label.set_rotation(30) 
    for label in ax2.xaxis.get_ticklabels(): 
        label.set_rotation(30) 
    
    # tweak the subplot spacing to fit the rotated labels correctly 
    plt.subplots_adjust(hspace=0.35, bottom=0.125) 
    
    plt.show() 
    

    希望幫助:

  2. 共享一個軸,應在add_subplot命令使用sharex=first_axis_instance

我已經把你應該能夠運行一個實例來完成。

+0

子圖中的'sharex'和'sharey'屬性非常方便,感謝發佈。 (它可以比通過讀取和設置其他常見限制好得多:當通過交互式放大來檢查結果時,如果共享,兩個/所有子圖將放大在一起。) – Bonlenfum 2013-05-13 16:05:47

+0

'sharex = first_axis_instance'這是一個'軸'實例,對嗎? – 2016-08-05 15:02:12

6

你應該改變這一行:

ax = fig.add_subplot(111) 

ax = fig.add_subplot(211) 

原來的命令意味着有一行和一列,因此它佔據整個圖形。所以你的第二張圖fig.add_subplot(212)覆蓋了第一張圖的下半部分。

編輯

如果你不想兩個地塊,用途subplots_adjust()之間的差距,以改變次要情節邊距的大小。

+0

感謝您的發現。我幾乎尷尬地錯過了那些顯而易見的東西。也許我一直在盯着代碼太久;)。情節現在更接近我想要的。但是,有幾個懸而未決的問題。請有機會看看我編輯的問題。 – 2012-04-04 11:08:31

2

來自@Pelson的例子簡化了。

import matplotlib.pyplot as plt 
import datetime as dt 

#Two subplots that share one x axis 
fig,ax=plt.subplots(2,sharex=True) 

#plot data 
n_pts = 10 
dates = [dt.datetime.now() + dt.timedelta(days=i) for i in range(n_pts)] 
ax[0].bar(dates, range(10, 20)) 
ax[1].plot(dates, range(10)) 

#rotate and format the dates on the x axis 
fig.autofmt_xdate() 

次要情節共享x軸在一條線,當你想要兩個以上的次要情節是方便創建:

fig, ax = plt.subplots(number_of_subplots, sharex=True) 

要在X軸上正確格式的日期,我們可以只需使用fig.autofmt_xdate()

shared x xaxis

有關更多信息,請參閱shared axis demodate demo來自pylab的例子。 這個例子在Python3上運行,matplotlib 1.5.1

相關問題