2012-07-05 4 views
1

마침표로 타원이있는 플롯을 만들고 싶습니다. 다음은 현재 실제로 원이라는 하나의 큰 타원을 만드는 샘플 코드입니다. 이 단순화 된 경우, ax1.axis("equal") 순수 원을 줄 것이다,하지만 내 마지막 플롯,이 명령은 전체 플롯을 파괴되지만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")을 사용하지 않고 범용 타원 도구를 만들고 싶습니다. 보시다시피이 프로그램에서 주요 축의 편심 도와 경사각을 설정할 수 있습니다.

문제 : 문제는 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에서 일식 위치와 양식은 먼저 높이와 너비로 축척 한 다음 중심을 중심으로 회전 한 다음 필요한 위치로 변환하여 설정합니다. 그래서 회전과 높이를 스케일링하기 전에 (스크립트에서와 같이) mork을 할 수도 있지만 정확히 맞히기는 어렵습니다 (아마도 회전을 스케일링하고 반전시켜야하지만, 변환 메스는 녹슬지 않습니다).

올바르게 타원의 형태를 확장 할 경우 타원 클래스를 서브 클래스와 _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) 

P.S.을 ax_ratioy_lim/x_lim으로 가정합니다!

+0

여기서 코드를 복사 할 때'ax_ratio == DefSize [0]/DefSize [1]'을 추가하는 것을 잊어 버렸습니다. 죄송합니다. – makhlaghi

+0

고맙습니다.이 새로운 수업을 통해 완벽하게 작동했습니다. 그것은 완벽하게 작동합니다. 다시 한번 감사드립니다. – makhlaghi