顶部 0 度的顺时针极坐标图

发布于 2024-12-08 04:05:27 字数 2100 浏览 0 评论 0原文

如何制作顺时针极坐标图?有人问类似的问题此处如何使 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()

编辑:

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)正确吗?

How can I make a clockwise polar plot? Somebody ask a similar question here: How to make the angles in a matplotlib polar plot go clockwise with 0° at the top?, But I don't understand this:

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

How to use register_projection(NorthPolarAxes) correctly?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

度的依靠╰つ 2024-12-15 04:05:27

添加这些行:

ax.set_theta_direction(-1)
ax.set_theta_offset(pi/2.0)

Add these lines:

ax.set_theta_direction(-1)
ax.set_theta_offset(pi/2.0)
凌乱心跳 2024-12-15 04:05:27
ax.set_theta_direction(-1)
ax.set_theta_zero_location('N')

稍微更容易理解一些。

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

is slightly more comprehensible.

薄荷梦 2024-12-15 04:05:27

编辑:请注意,帕维尔提供了更好的解决方案


您链接到的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.
    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()

在此处输入图像描述


来自 matplotlib/projections/polar.pyPolarTransformInvertedPolarTransform 是因为我认为它们有助于解释每个组件的作用。这将指导您更改公式。

要获得顺时针方向的行为,您只需更改 t --> -t

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

InvertedEastPolarTransform 中,当 y > 时,我们要使用 2 * npy.pi - theta 0(上半平面),而不是当 y y 时0 。

Edit: Please note that Pavel has provided a much better solution!


The SO question you linked to contains the answer. Here is a slightly modified version of ptomato's NorthPolarAxes class with theta=0 pointing East and increasing clockwise:

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


The doc strings from matplotlib/projections/polar.py's PolarTransform and InvertedPolarTransform were added because I think they help explain what each component is doing. That guides you in changing the formulas.

To get clockwise behavior, you simply change t --> -t:

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

and in InvertedEastPolarTransform, we want to use 2 * npy.pi - theta when y > 0 (the upper half-plane) instead of when y < 0.

我纯我任性 2024-12-15 04:05:27

简答

使用以下代码创建子图:

kw = dict(projection = 'polar',     # <-- polar projection
          theta_offset = np.pi/2,   # <-- rotate theta
          theta_direction = -1)     # <-- theta clockwise

_, ax = plt.subplots(subplot_kw=kw)

解释

使用projection = 'polar'时,创建的子图使用类matplotlib.projections.polar.PolarAxes 接受参数 theta_offsettheta_direction

或者,您可以创建不带参数的极坐标子图,然后调用 ax.set_theta_zero_location` 和 ax.set_theta_direction 偏移 theta 轴并改变它的方向。

您可以查看其他方法,例如 set_thetalim

示例

import numpy as np
import matplotlib.pyplot as plt

# Theta
theta_deg = np.linspace(0, 360, num=145)
theta_rad = np.radians(theta_deg)

# Rho
rho = abs(np.cos(theta_rad))

# Create polar subplot
kw = dict(projection = 'polar',
          theta_offset = np.pi/2,
          theta_direction = -1)
_, ax = plt.subplots(subplot_kw=kw)

# Plot rho against theta
ax.plot(theta_rad, rho)

在此处输入图像描述

Short answer

Create your subplot using this code:

kw = dict(projection = 'polar',     # <-- polar projection
          theta_offset = np.pi/2,   # <-- rotate theta
          theta_direction = -1)     # <-- theta clockwise

_, ax = plt.subplots(subplot_kw=kw)

Explanation

When using projection = 'polar', the subplot created uses a projection of class matplotlib.projections.polar.PolarAxes which accepts parameters theta_offset and theta_direction.

Alternatively you can create the polar subplot without parameters, and later call ax.set_theta_zero_location` and ax.set_theta_direction to offset theta axis and change its direction.

You may look at other methods like set_thetalim

Example

import numpy as np
import matplotlib.pyplot as plt

# Theta
theta_deg = np.linspace(0, 360, num=145)
theta_rad = np.radians(theta_deg)

# Rho
rho = abs(np.cos(theta_rad))

# Create polar subplot
kw = dict(projection = 'polar',
          theta_offset = np.pi/2,
          theta_direction = -1)
_, ax = plt.subplots(subplot_kw=kw)

# Plot rho against theta
ax.plot(theta_rad, rho)

enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文