2010-03-10 6 views
26

나는 극좌표를 만들기 위해 matplotlib과 numpy를 사용하고있다. 다음은 몇 가지 샘플 코드입니다.matplotlib 극좌표 플롯에서 각을 만드는 방법은 시계 방향으로 0도 위로 이동 하시겠습니까?

import numpy as N 
import matplotlib.pyplot as P 

angle = N.arange(0, 360, 10, dtype=float) * N.pi/180.0 
arbitrary_data = N.abs(N.sin(angle)) + 0.1 * (N.random.random_sample(size=angle.shape) - 0.5) 

P.clf() 
P.polar(angle, arbitrary_data) 
P.show() 

0시는 플롯에서 3시 방향이고 각도는 반 시계 방향으로 향합니다. 데이터 시각화의 목적이 12시 방향에서 0 °이고 각도가 시계 방향으로 향하는 것이 더 유용 할 것입니다. 이 작업을 수행 할 수있는 방법이 있나요 데이터를 회전하고 수동으로 축 레이블을 변경하는 것 외에 이 있습니까?

답변

18

알아 냈습니다 - matplotlib을 사용하면 맞춤 투영을 만들 수 있습니다. 내가 PolarAxes에서 상속 한 것을 만들었습니다.

import numpy as N 
import matplotlib.pyplot as P 

from matplotlib.projections import PolarAxes, register_projection 
from matplotlib.transforms import Affine2D, Bbox, IdentityTransform 

class NorthPolarAxes(PolarAxes): 
    ''' 
    A variant of PolarAxes where theta starts pointing north and goes 
    clockwise. 
    ''' 
    name = 'northpolar' 

    class NorthPolarTransform(PolarAxes.PolarTransform): 
     def transform(self, tr): 
      xy = N.zeros(tr.shape, N.float_) 
      t = tr[:, 0:1] 
      r = tr[:, 1:2] 
      x = xy[:, 0:1] 
      y = xy[:, 1:2] 
      x[:] = r * N.sin(t) 
      y[:] = r * N.cos(t) 
      return xy 

     transform_non_affine = transform 

     def inverted(self): 
      return NorthPolarAxes.InvertedNorthPolarTransform() 

    class InvertedNorthPolarTransform(PolarAxes.InvertedPolarTransform): 
     def transform(self, xy): 
      x = xy[:, 0:1] 
      y = xy[:, 1:] 
      r = N.sqrt(x*x + y*y) 
      theta = N.arctan2(y, x) 
      return N.concatenate((theta, r), 1) 

     def inverted(self): 
      return NorthPolarAxes.NorthPolarTransform() 

    def _set_lim_and_transforms(self): 
     PolarAxes._set_lim_and_transforms(self) 
     self.transProjection = self.NorthPolarTransform() 
     self.transData = (
      self.transScale + 
      self.transProjection + 
      (self.transProjectionAffine + self.transAxes)) 
     self._xaxis_transform = (
      self.transProjection + 
      self.PolarAffine(IdentityTransform(), Bbox.unit()) + 
      self.transAxes) 
     self._xaxis_text1_transform = (
      self._theta_label1_position + 
      self._xaxis_transform) 
     self._yaxis_transform = (
      Affine2D().scale(N.pi * 2.0, 1.0) + 
      self.transData) 
     self._yaxis_text1_transform = (
      self._r_label1_position + 
      Affine2D().scale(1.0/360.0, 1.0) + 
      self._yaxis_transform) 

register_projection(NorthPolarAxes) 

angle = N.arange(0, 360, 10, dtype=float) * N.pi/180.0 
arbitrary_data = (N.abs(N.sin(angle)) + 0.1 * 
    (N.random.random_sample(size=angle.shape) - 0.5)) 

P.clf() 
P.subplot(1, 1, 1, projection='northpolar') 
P.plot(angle, arbitrary_data) 
P.show() 
+1

굉장합니다. 맞춤 프로젝션 예제에 포함되어 있어야합니다. – Mark

+1

코드베이스에 통합하는 것이 좋습니다. –

+0

FigureCanvasGTKAgg로 어떻게 작동하는지 알기 원하십니까? – Sardathrion

4

matplotlib/projections/polar.py를 수정할 수 있습니다.

는 말한다 여기서

def transform(self, tr): 
     xy = npy.zeros(tr.shape, npy.float_) 
     t = tr[:, 0:1] 
     r = tr[:, 1:2] 
     x = xy[:, 0:1] 
     y = xy[:, 1:2] 
     x[:] = - r * npy.sin(t) 
     y[:] = r * npy.cos(t) 
     return xy 

실제로 그것을 시도하지 않은, 당신은 X를 조정할 필요가 있습니다 [이 :]과 Y [:]로 지정을

def transform(self, tr): 
     xy = npy.zeros(tr.shape, npy.float_) 
     t = tr[:, 0:1] 
     r = tr[:, 1:2] 
     x = xy[:, 0:1] 
     y = xy[:, 1:2] 
     x[:] = r * npy.cos(t) 
     y[:] = r * npy.sin(t) 
     return xy 

이 말하십시오 너의 취향. 이 변경은 matplotlib polar plot을 사용하는 모든 프로그램에 영향을줍니다.

+0

이 독창적이지만, 코드를 패치하는 것은 부정 행위의 종류가, 그렇지? 그러나, 당신은 저에게 아이디어를주었습니다. Matplotlib을 사용하면 모든 종류의 변형이있는 축을 만들 수 있습니다. 아마도 내가 찾고있는 변환을 사용하여 대체 polar() 함수를 작성할 수 있습니다. – ptomato

2

모두 반전 루틴은 변환의 전체 경로를 사용해야합니다

return NorthPolarAxes.InvertedNorthPolarTransform() 

return NorthPolarAxes.NorthPolarTransform() 

지금 같은 NorthPolarAxesSubplot 같은 NorthPolarAxes의 자동 생성 서브 클래스가 변환 기능에 액세스 할 수 있습니다.

희망이 도움이됩니다.

28

이 질문을 업데이트하면 Matplotlib 1.1에서 세타 방향 (CW/CCW) 및 세타 = 0 위치를 설정하는 데 두 가지 방법이 있습니다.

체크 아웃 http://matplotlib.sourceforge.net/devel/add_new_projection.html#matplotlib.projections.polar.PolarAxes

는 특히, set_theta_direction()set_theta_offset()를 참조하십시오.

많은 사람들이 나침반 모양의 플롯을 시도합니다.

+1

극축 * ax *가있는 경우 : ** ax.set_theta_offset (0.5 * numpy.pi) ** – zinjaai

14

는 예와 klimaat의 답변을 확장하려면 :

import math 
angle=[0.,5.,10.,15.,20.,25.,30.,35.,40.,45.,50.,55.,60.,65.,70.,75.,\ 
     80.,85.,90.,95.,100.,105.,110.,115.,120.,125.] 

angle = [math.radians(a) for a in angle] 


lux=[12.67,12.97,12.49,14.58,12.46,12.59,11.26,10.71,17.74,25.95,\ 
    15.07,7.43,6.30,6.39,7.70,9.19,11.30,13.30,14.07,15.92,14.70,\ 
    10.70,6.27,2.69,1.29,0.81] 

import matplotlib.pyplot as P 
import matplotlib 
P.clf() 
sp = P.subplot(1, 1, 1, projection='polar') 
sp.set_theta_zero_location('N') 
sp.set_theta_direction(-1) 
P.plot(angle, lux) 
P.show()