StrConverter.py 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. """StrConverter module containing class StrConverter."""
  2. import numpy as np
  3. import matplotlib.units as units
  4. __all__ = ['StrConverter']
  5. class StrConverter(units.ConversionInterface):
  6. """
  7. A Matplotlib converter class for string data values.
  8. Valid units for string are:
  9. - 'indexed' : Values are indexed as they are specified for plotting.
  10. - 'sorted' : Values are sorted alphanumerically.
  11. - 'inverted' : Values are inverted so that the first value is on top.
  12. - 'sorted-inverted' : A combination of 'sorted' and 'inverted'
  13. """
  14. @staticmethod
  15. def axisinfo(unit, axis):
  16. # docstring inherited
  17. return None
  18. @staticmethod
  19. def convert(value, unit, axis):
  20. # docstring inherited
  21. if value == []:
  22. return []
  23. # we delay loading to make matplotlib happy
  24. ax = axis.axes
  25. if axis is ax.xaxis:
  26. isXAxis = True
  27. else:
  28. isXAxis = False
  29. axis.get_major_ticks()
  30. ticks = axis.get_ticklocs()
  31. labels = axis.get_ticklabels()
  32. labels = [l.get_text() for l in labels if l.get_text()]
  33. if not labels:
  34. ticks = []
  35. labels = []
  36. if not np.iterable(value):
  37. value = [value]
  38. newValues = []
  39. for v in value:
  40. if v not in labels and v not in newValues:
  41. newValues.append(v)
  42. labels.extend(newValues)
  43. # DISABLED: This is disabled because matplotlib bar plots do not
  44. # DISABLED: recalculate the unit conversion of the data values
  45. # DISABLED: this is due to design and is not really a bug.
  46. # DISABLED: If this gets changed, then we can activate the following
  47. # DISABLED: block of code. Note that this works for line plots.
  48. # DISABLED if unit:
  49. # DISABLED if unit.find("sorted") > -1:
  50. # DISABLED labels.sort()
  51. # DISABLED if unit.find("inverted") > -1:
  52. # DISABLED labels = labels[::-1]
  53. # add padding (so they do not appear on the axes themselves)
  54. labels = [''] + labels + ['']
  55. ticks = list(range(len(labels)))
  56. ticks[0] = 0.5
  57. ticks[-1] = ticks[-1] - 0.5
  58. axis.set_ticks(ticks)
  59. axis.set_ticklabels(labels)
  60. # we have to do the following lines to make ax.autoscale_view work
  61. loc = axis.get_major_locator()
  62. loc.set_bounds(ticks[0], ticks[-1])
  63. if isXAxis:
  64. ax.set_xlim(ticks[0], ticks[-1])
  65. else:
  66. ax.set_ylim(ticks[0], ticks[-1])
  67. result = [ticks[labels.index(v)] for v in value]
  68. ax.viewLim.ignore(-1)
  69. return result
  70. @staticmethod
  71. def default_units(value, axis):
  72. # docstring inherited
  73. # The default behavior for string indexing.
  74. return "indexed"