Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2058905

Browse files
committed
For polar plots, report cursor position with correct precision.
... similar to what's done for cartesian plots (in ScalarFormatter.format_data_short).
1 parent 0520d99 commit 2058905

File tree

2 files changed

+48
-3
lines changed

2 files changed

+48
-3
lines changed

lib/matplotlib/projections/polar.py

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from collections import OrderedDict
2+
import math
23
import types
34

45
import numpy as np
@@ -187,6 +188,7 @@ class ThetaFormatter(mticker.Formatter):
187188
Used to format the *theta* tick labels. Converts the native
188189
unit of radians into degrees and adds a degree symbol.
189190
"""
191+
190192
def __call__(self, x, pos=None):
191193
vmin, vmax = self.axis.get_view_interval()
192194
d = np.rad2deg(abs(vmax - vmin))
@@ -1403,11 +1405,40 @@ def set_rgrids(self, radii, labels=None, angle=None, fmt=None, **kwargs):
14031405

14041406
def format_coord(self, theta, r):
14051407
# docstring inherited
1408+
screen_xy = self.transData.transform((theta, r))
1409+
screen_xys = screen_xy + np.stack(
1410+
np.meshgrid([-1, 0, 1], [-1, 0, 1])).reshape((2, -1)).T
1411+
ts, rs = self.transData.inverted().transform(screen_xys).T
1412+
delta_t = abs((ts - theta + np.pi) % (2 * np.pi) - np.pi).max()
1413+
delta_t_halfturns = delta_t / np.pi
1414+
delta_t_degrees = delta_t_halfturns * 180
1415+
delta_r = abs(rs - r).max()
14061416
if theta < 0:
14071417
theta += 2 * np.pi
1408-
theta /= np.pi
1409-
return ('\N{GREEK SMALL LETTER THETA}=%0.3f\N{GREEK SMALL LETTER PI} '
1410-
'(%0.3f\N{DEGREE SIGN}), r=%0.3f') % (theta, theta * 180.0, r)
1418+
theta_halfturns = theta / np.pi
1419+
theta_degrees = theta_halfturns * 180
1420+
1421+
# See ScalarFormatter.format_data_short. For r, use #g-formatting
1422+
# (as for linear axes), but for theta, use f-formatting as scientific
1423+
# notation doesn't make sense and the trailing dot is ugly.
1424+
def format_sig(value, delta, opt, fmt):
1425+
digits_post_decimal = math.floor(math.log10(delta))
1426+
digits_offset = (
1427+
# For "f", only count digits after decimal point.
1428+
0 if fmt == "f"
1429+
# For "g", offset by digits before the decimal point.
1430+
else math.floor(math.log10(abs(value))) + 1 if value
1431+
# For "g", 0 contributes 1 "digit" before the decimal point.
1432+
else 1)
1433+
fmt_prec = max(0, digits_offset - digits_post_decimal)
1434+
return f"{value:-{opt}.{fmt_prec}{fmt}}"
1435+
1436+
return ('\N{GREEK SMALL LETTER THETA}={}\N{GREEK SMALL LETTER PI} '
1437+
'({}\N{DEGREE SIGN}), r={}').format(
1438+
format_sig(theta_halfturns, delta_t_halfturns, "", "f"),
1439+
format_sig(theta_degrees, delta_t_degrees, "", "f"),
1440+
format_sig(r, delta_r, "#", "g"),
1441+
)
14111442

14121443
def get_data_ratio(self):
14131444
"""

lib/matplotlib/tests/test_polar.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,3 +410,17 @@ def test_axvline_axvspan_do_not_modify_rlims():
410410
ax.axvline(.5)
411411
ax.plot([.1, .2])
412412
assert ax.get_ylim() == (0, .2)
413+
414+
415+
def test_cursor_precision():
416+
ax = plt.subplot(projection="polar")
417+
# Higher radii correspond to higher theta-precisions.
418+
assert ax.format_coord(0, 0) == "θ=0π (0°), r=0.000"
419+
assert ax.format_coord(0, .1) == "θ=0.00π (0°), r=0.100"
420+
assert ax.format_coord(0, 1) == "θ=0.000π (0.0°), r=1.000"
421+
assert ax.format_coord(1, 0) == "θ=0.3π (57°), r=0.000"
422+
assert ax.format_coord(1, .1) == "θ=0.32π (57°), r=0.100"
423+
assert ax.format_coord(1, 1) == "θ=0.318π (57.3°), r=1.000"
424+
assert ax.format_coord(2, 0) == "θ=0.6π (115°), r=0.000"
425+
assert ax.format_coord(2, .1) == "θ=0.64π (115°), r=0.100"
426+
assert ax.format_coord(2, 1) == "θ=0.637π (114.6°), r=1.000"

0 commit comments

Comments
 (0)