Python: clockwise polar plot
add these strings:
ax.set_theta_direction(-1)ax.set_theta_offset(pi/2.0)
ax.set_theta_direction(-1)ax.set_theta_zero_location('N')
is slightly more comprehensible.
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 pltimport numpy as npimport matplotlib.projections as projectionsimport matplotlib.transforms as mtransformsclass 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()
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
.