tricontour.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. import numpy as np
  2. from matplotlib import docstring
  3. from matplotlib.contour import ContourSet
  4. from matplotlib.tri.triangulation import Triangulation
  5. class TriContourSet(ContourSet):
  6. """
  7. Create and store a set of contour lines or filled regions for
  8. a triangular grid.
  9. User-callable method: clabel
  10. Attributes
  11. ----------
  12. ax
  13. The axes object in which the contours are drawn.
  14. collections
  15. A silent_list of LineCollections or PolyCollections.
  16. levels
  17. Contour levels.
  18. layers
  19. Same as levels for line contours; half-way between
  20. levels for filled contours. See :meth:`_process_colors`.
  21. """
  22. def __init__(self, ax, *args, **kwargs):
  23. """
  24. Draw triangular grid contour lines or filled regions,
  25. depending on whether keyword arg 'filled' is False
  26. (default) or True.
  27. The first argument of the initializer must be an axes
  28. object. The remaining arguments and keyword arguments
  29. are described in the docstring of `~.Axes.tricontour`.
  30. """
  31. ContourSet.__init__(self, ax, *args, **kwargs)
  32. def _process_args(self, *args, **kwargs):
  33. """
  34. Process args and kwargs.
  35. """
  36. if isinstance(args[0], TriContourSet):
  37. C = args[0].cppContourGenerator
  38. if self.levels is None:
  39. self.levels = args[0].levels
  40. else:
  41. from matplotlib import _tri
  42. tri, z = self._contour_args(args, kwargs)
  43. C = _tri.TriContourGenerator(tri.get_cpp_triangulation(), z)
  44. self._mins = [tri.x.min(), tri.y.min()]
  45. self._maxs = [tri.x.max(), tri.y.max()]
  46. self.cppContourGenerator = C
  47. return kwargs
  48. def _get_allsegs_and_allkinds(self):
  49. """
  50. Create and return allsegs and allkinds by calling underlying C code.
  51. """
  52. allsegs = []
  53. if self.filled:
  54. lowers, uppers = self._get_lowers_and_uppers()
  55. allkinds = []
  56. for lower, upper in zip(lowers, uppers):
  57. segs, kinds = self.cppContourGenerator.create_filled_contour(
  58. lower, upper)
  59. allsegs.append([segs])
  60. allkinds.append([kinds])
  61. else:
  62. allkinds = None
  63. for level in self.levels:
  64. segs = self.cppContourGenerator.create_contour(level)
  65. allsegs.append(segs)
  66. return allsegs, allkinds
  67. def _contour_args(self, args, kwargs):
  68. if self.filled:
  69. fn = 'contourf'
  70. else:
  71. fn = 'contour'
  72. tri, args, kwargs = Triangulation.get_from_args_and_kwargs(*args,
  73. **kwargs)
  74. z = np.ma.asarray(args[0])
  75. if z.shape != tri.x.shape:
  76. raise ValueError('z array must have same length as triangulation x'
  77. ' and y arrays')
  78. # z values must be finite, only need to check points that are included
  79. # in the triangulation.
  80. z_check = z[np.unique(tri.get_masked_triangles())]
  81. if np.ma.is_masked(z_check):
  82. raise ValueError('z must not contain masked points within the '
  83. 'triangulation')
  84. if not np.isfinite(z_check).all():
  85. raise ValueError('z array must not contain non-finite values '
  86. 'within the triangulation')
  87. z = np.ma.masked_invalid(z, copy=False)
  88. self.zmax = float(z_check.max())
  89. self.zmin = float(z_check.min())
  90. if self.logscale and self.zmin <= 0:
  91. raise ValueError('Cannot %s log of negative values.' % fn)
  92. self._process_contour_level_args(args[1:])
  93. return (tri, z)
  94. docstring.interpd.update(_tricontour_doc="""
  95. Draw contour %(type)s on an unstructured triangular grid.
  96. The triangulation can be specified in one of two ways; either ::
  97. %(func)s(triangulation, ...)
  98. where *triangulation* is a `.Triangulation` object, or ::
  99. %(func)s(x, y, ...)
  100. %(func)s(x, y, triangles, ...)
  101. %(func)s(x, y, triangles=triangles, ...)
  102. %(func)s(x, y, mask=mask, ...)
  103. %(func)s(x, y, triangles, mask=mask, ...)
  104. in which case a `.Triangulation` object will be created. See that class'
  105. docstring for an explanation of these cases.
  106. The remaining arguments may be::
  107. %(func)s(..., Z)
  108. where *Z* is the array of values to contour, one per point in the
  109. triangulation. The level values are chosen automatically.
  110. ::
  111. %(func)s(..., Z, levels)
  112. contour up to *levels+1* automatically chosen contour levels (*levels*
  113. intervals).
  114. ::
  115. %(func)s(..., Z, levels)
  116. draw contour %(type)s at the values specified in sequence *levels*, which must
  117. be in increasing order.
  118. ::
  119. %(func)s(Z, **kwargs)
  120. Use keyword arguments to control colors, linewidth, origin, cmap ... see below
  121. for more details.
  122. Parameters
  123. ----------
  124. triangulation : `.Triangulation`, optional
  125. The unstructured triangular grid.
  126. If specified, then *x*, *y*, *triangles*, and *mask* are not accepted.
  127. x, y : array-like, optional
  128. The coordinates of the values in *Z*.
  129. triangles : int array-like of shape (ntri, 3), optional
  130. For each triangle, the indices of the three points that make up the
  131. triangle, ordered in an anticlockwise manner. If not specified, the
  132. Delaunay triangulation is calculated.
  133. mask : bool array-like of shape (ntri), optional
  134. Which triangles are masked out.
  135. Z : array-like(N, M)
  136. The height values over which the contour is drawn.
  137. levels : int or array-like, optional
  138. Determines the number and positions of the contour lines / regions.
  139. If an int *n*, use `~matplotlib.ticker.MaxNLocator`, which tries to
  140. automatically choose no more than *n+1* "nice" contour levels between
  141. *vmin* and *vmax*.
  142. If array-like, draw contour lines at the specified levels. The values must
  143. be in increasing order.
  144. Returns
  145. -------
  146. `~matplotlib.tri.TriContourSet`
  147. Other Parameters
  148. ----------------
  149. colors : color string or sequence of colors, optional
  150. The colors of the levels, i.e., the contour %(type)s.
  151. The sequence is cycled for the levels in ascending order. If the sequence
  152. is shorter than the number of levels, it's repeated.
  153. As a shortcut, single color strings may be used in place of one-element
  154. lists, i.e. ``'red'`` instead of ``['red']`` to color all levels with the
  155. same color. This shortcut does only work for color strings, not for other
  156. ways of specifying colors.
  157. By default (value *None*), the colormap specified by *cmap* will be used.
  158. alpha : float, default: 1
  159. The alpha blending value, between 0 (transparent) and 1 (opaque).
  160. cmap : str or `.Colormap`, default: :rc:`image.cmap`
  161. A `.Colormap` instance or registered colormap name. The colormap maps the
  162. level values to colors.
  163. If both *colors* and *cmap* are given, an error is raised.
  164. norm : `~matplotlib.colors.Normalize`, optional
  165. If a colormap is used, the `.Normalize` instance scales the level values to
  166. the canonical colormap range [0, 1] for mapping to colors. If not given,
  167. the default linear scaling is used.
  168. origin : {*None*, 'upper', 'lower', 'image'}, default: None
  169. Determines the orientation and exact position of *Z* by specifying the
  170. position of ``Z[0, 0]``. This is only relevant, if *X*, *Y* are not given.
  171. - *None*: ``Z[0, 0]`` is at X=0, Y=0 in the lower left corner.
  172. - 'lower': ``Z[0, 0]`` is at X=0.5, Y=0.5 in the lower left corner.
  173. - 'upper': ``Z[0, 0]`` is at X=N+0.5, Y=0.5 in the upper left corner.
  174. - 'image': Use the value from :rc:`image.origin`.
  175. extent : (x0, x1, y0, y1), optional
  176. If *origin* is not *None*, then *extent* is interpreted as in `.imshow`: it
  177. gives the outer pixel boundaries. In this case, the position of Z[0, 0] is
  178. the center of the pixel, not a corner. If *origin* is *None*, then
  179. (*x0*, *y0*) is the position of Z[0, 0], and (*x1*, *y1*) is the position
  180. of Z[-1, -1].
  181. This argument is ignored if *X* and *Y* are specified in the call to
  182. contour.
  183. locator : ticker.Locator subclass, optional
  184. The locator is used to determine the contour levels if they are not given
  185. explicitly via *levels*.
  186. Defaults to `~.ticker.MaxNLocator`.
  187. extend : {'neither', 'both', 'min', 'max'}, default: 'neither'
  188. Determines the ``%(func)s``-coloring of values that are outside the
  189. *levels* range.
  190. If 'neither', values outside the *levels* range are not colored. If 'min',
  191. 'max' or 'both', color the values below, above or below and above the
  192. *levels* range.
  193. Values below ``min(levels)`` and above ``max(levels)`` are mapped to the
  194. under/over values of the `.Colormap`. Note that most colormaps do not have
  195. dedicated colors for these by default, so that the over and under values
  196. are the edge values of the colormap. You may want to set these values
  197. explicitly using `.Colormap.set_under` and `.Colormap.set_over`.
  198. .. note::
  199. An existing `.TriContourSet` does not get notified if properties of its
  200. colormap are changed. Therefore, an explicit call to
  201. `.ContourSet.changed()` is needed after modifying the colormap. The
  202. explicit call can be left out, if a colorbar is assigned to the
  203. `.TriContourSet` because it internally calls `.ContourSet.changed()`.
  204. xunits, yunits : registered units, optional
  205. Override axis units by specifying an instance of a
  206. :class:`matplotlib.units.ConversionInterface`.""")
  207. @docstring.Substitution(func='tricontour', type='lines')
  208. @docstring.dedent_interpd
  209. def tricontour(ax, *args, **kwargs):
  210. """
  211. %(_tricontour_doc)s
  212. linewidths : float or array-like, default: :rc:`contour.linewidth`
  213. The line width of the contour lines.
  214. If a number, all levels will be plotted with this linewidth.
  215. If a sequence, the levels in ascending order will be plotted with
  216. the linewidths in the order specified.
  217. If None, this falls back to :rc:`lines.linewidth`.
  218. linestyles : {*None*, 'solid', 'dashed', 'dashdot', 'dotted'}, optional
  219. If *linestyles* is *None*, the default is 'solid' unless the lines are
  220. monochrome. In that case, negative contours will take their linestyle
  221. from :rc:`contour.negative_linestyle` setting.
  222. *linestyles* can also be an iterable of the above strings specifying a
  223. set of linestyles to be used. If this iterable is shorter than the
  224. number of contour levels it will be repeated as necessary.
  225. """
  226. kwargs['filled'] = False
  227. return TriContourSet(ax, *args, **kwargs)
  228. @docstring.Substitution(func='tricontourf', type='regions')
  229. @docstring.dedent_interpd
  230. def tricontourf(ax, *args, **kwargs):
  231. """
  232. %(_tricontour_doc)s
  233. antialiased : bool, default: True
  234. Whether to use antialiasing.
  235. Notes
  236. -----
  237. `.tricontourf` fills intervals that are closed at the top; that is, for
  238. boundaries *z1* and *z2*, the filled region is::
  239. z1 < Z <= z2
  240. except for the lowest interval, which is closed on both sides (i.e. it
  241. includes the lowest value).
  242. """
  243. kwargs['filled'] = True
  244. return TriContourSet(ax, *args, **kwargs)