Python: полярный график по часовой стрелке - PullRequest
11 голосов
/ 05 октября 2011

Как сделать график по часовой стрелке? Кто-то задает похожий вопрос здесь : Как заставить углы на полярном графике matplotlib двигаться по часовой стрелке с 0 ° вверху?
Но я этого не понимаю.

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

Как правильно использовать register_projection (NorthPolarAxes)?

Ответы [ 3 ]

17 голосов
/ 28 августа 2013

добавить эти строки:

ax.set_theta_direction(-1)

ax.set_theta_offset(pi/2.0)
7 голосов
/ 04 октября 2014

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

немного более понятно.

3 голосов
/ 05 октября 2011

Редактировать: Обратите внимание, что Павел предоставил гораздо лучшее решение !


SO вопрос, на который вы ссылались, содержит ответ. Вот слегка измененная версия класса ptomato NorthPolarAxes класса с theta=0, указывающим на восток и увеличивающимся по часовой стрелке:

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.
    /1568805/kak-sdelat-tak-chtoby-ugly-v-polyarnom-grafike-matplotlib-shli-po-chasovoi-strelke-s-0-vverhu#1568811
    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


Строки документа из matplotlib/projections/polar.py PolarTransform и InvertedPolarTransform были добавлены, потому что я думаю, что они помогают объяснить, что делает каждый компонент. Это поможет вам изменить формулы.

Чтобы получить поведение по часовой стрелке, просто измените t -> -t:

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

и в InvertedEastPolarTransform мы хотим использовать 2 * npy.pi - theta, когда y > 0 (верхняя полуплоскость), а не когда y < 0.

...