2012-08-02 165 views
8

我不能夠在以下數圖繪製一個簡單,垂直箭頭:Matplotlib:繪製垂直箭頭,在雙對數座標

#!/usr/bin/python2 

import matplotlib.pyplot as plt 
import matplotlib as mpl 

plt.yscale('log') 
plt.xscale('log') 
plt.ylim((1e-20,1e-10)) 
plt.xlim((1e-12,1)) 

plt.arrow(0.00006666, 1e-20, 0, 1e-8 - 1e-20, length_includes_head=True) 

plt.savefig('test.pdf') 

它只是不顯示。從文檔中可以看出,所有參數(如寬度,高度等等)都與軸的縮放比例相關。這非常違反直覺。我嘗試使用axisartist包的twin()來定義我的頂部的軸,並且限制了(0,1)(0,1)對箭頭參數有更多的控制,但我無法弄清楚如何在主要的參數上有一個完全獨立的軸。

任何想法?

+1

似乎是matplotlib的問題。嘗試'plt.arrow(6e-4,1e-4,0.1,0.2,length_includes_head = True)'並將視圖移到y的更高值。你會看到箭頭線大約從10-4開始。但是,如果您使用較低的值(即對於x和y,則爲1e-5),線消失,並且您只能看到大部分與以前相同的小箭頭。 (顯然,你應該使用plt.show()來做到這一點) – joaquin 2012-08-02 17:24:54

+0

那麼是否有任何解決方法? – janoliver 2012-08-02 17:47:20

+0

如果我知道我會寫一個答案;-)。但現在至少你知道箭頭在那裏...... – joaquin 2012-08-02 17:51:42

回答

4

次要情節接近

創建次要情節做以下

  • 對準位置
  • 使用set_axis_off()打開軸傾斜後(蜱,標籤等)
  • 繪製箭頭!

所以幾行就得到你想要的!

E.g.

#!/usr/bin/python2 

import matplotlib.pyplot as plt 

hax = plt.subplot(1,2,1) 
plt.yscale('log') 
plt.xscale('log') 
plt.ylim((1e-20,1e-10)) 
plt.xlim((1e-12,1)) 

hax2 = plt.subplot(1,2,2) 
plt.arrow(0.1, 1, 0, 1, length_includes_head=True) 

hax.set_position([0.1, 0.1, 0.8, 0.8]) 
hax2.set_position([0.1, 0.1, 0.8, 0.8]) 

hax2.set_axis_off() 

plt.savefig('test.pdf') 

重縮放數據

可選地一個可能更簡單的方法,雖然軸標籤可能是棘手的,是重新定標該數據。

import numpy 

# Other import commands and data input 

plt.plot(numpy.log10(x), numpy.log10(y))) 

不是一個偉大的解決方案,但如果你能處理的刻度標記一個體面的結果!

+0

嗨,我需要一個單獨的x和y軸,因爲兩者都在主機軸上進行日誌縮放。 axisartists的'twin'功能總是使用主機和寄生蟲軸之間的轉換功能。我不希望他們以任何方式連接。由於關於這些事情的文檔很差,我找不到一個(可能不是骯髒的)方法來實現這一點。如果它不容易實現,我可能只需在inkscape左右插入箭頭即可。 – janoliver 2012-08-02 17:46:00

+0

覆蓋。我想不出有兩個完全獨立的圖表,每個圖表都有自己的x軸和y軸,等等。 – janoliver 2012-08-02 18:43:40

+0

那麼爲什麼不直接做一個'log(x)'和'log(y)'的線性圖?它使繪製箭頭微不足道。 – jmetz 2012-08-02 19:02:29

5

我正在尋找這個問題的答案,並找到了一個有用的答案!您可以指定任何「mathtext」字符(matplotlib的LaTeX版本)作爲標記。嘗試: plt.plot(x,y,'ko',marker = r'$ \ downarrow $',markersize = 20)

這將在位置(x,y)繪製一個向下指向的黑色箭頭,在任何情節(甚至對數日誌)上看起來都不錯。 請參閱:matplotlib.org/users/mathtext.html#mathtext-tutorial以獲取更多可用的符號。

1

我知道這個線程已經死了很長一段時間,但我認爲發佈我的解決方案可能有助於任何人試圖找出如何有效地繪製對數級箭頭。

作爲別人已發佈內容的替代方案,您可以使用transformation object來輸入不是原始軸比例的箭頭座標,而是以「軸座標」的(線性)比例輸入。我所說的軸座標是指那些通過[0,1](垂直範圍)歸一化爲[0,1](水平範圍)的點,其中點(0,0)是左下角和點(1,1)將是右上角,依此類推。然後,你可以簡單地包括箭頭:

plt.arrow(0.1, 0.1, 0.9, 0.9, transform=plot1.transAxes, length_includes_head=True) 

這給了跨越斜在情節的水平和垂直範圍的4/5的箭頭,從左下到右上(其中plot1是子圖名稱)。

如果你想這樣做一般來說,在精確座標(x0,y0)和日誌空間(x1,y1)可以爲箭頭指定,如果你寫兩個函數fx(x)fy(y)從原始座標變換,這不是太困難到這些「座標軸」座標。我舉了一個例子,說明如何修改OP發佈的原始代碼以實現下面的內容(道歉不包括代碼生成的圖像,我沒有所需的聲望)。

#!/usr/bin/python3 

import numpy as np 
import matplotlib.pyplot as plt 
import matplotlib as mpl 

# functions fx and fy take log-scale coordinates to 'axes' coordinates 
ax = 1E-12 # [ax,bx] is range of horizontal axis 
bx = 1E0 
def fx(x): 
    return (np.log(x) - np.log(ax))/(np.log(bx) - np.log(ax)) 

ay = 1E-20 # [ay,by] is range of vertical axis 
by = 1E-10 
def fy(y): 
    return (np.log(y) - np.log(ay))/(np.log(by) - np.log(ay)) 

plot1 = plt.subplot(111) 
plt.xscale('log') 
plt.yscale('log') 
plt.xlim(ax, bx) 
plt.ylim(ay, by) 

# transformed coordinates for arrow from (1E-10,1E-18) to (1E-4,1E-16) 
x0 = fx(1E-10) 
y0 = fy(1E-18) 
x1 = fx(1E-4) - fx(1E-10) 
y1 = fy(1E-16) - fy(1E-18) 

plt.arrow(
      x0, y0, x1, y1, # input transformed arrow coordinates 
      transform = plot1.transAxes, # tell matplotlib to use axes coordinates 
      facecolor = 'black', 
      length_includes_head=True 
     ) 

plt.grid(True) 
plt.savefig('test.pdf')