You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

185 lines
5.1 KiB

4 years ago
  1. import matplotlib.cbook as cbook
  2. import matplotlib.artist as martist
  3. class Container(tuple):
  4. """
  5. Base class for containers.
  6. Containers are classes that collect semantically related Artists such as
  7. the bars of a bar plot.
  8. """
  9. def __repr__(self):
  10. return ("<{} object of {} artists>"
  11. .format(type(self).__name__, len(self)))
  12. def __new__(cls, *kl, **kwargs):
  13. return tuple.__new__(cls, kl[0])
  14. def __init__(self, kl, label=None):
  15. self.eventson = False # fire events only if eventson
  16. self._oid = 0 # an observer id
  17. self._propobservers = {} # a dict from oids to funcs
  18. self._remove_method = None
  19. self.set_label(label)
  20. @cbook.deprecated("3.0")
  21. def set_remove_method(self, f):
  22. self._remove_method = f
  23. def remove(self):
  24. for c in cbook.flatten(
  25. self, scalarp=lambda x: isinstance(x, martist.Artist)):
  26. if c is not None:
  27. c.remove()
  28. if self._remove_method:
  29. self._remove_method(self)
  30. def get_label(self):
  31. """
  32. Get the label used for this artist in the legend.
  33. """
  34. return self._label
  35. def set_label(self, s):
  36. """
  37. Set the label to *s* for auto legend.
  38. Parameters
  39. ----------
  40. s : string or anything printable with '%s' conversion.
  41. """
  42. if s is not None:
  43. self._label = '%s' % (s, )
  44. else:
  45. self._label = None
  46. self.pchanged()
  47. def add_callback(self, func):
  48. """
  49. Adds a callback function that will be called whenever one of
  50. the :class:`Artist`'s properties changes.
  51. Returns an *id* that is useful for removing the callback with
  52. :meth:`remove_callback` later.
  53. """
  54. oid = self._oid
  55. self._propobservers[oid] = func
  56. self._oid += 1
  57. return oid
  58. def remove_callback(self, oid):
  59. """
  60. Remove a callback based on its *id*.
  61. .. seealso::
  62. :meth:`add_callback`
  63. For adding callbacks
  64. """
  65. try:
  66. del self._propobservers[oid]
  67. except KeyError:
  68. pass
  69. def pchanged(self):
  70. """
  71. Fire an event when property changed, calling all of the
  72. registered callbacks.
  73. """
  74. for oid, func in list(self._propobservers.items()):
  75. func(self)
  76. def get_children(self):
  77. return [child for child in cbook.flatten(self) if child is not None]
  78. class BarContainer(Container):
  79. """
  80. Container for the artists of bar plots (e.g. created by `.Axes.bar`).
  81. The container can be treated as a tuple of the *patches* themselves.
  82. Additionally, you can access these and further parameters by the
  83. attributes.
  84. Attributes
  85. ----------
  86. patches : list of :class:`~matplotlib.patches.Rectangle`
  87. The artists of the bars.
  88. errorbar : None or :class:`~matplotlib.container.ErrorbarContainer`
  89. A container for the error bar artists if error bars are present.
  90. *None* otherwise.
  91. """
  92. def __init__(self, patches, errorbar=None, **kwargs):
  93. self.patches = patches
  94. self.errorbar = errorbar
  95. Container.__init__(self, patches, **kwargs)
  96. class ErrorbarContainer(Container):
  97. """
  98. Container for the artists of error bars (e.g. created by `.Axes.errorbar`).
  99. The container can be treated as the *lines* tuple itself.
  100. Additionally, you can access these and further parameters by the
  101. attributes.
  102. Attributes
  103. ----------
  104. lines : tuple
  105. Tuple of ``(data_line, caplines, barlinecols)``.
  106. - data_line : :class:`~matplotlib.lines.Line2D` instance of
  107. x, y plot markers and/or line.
  108. - caplines : tuple of :class:`~matplotlib.lines.Line2D` instances of
  109. the error bar caps.
  110. - barlinecols : list of :class:`~matplotlib.collections.LineCollection`
  111. with the horizontal and vertical error ranges.
  112. has_xerr, has_yerr : bool
  113. ``True`` if the errorbar has x/y errors.
  114. """
  115. def __init__(self, lines, has_xerr=False, has_yerr=False, **kwargs):
  116. self.lines = lines
  117. self.has_xerr = has_xerr
  118. self.has_yerr = has_yerr
  119. Container.__init__(self, lines, **kwargs)
  120. class StemContainer(Container):
  121. """
  122. Container for the artists created in a :meth:`.Axes.stem` plot.
  123. The container can be treated like a namedtuple ``(markerline, stemlines,
  124. baseline)``.
  125. Attributes
  126. ----------
  127. markerline : :class:`~matplotlib.lines.Line2D`
  128. The artist of the markers at the stem heads.
  129. stemlines : list of :class:`~matplotlib.lines.Line2D`
  130. The artists of the vertical lines for all stems.
  131. baseline : :class:`~matplotlib.lines.Line2D`
  132. The artist of the horizontal baseline.
  133. """
  134. def __init__(self, markerline_stemlines_baseline, **kwargs):
  135. markerline, stemlines, baseline = markerline_stemlines_baseline
  136. self.markerline = markerline
  137. self.stemlines = stemlines
  138. self.baseline = baseline
  139. Container.__init__(self, markerline_stemlines_baseline, **kwargs)