2011-10-05 780 views
10

¿Cómo puedo hacer un diagrama en el sentido de las agujas del reloj? Alguien hace una pregunta similar here: How to make the angles in a matplotlib polar plot go clockwise with 0° at the top?
Pero no entiendo esto.Python: diagrama polar en el sentido de las agujas del reloj

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() 

Cómo usar correctamente register_projection (NorthPolarAxes)?

Respuesta

14

añadir estas cadenas:

ax.set_theta_direction(-1) 

ax.set_theta_offset(pi/2.0) 
3

Editar: Tenga en cuenta que Pavel ha proporcionado un much better solution!


El SO pregunta que contiene vinculados a la respuesta. Aquí es una versión ligeramente modificada de ptomato's NorthPolarAxes class con theta=0 señalando Medio y el aumento de las agujas del reloj: se añadieron

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


Las cadenas de documentación de matplotlib/projections/polar.py 's PolarTransform y InvertedPolarTransform porque creo que ayudan a explicar por qué cada componente está haciendo. Eso te guía para cambiar las fórmulas.

Para obtener un comportamiento hacia la derecha, basta con cambiar t ->-t:

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

y en InvertedEastPolarTransform, queremos utilizar 2 * npy.pi - theta cuando y > 0 (el semiplano superior) en lugar de cuando y < 0.

+0

La respuesta dada por Pavel funciona y es mucho más simple. –

+0

@PabloReyes: Gracias por notificarme. – unutbu

7

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

es ligeramente más comprensible.

Cuestiones relacionadas