Ответ 1
добавить эти строки:
ax.set_theta_direction(-1)
ax.set_theta_offset(pi/2.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()
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)?
добавить эти строки:
ax.set_theta_direction(-1)
ax.set_theta_offset(pi/2.0)
ax.set_theta_direction(-1)
ax.set_theta_zero_location('N')
немного более понятным.
Изменить: обратите внимание, что Павел предоставил гораздо лучшее решение!
Вопрос SO, с которым вы связаны, содержит ответ. Вот немного измененная версия ptomato NorthPolarAxes
class с 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/info/2417794/2433287#2433287
https://stackoverflow.com/info/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()
Строки doc из 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
.