|
1 | 1 | from collections import OrderedDict
|
| 2 | +import math |
2 | 3 | import types
|
3 | 4 |
|
4 | 5 | import numpy as np
|
@@ -187,6 +188,7 @@ class ThetaFormatter(mticker.Formatter):
|
187 | 188 | Used to format the *theta* tick labels. Converts the native
|
188 | 189 | unit of radians into degrees and adds a degree symbol.
|
189 | 190 | """
|
| 191 | + |
190 | 192 | def __call__(self, x, pos=None):
|
191 | 193 | vmin, vmax = self.axis.get_view_interval()
|
192 | 194 | d = np.rad2deg(abs(vmax - vmin))
|
@@ -1403,11 +1405,40 @@ def set_rgrids(self, radii, labels=None, angle=None, fmt=None, **kwargs):
|
1403 | 1405 |
|
1404 | 1406 | def format_coord(self, theta, r):
|
1405 | 1407 | # 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() |
1406 | 1416 | if theta < 0:
|
1407 | 1417 | 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 | + ) |
1411 | 1442 |
|
1412 | 1443 | def get_data_ratio(self):
|
1413 | 1444 | """
|
|
0 commit comments