2011-10-05 31 views
10

Làm cách nào để tạo một âm mưu theo chiều kim đồng hồ? Ai đó hỏi một câu hỏi tương tự here: How to make the angles in a matplotlib polar plot go clockwise with 0° at the top?
Nhưng tôi không hiểu điều này.Python: cốt truyện theo chiều kim đồng hồ

import matplotlib.pyplot as plt 
import numpy as np 

fig = plt.figure() 
ax = fig.add_subplot(111, polar=True) 
ax.grid(True) 

theta = np.arange(0,370,10) 
theta = [i*np.pi/180.0 for i in theta] # convert to radians 

x = [3.00001,3,3,3,3,3,3,3,3,3,3,3,3,3,2.5,2,2,2,2,2,1.5,1.5,1,1.5,2,2,2.5,2.5,3,3,3,3,3,3,3,3,3] 
ax.plot(theta, x) 
plt.show() 

EDIT:

import matplotlib.pyplot as plt 
import numpy as np 
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 = np.zeros(tr.shape, np.float_) 
      t = tr[:, 0:1] 
      r = tr[:, 1:2] 
      x = xy[:, 0:1] 
      y = xy[:, 1:2] 
      x[:] = r * np.sin(t) 
      y[:] = r * np.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 = np.sqrt(x*x + y*y) 

fig = plt.figure() 
register_projection(NorthPolarAxes) 
ax=plt.subplot(1, 1, 1, projection='northpolar')  
theta=np.linspace(0,2*np.pi,37) 
x = [3.00001,3,3,3,3,3,3,3,3,3,3,3,3,3,2.5,2,2,2,2, 
    2,1.5,1.5,1,1.5,2,2,2.5,2.5,3,3,3,3,3,3,3,3,3] 
ax.plot(theta, x) 
plt.show() 

Làm thế nào để sử dụng một cách chính xác register_projection (NorthPolarAxes)?

Trả lời

14

thêm các chuỗi:

ax.set_theta_direction(-1) 

ax.set_theta_offset(pi/2.0) 
3

Chỉnh sửa: Xin lưu ý rằng Pavel đã cung cấp much better solution!


Câu hỏi SO bạn đã liên kết chứa câu trả lời. Đây là một phiên bản sửa đổi nhẹ của ptomato's NorthPolarAxes class với theta=0 chỉ Đông và tăng chiều kim đồng hồ:

import matplotlib.pyplot as plt 
import numpy as np 
import matplotlib.projections as projections 
import matplotlib.transforms as mtransforms 

class EastPolarAxes(projections.PolarAxes): 
    ''' 
    A variant of PolarAxes where theta starts pointing East and goes 
    clockwise. 
    https://stackoverflow.com/questions/2417794/2433287#2433287 
    https://stackoverflow.com/questions/7664153/7664545#7664545  
    ''' 
    name = 'eastpolar' 

    class EastPolarTransform(projections.PolarAxes.PolarTransform): 
     """ 
     The base polar transform. This handles projection *theta* and 
     *r* into Cartesian coordinate space *x* and *y*, but does not 
     perform the ultimate affine transformation into the correct 
     position. 
     """   
     def transform(self, tr): 
      xy = np.zeros(tr.shape, np.float_) 
      t = tr[:, 0:1] 
      r = tr[:, 1:2] 
      x = xy[:, 0:1] 
      y = xy[:, 1:2] 
      x[:] = r * np.cos(-t) 
      y[:] = r * np.sin(-t) 
      return xy 

     transform_non_affine = transform 

     def inverted(self): 
      return EastPolarAxes.InvertedEastPolarTransform() 

    class InvertedEastPolarTransform(projections.PolarAxes.InvertedPolarTransform): 
     """ 
     The inverse of the polar transform, mapping Cartesian 
     coordinate space *x* and *y* back to *theta* and *r*. 
     """   
     def transform(self, xy): 
      x = xy[:, 0:1] 
      y = xy[:, 1:] 
      r = np.sqrt(x*x + y*y) 
      theta = npy.arccos(x/r) 
      theta = npy.where(y > 0, 2 * npy.pi - theta, theta) 
      return np.concatenate((theta, r), 1) 

     def inverted(self): 
      return EastPolarAxes.EastPolarTransform() 

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

def eastpolar_axes(): 
    projections.register_projection(EastPolarAxes) 
    ax=plt.subplot(1, 1, 1, projection='eastpolar')  
    theta=np.linspace(0,2*np.pi,37) 
    x = [3.00001,3,3,3,3,3,3,3,3,3,3,3,3,3,2.5,2,2,2,2, 
     2,1.5,1.5,1,1.5,2,2,2.5,2.5,3,3,3,3,3,3,3,3,3] 
    ax.plot(theta, x) 
    plt.show() 

eastpolar_axes() 

enter image description here


Các chuỗi doc từ matplotlib/projections/polar.py 's PolarTransformInvertedPolarTransform đã được thêm vào bởi vì tôi nghĩ rằng họ giúp giải thích những gì mỗi thành phần đang hoạt động. Điều đó hướng dẫn bạn trong việc thay đổi các công thức.

Để có được hành vi chiều kim đồng hồ, bạn chỉ cần thay đổi t ->-t:

 x[:] = r * np.cos(-t) 
     y[:] = r * np.sin(-t) 

và trong InvertedEastPolarTransform, chúng tôi muốn sử dụng 2 * npy.pi - theta khi y > 0 (phía trên nửa mặt phẳng) thay vì khi y < 0.

+0

Câu trả lời do Pavel đưa ra và đơn giản hơn rất nhiều. –

+0

@PabloReyes: Cảm ơn bạn đã thông báo cho tôi. – unutbu

7

ax.set_theta_direction(-1) ax.set_theta_direction('N')

là hơi dễ hiểu hơn.

Các vấn đề liên quan