UnitDblConverter.py 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. """UnitDblConverter module containing class UnitDblConverter."""
  2. import numpy as np
  3. from matplotlib import cbook, units
  4. import matplotlib.projections.polar as polar
  5. __all__ = ['UnitDblConverter']
  6. # A special function for use with the matplotlib FuncFormatter class
  7. # for formatting axes with radian units.
  8. # This was copied from matplotlib example code.
  9. def rad_fn(x, pos=None):
  10. """Radian function formatter."""
  11. n = int((x / np.pi) * 2.0 + 0.25)
  12. if n == 0:
  13. return str(x)
  14. elif n == 1:
  15. return r'$\pi/2$'
  16. elif n == 2:
  17. return r'$\pi$'
  18. elif n % 2 == 0:
  19. return fr'${n//2}\pi$'
  20. else:
  21. return fr'${n}\pi/2$'
  22. class UnitDblConverter(units.ConversionInterface):
  23. """
  24. Provides Matplotlib conversion functionality for the Monte UnitDbl class.
  25. """
  26. # default for plotting
  27. defaults = {
  28. "distance": 'km',
  29. "angle": 'deg',
  30. "time": 'sec',
  31. }
  32. @staticmethod
  33. def axisinfo(unit, axis):
  34. # docstring inherited
  35. # Delay-load due to circular dependencies.
  36. import matplotlib.testing.jpl_units as U
  37. # Check to see if the value used for units is a string unit value
  38. # or an actual instance of a UnitDbl so that we can use the unit
  39. # value for the default axis label value.
  40. if unit:
  41. label = unit if isinstance(unit, str) else unit.label()
  42. else:
  43. label = None
  44. if label == "deg" and isinstance(axis.axes, polar.PolarAxes):
  45. # If we want degrees for a polar plot, use the PolarPlotFormatter
  46. majfmt = polar.PolarAxes.ThetaFormatter()
  47. else:
  48. majfmt = U.UnitDblFormatter(useOffset=False)
  49. return units.AxisInfo(majfmt=majfmt, label=label)
  50. @staticmethod
  51. def convert(value, unit, axis):
  52. # docstring inherited
  53. if not cbook.is_scalar_or_string(value):
  54. return [UnitDblConverter.convert(x, unit, axis) for x in value]
  55. # If no units were specified, then get the default units to use.
  56. if unit is None:
  57. unit = UnitDblConverter.default_units(value, axis)
  58. # Convert the incoming UnitDbl value/values to float/floats
  59. if isinstance(axis.axes, polar.PolarAxes) and value.type() == "angle":
  60. # Guarantee that units are radians for polar plots.
  61. return value.convert("rad")
  62. return value.convert(unit)
  63. @staticmethod
  64. def default_units(value, axis):
  65. # docstring inherited
  66. # Determine the default units based on the user preferences set for
  67. # default units when printing a UnitDbl.
  68. if cbook.is_scalar_or_string(value):
  69. return UnitDblConverter.defaults[value.type()]
  70. else:
  71. return UnitDblConverter.default_units(value[0], axis)