web-dev-qa-db-ja.com

matplotlib極プロットの角度を時計回りに0°を上にして移動させる方法は?

私はmatplotlibとnumpyを使用して極座標プロットを作成しています。サンプルコードは次のとおりです。

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

プロットの3時が0°で、角度が反時計回りになっていることがわかります。私のデータ視覚化の目的では、12時の位置を0°にし、角度を時計回りにする方が便利です。これを行う方法はありますか以外にデータを回転させ、軸ラベルを手動で変更しますか?

31
ptomato

私はそれを見つけました--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()
20
ptomato

この質問を更新すると、Matplotlib 1.1では、シータ方向(CW/CCW)とシータ= 0の位置を設定するための2つのメソッドがPolarAxesにあります。

チェックアウト http://matplotlib.sourceforge.net/devel/add_new_projection.html#matplotlib.projections.polar.PolarAxes

具体的には、set_theta_direction()およびset_theta_offset()を参照してください。

コンパスのようなプロットをしようとしている人がたくさんいるようです。

29
klimaat

例を挙げて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()
18
user90855

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.cos(t)
        y[:] = r * npy.sin(t)
        return xy

それを言わせてください:

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 [:]の割り当てを微調整する必要があるかもしれません。この変更は、matplotlib極プロットを使用するすべてのプログラムに影響します。

4

両方の反転ルーチンは、変換へのフルパスを使用する必要があります。

return NorthPolarAxes.InvertedNorthPolarTransform()

そして

return NorthPolarAxes.NorthPolarTransform()

これで、NorthPolarAxesSubplotなどのNorthPolarAxesの自動的に作成されたサブクラスが変換関数にアクセスできるようになりました。

お役に立てれば。

2
Rolv