2012-10-05 88 views
2

下面是我繪製函數的代碼,我需要將「X」和「Y」標籤移動到第一個象限中,然後將它們放在傳統上靠近相應的箭頭。這是如何完成的?如何將軸標籤移動到matplotlib中的箭頭附近

import pylab as p 
import numpy as n 

from mpl_toolkits.axes_grid import axislines 


def cubic(x) : 
    return x**3 + 6*x 


def set_axes(): 
    fig = p.figure(1) 
    ax = axislines.SubplotZero(fig, 111) 
    fig.add_subplot(ax) 

    for direction in ['xzero', 'yzero']: 
     ax.axis[direction].set_axisline_style('->', size=2) 
     ax.axis[direction].set_visible(True) 

    for direction in ['right', 'top', 'left', 'bottom']: 
     ax.axis[direction].set_visible(False) 

    ax.axis['xzero'].set_label('X') 
    ax.axis['yzero'].set_label('Y') 

    ax.axis['yzero'].major_ticklabels.set_axis_direction('right') 
    ax.axis['yzero'].set_axislabel_direction('+') 
    ax.axis['yzero'].label.set_rotation(-90) 
    ax.axis['yzero'].label.set_va('center') 


set_axes() 

X = n.linspace(-15,15,100) 
Y = cubic(X) 

p.plot(X, Y) 

p.xlim(-5.0, 5.0) 
p.ylim(-15.0, 15.0) 

p.xticks(n.linspace(-5, 5, 11, endpoint=True)) 
p.grid(True) 

p.show() 

回答

5

通常情況下,要改變一個軸的(例如,ax.xaxis)標籤的位置,你會怎麼做axis.label.set_position(xy)。或者你可以設置一個座標,例如「ax.xaxis.set_x(1)`。

在你的情況,這將是:

ax['xzero'].label.set_x(1) 
ax['yzero'].label.set_y(1) 

然而,axislines(以及任何在axisartist或其他axes_grid)是一個有些過時模塊(這就是爲什麼axes_grid1存在)。在某些情況下,它不能正確分類。所以,當我們嘗試設置標籤的x和y位置時,沒有任何變化!


一個快速的解決方法是使用ax.annotate在你的箭的兩端放置標籤。但是,讓我們先嚐試使用不同的方式(之後我們將返回annotate)。


這些日子裏,你最好使用新的spines功能來完成你想要完成的任務。

import matplotlib.pyplot as plt 

fig, ax = plt.subplots() 

for spine in ['left', 'bottom']: 
    ax.spines[spine].set_position('zero') 

# Hide the other spines... 
for spine in ['right', 'top']: 
    ax.spines[spine].set_color('none') 

ax.axis([-4, 10, -4, 10]) 
ax.grid() 

plt.show() 

enter image description here

但是,我們仍然需要漂亮的箭頭裝飾:如

設置X和Y軸是 「零」 就是這麼簡單。這有點複雜,但只需兩次調用使用適當的參數進行註釋即可。

import matplotlib.pyplot as plt 

fig, ax = plt.subplots() 

#-- Set axis spines at 0 
for spine in ['left', 'bottom']: 
    ax.spines[spine].set_position('zero') 

# Hide the other spines... 
for spine in ['right', 'top']: 
    ax.spines[spine].set_color('none') 

#-- Decorate the spins 
arrow_length = 20 # In points 

# X-axis arrow 
ax.annotate('', xy=(1, 0), xycoords=('axes fraction', 'data'), 
      xytext=(arrow_length, 0), textcoords='offset points', 
      arrowprops=dict(arrowstyle='<|-', fc='black')) 

# Y-axis arrow 
ax.annotate('', xy=(0, 1), xycoords=('data', 'axes fraction'), 
      xytext=(0, arrow_length), textcoords='offset points', 
      arrowprops=dict(arrowstyle='<|-', fc='black')) 

#-- Plot 
ax.axis([-4, 10, -4, 10]) 
ax.grid() 

plt.show() 

enter image description here

(箭頭的寬度由文字大小(或可選的參數給arrowprops控制),因此指定類似size=16annotate將使箭頭寬一點,如果你想。)


在這一點上,這是最簡單的,只是添加了「X」和「Y」標籤作爲註解的一部分,雖然設置其職位將正常工作。

如果我們只是在標籤傳遞的,而不是來註釋空字符串的第一個參數(和更改對齊位),我們會在箭頭的兩端得到很好標籤:

import matplotlib.pyplot as plt 

fig, ax = plt.subplots() 

#-- Set axis spines at 0 
for spine in ['left', 'bottom']: 
    ax.spines[spine].set_position('zero') 

# Hide the other spines... 
for spine in ['right', 'top']: 
    ax.spines[spine].set_color('none') 

#-- Decorate the spins 
arrow_length = 20 # In points 

# X-axis arrow 
ax.annotate('X', xy=(1, 0), xycoords=('axes fraction', 'data'), 
      xytext=(arrow_length, 0), textcoords='offset points', 
      ha='left', va='center', 
      arrowprops=dict(arrowstyle='<|-', fc='black')) 

# Y-axis arrow 
ax.annotate('Y', xy=(0, 1), xycoords=('data', 'axes fraction'), 
      xytext=(0, arrow_length), textcoords='offset points', 
      ha='center', va='bottom', 
      arrowprops=dict(arrowstyle='<|-', fc='black')) 

#-- Plot 
ax.axis([-4, 10, -4, 10]) 
ax.grid() 

plt.show() 

enter image description here

只需稍微多一點工作(直接訪問脊柱的變換),您可以使用generalize the use of annotate來處理任何類型的脊柱對齊(例如「被丟棄」的脊椎等)。

無論如何,希望有所幫助。如果你願意,你也可以get fancier with it

+0

謝謝!使用註釋來繪製箭頭的一個問題是箭頭比軸線稍厚。 – akonsu