FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

polar plots do not properly handle units by jrevans · Pull Request #4905 · matplotlib/matplotlib · GitHub

Repository navigation

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .py  (2) All 1 file type selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
34 changes: 29 additions & 5 deletions lib/matplotlib/projections/polar.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,8 @@ def set_theta_offset(self, offset):
"""
Set the offset for the location of 0 in radians.
"""
# Make sure to strip away units
offset = self.convert_xunits(offset)
self._theta_offset = offset

def get_theta_offset(self):
Expand Down Expand Up @@ -521,9 +523,17 @@ def set_thetagrids(self, angles, labels=None, frac=None, fmt=None,
ACCEPTS: sequence of floats
"""
# Make sure we take into account unitized data
angles = self.convert_yunits(angles)
angles = np.asarray(angles, np.float_)
self.set_xticks(angles * (np.pi / 180.0))
if isinstance( angles[0], float ):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Why do we need this if-branch? Is convert_yunits() not returning radians? If not, is that a regression?

# If the data is floats it is assumed to be degrees (as per the
# docsting for this method)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

docstring

angles = np.asarray(angles, np.float_)
self.set_xticks(angles * (np.pi / 180.0))
else:
# The unit converters are defined to return radians

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Silly question, where is this documented/implemented?

angles = self.convert_xunits(angles)
angles = np.asarray(angles, np.float_)
self.set_xticks(angles)

if labels is not None:
self.set_xticklabels(labels)
elif fmt is not None:
Expand Down Expand Up @@ -560,12 +570,16 @@ def set_rgrids(self, radii, labels=None, angle=None, fmt=None,
ACCEPTS: sequence of floats
"""
# Make sure we take into account unitized data
radii = self.convert_xunits(radii)
radii = self.convert_yunits(radii)
radii = np.asarray(radii)
rmin = radii.min()
if rmin <= 0:
raise ValueError('radial grids must be strictly positive')

# Handle unitized data
if angle is not None:
angle = self.convert_xunits(angle)

self.set_yticks(radii)
if labels is not None:
self.set_yticklabels(labels)
Expand All @@ -591,11 +605,21 @@ def format_coord(self, theta, r):
Return a format string formatting the coordinate using Unicode
characters.
"""
# Strip away any units
r = self.convert_yunits(r)
if not isinstance( theta, float ):
theta = self.convert_xunits(theta)
# Stripping away units makes theta be in radians.
# convert to degrees
theta = theta * (180.0 / np.pi)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Maybe I am wrong, but this seems incorrect? The subsequent code already divides theta by pi and later multiplies by 180. In fact, the formatting string says that it is displaying radians first, then degrees second.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

I think you're right. Even though this function calls the arguments theta/r, it's called by matplotlib, so it's (sorta) x/y, meaning "theta" is in radians.


theta /= math.pi
# \u03b8: lower-case theta
# \u03c0: lower-case pi
# \u00b0: degree symbol
return '\u03b8=%0.3f\u03c0 (%0.3f\u00b0), r=%0.3f' % (theta, theta * 180.0, r)
s = '\u03b8=%0.3f\u03c0 (%0.3f\u00b0), r=%0.3f' % (theta, theta * 180.0, r)
s = s.encode( 'utf-8' )

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

This shouldn't be necessary and probably indicates a bug somewhere else. Returning unicode from this function is actually what we want. Can you describe which backend/platform you were using when you can across this problem?

return s

def get_data_ratio(self):
'''
Expand Down
101 changes: 101 additions & 0 deletions lib/matplotlib/tests/test_axes.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,107 @@ def test_polar_units():
assert_true(isinstance(plt.gca().get_xaxis().get_major_formatter(), units.UnitDblFormatter))


def test_polar_format_coord():

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

This needs a @cleanup decorator so global state does not leak.

import matplotlib.testing.jpl_units as units
units.register()

deg = units.UnitDbl(1.0, "deg")
km = units.UnitDbl(1.0, "km")

fig = plt.figure()
ax = plt.subplot(111, polar=True)

# Make sure this doesn't throw any exceptions
ax.format_coord( 30.0*deg, 4.0*km )

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Can you PEP8 the whitespace here?



@image_comparison(baseline_images=['polar_rgrids'])

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

As these tests add new image comparison tests, you'll also need to commit the new baseline images.

def test_polar_rgrids():
import matplotlib.testing.jpl_units as units
units.register()

pi = np.pi
deg = units.UnitDbl(1.0, "deg")
rad = units.UnitDbl(1.0, "rad")
km = units.UnitDbl(1.0, "km")

fig = plt.figure()

ax1 = plt.subplot(221, polar=True)
ax1.set_rgrids([45*deg, 90*deg], angle=60.0*deg)

ax2 = plt.subplot(222, polar=True)
ax2.set_rgrids([pi/4*rad, pi/2*rad], angle=60.0*deg)

ax3 = plt.subplot(223, polar=True)
ax3.set_rgrids([45*deg, 90*deg], angle=pi/3*rad)

ax4 = plt.subplot(224, polar=True)
ax4.set_rgrids([pi/4*rad, pi/2*rad], angle=pi/3*rad)


@image_comparison(baseline_images=['polar_rticks'])
def test_polar_rticks():
import matplotlib.testing.jpl_units as units
units.register()

pi = np.pi
deg = units.UnitDbl(1.0, "deg")
rad = units.UnitDbl(1.0, "rad")
km = units.UnitDbl(1.0, "km")

fig = plt.figure()

ax = plt.subplot(111, polar=True)
ax.set_rticks([1.5*km, 3.0*km, 4.5*km])

x1 = [30.0*deg, 45.0*deg, 60.0*deg, 90.0*deg]
y1 = [1.0*km, 2.0*km, 3.0*km, 4.0*km]

ax.plot( x1, y1 )


@image_comparison(baseline_images=['polar_teta_offset'])

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

teta -> theta

def test_polar_theta_offset():
import matplotlib.testing.jpl_units as units
units.register()

pi = np.pi
deg = units.UnitDbl(1.0, "deg")
rad = units.UnitDbl(1.0, "rad")
km = units.UnitDbl(1.0, "km")

fig = plt.figure()

ax1 = plt.subplot(211, polar=True)
ax1.set_theta_offset(45*deg)

ax2 = plt.subplot(212, polar=True)
ax2.set_theta_offset(pi/4*rad)


@image_comparison(baseline_images=['polar_tetagrids'])
def test_polar_thetagrids():
import matplotlib.testing.jpl_units as units
units.register()

pi = np.pi
deg = units.UnitDbl(1.0, "deg")
rad = units.UnitDbl(1.0, "rad")
km = units.UnitDbl(1.0, "km")

fig = plt.figure()

ax1 = plt.subplot(311, polar=True)
ax1.set_thetagrids([90*deg, 180*deg])

ax2 = plt.subplot(312, polar=True)
ax2.set_thetagrids([pi/2*rad, pi*rad])

ax3 = plt.subplot(313, polar=True)
ax3.set_thetagrids([90.0, 180.0])


@image_comparison(baseline_images=['polar_rmin'])
def test_polar_rmin():
r = np.arange(0, 3.0, 0.01)
Expand Down

Back | FazBrowse Home | New Git URL