2012-07-05 57 views
1

我想用橢圓作爲標記進行繪圖。這裏是一個示例代碼,其中一個大橢圓現在實際上是一個圓。matplotlib中具有各種角度和偏心的橢圓

#! /usr/bin/env python3.2 
import numpy as np 
import pylab 
import matplotlib.pyplot as plt 
from matplotlib.backends.backend_pdf import PdfPages 
from matplotlib.patches import Ellipse 

PlotFileName="test.pdf" 
pdf = PdfPages(PlotFileName) 
fig=plt.figure(1) 
ax1=fig.add_subplot(111) 
x_lim=3 
plt.xlim([0,x_lim]) 
plt.ylim([0,x_lim]) 

F=pylab.gcf() 
DefSize = F.get_size_inches() 

#These lines have a true angle of 45 degrees, only as a reference: 
offset_along_x=x_lim-(x_lim/ax_ratio) 
ax1.plot([offset_along_x/2, x_lim-(offset_along_x/2)], [0, x_lim], "b") 
ax1.plot([offset_along_x/2, x_lim-(offset_along_x/2)], [x_lim, 0], "b") 

e=0.0 
theta=0 
maj_ax=2 
min_ax=maj_ax*np.sqrt(1-e**2) 
xconst=(DefSize[1]/DefSize[0])*np.cos(theta*np.pi/180)-np.sin(theta*np.pi/180) 
yconst=np.cos(theta*np.pi/180)+(DefSize[1]/DefSize[0])*np.sin(theta*np.pi/180) 
print("xconstant= {}".format(xconst)) 
print("yconstant= {}".format(yconst)) 
ax1.add_artist(Ellipse((x_lim/2, x_lim/2), xconst*maj_ax, yconst*min_ax, angle=theta, facecolor="green", edgecolor="black",zorder=2, alpha=0.5)) 

pdf.savefig(fig) 
pdf.close() 
plt.close() 

雖然在這個簡單的情況下,ax1.axis("equal")會給純圓形,但在我最後的情節,該命令會毀了整個情節(天秤不相等)。所以我想製作一個通用的橢圓工具而不使用ax1.axis("equal")。如您所見,您可以在此程序中設置主軸的偏心度和傾斜角度。

問題: 問題似乎是,我不明白matplotlib如何旋轉其圖像。如果將theta的值更改爲0或90以外的值,則該對象將不再是圓形。與ax1.axis("equal")的輸出是一個圈,現在重要的是theta的值是多少。所以我的第一個問題是:在改變theta的同時,我應該如何將輸出保持爲一個圓圈。我假設一旦我解決這個問題,它也將工作於一個橢圓。有人能幫助我嗎?我真的很感激。

+0

我注意到補丁中存在[Circle](http://matplotlib.sourceforge.net/api/artist_api.html#matplotlib.patches.Circle),爲什麼不直接用它來代替橢圓? – Mayli

+0

我想最後製作一個橢圓。我正在製作一個圓圈來校準我的程序。如果它能夠正確地使用圓圈,它將與橢圓一起工作。 – makhlaghi

+1

我想你只是對數據座標和顯示座標感到困惑。目前橢圓正在繪製在_data_座標中。您似乎想要_display_座標中的旋轉,寬度和高度,但數據座標中的中心正確嗎?如果是這樣,你只需要定義正確的轉換。我現在正在旅行,所以我不能舉一個例子,但是本教程是一個很好的開始:http://matplotlib.sourceforge.net/users/transforms_tutorial.html您將需要一個混合轉換。 –

回答

3

在matplotlib中,eclipse的位置和形式是先設置高度和寬度,然後圍繞它的中心旋轉,然後轉換到所需的位置。因此,旋轉和縮放高度以及之前可能會(如在腳本中)一樣,但很難完全正確(您可能必須縮放和反轉旋轉,但我的轉換數學是生鏽的)。

如果要正確縮放橢圓的形式,你需要繼承橢圓類並重新定義_recompute_transform功能:

from matplotlib import transforms 

class TransformedEllipse(Ellipse): 

    def __init__(self, xy, width, height, angle=0.0, fix_x = 1.0, **kwargs): 
     Ellipse.__init__(self, xy, width, height, angle, **kwargs) 

     self.fix_x = fix_x 

    def _recompute_transform(self): 

     center = (self.convert_xunits(self.center[0]), 
        self.convert_yunits(self.center[1])) 
     width = self.convert_xunits(self.width) 
     height = self.convert_yunits(self.height) 
     self._patch_transform = transforms.Affine2D() \ 
      .scale(width * 0.5, height * 0.5) \ 
      .rotate_deg(self.angle) \ 
      .scale(self.fix_x, 1) \ 
      .translate(*center) 

,並使用它,像這樣:

fix_x = DefSize[1]/DefSize[0]/ax_ratio 

ellipse = TransformedEllipse((x_lim/2.0, x_lim/2.0), maj_ax, min_ax, angle=theta, facecolor="green", edgecolor="black",zorder=2, alpha=0.5, fix_x = fix_x) 

附:我假設ax_ratioy_lim/x_lim

+0

在這裏複製代碼我忘了添加'ax_ratio == DefSize [0]/DefSize [1]'。抱歉。 – makhlaghi

+0

非常感謝您的支持,它與您定義的這個新課程完美配合。它完美的作品。再次感謝。 – makhlaghi