_tricontour.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. import numpy as np
  2. from matplotlib import _docstring
  3. from matplotlib.contour import ContourSet
  4. from matplotlib.tri._triangulation import Triangulation
  5. @_docstring.dedent_interpd
  6. class TriContourSet(ContourSet):
  7. """
  8. Create and store a set of contour lines or filled regions for
  9. a triangular grid.
  10. This class is typically not instantiated directly by the user but by
  11. `~.Axes.tricontour` and `~.Axes.tricontourf`.
  12. %(contour_set_attributes)s
  13. """
  14. def __init__(self, ax, *args, **kwargs):
  15. """
  16. Draw triangular grid contour lines or filled regions,
  17. depending on whether keyword arg *filled* is False
  18. (default) or True.
  19. The first argument of the initializer must be an `~.axes.Axes`
  20. object. The remaining arguments and keyword arguments
  21. are described in the docstring of `~.Axes.tricontour`.
  22. """
  23. super().__init__(ax, *args, **kwargs)
  24. def _process_args(self, *args, **kwargs):
  25. """
  26. Process args and kwargs.
  27. """
  28. if isinstance(args[0], TriContourSet):
  29. C = args[0]._contour_generator
  30. if self.levels is None:
  31. self.levels = args[0].levels
  32. self.zmin = args[0].zmin
  33. self.zmax = args[0].zmax
  34. self._mins = args[0]._mins
  35. self._maxs = args[0]._maxs
  36. else:
  37. from matplotlib import _tri
  38. tri, z = self._contour_args(args, kwargs)
  39. C = _tri.TriContourGenerator(tri.get_cpp_triangulation(), z)
  40. self._mins = [tri.x.min(), tri.y.min()]
  41. self._maxs = [tri.x.max(), tri.y.max()]
  42. self._contour_generator = C
  43. return kwargs
  44. def _contour_args(self, args, kwargs):
  45. tri, args, kwargs = Triangulation.get_from_args_and_kwargs(*args,
  46. **kwargs)
  47. z, *args = args
  48. z = np.ma.asarray(z)
  49. if z.shape != tri.x.shape:
  50. raise ValueError('z array must have same length as triangulation x'
  51. ' and y arrays')
  52. # z values must be finite, only need to check points that are included
  53. # in the triangulation.
  54. z_check = z[np.unique(tri.get_masked_triangles())]
  55. if np.ma.is_masked(z_check):
  56. raise ValueError('z must not contain masked points within the '
  57. 'triangulation')
  58. if not np.isfinite(z_check).all():
  59. raise ValueError('z array must not contain non-finite values '
  60. 'within the triangulation')
  61. z = np.ma.masked_invalid(z, copy=False)
  62. self.zmax = float(z_check.max())
  63. self.zmin = float(z_check.min())
  64. if self.logscale and self.zmin <= 0:
  65. func = 'contourf' if self.filled else 'contour'
  66. raise ValueError(f'Cannot {func} log of negative values.')
  67. self._process_contour_level_args(args, z.dtype)
  68. return (tri, z)
  69. _docstring.interpd.update(_tricontour_doc="""
  70. Draw contour %%(type)s on an unstructured triangular grid.
  71. Call signatures::
  72. %%(func)s(triangulation, z, [levels], ...)
  73. %%(func)s(x, y, z, [levels], *, [triangles=triangles], [mask=mask], ...)
  74. The triangular grid can be specified either by passing a `.Triangulation`
  75. object as the first parameter, or by passing the points *x*, *y* and
  76. optionally the *triangles* and a *mask*. See `.Triangulation` for an
  77. explanation of these parameters. If neither of *triangulation* or
  78. *triangles* are given, the triangulation is calculated on the fly.
  79. It is possible to pass *triangles* positionally, i.e.
  80. ``%%(func)s(x, y, triangles, z, ...)``. However, this is discouraged. For more
  81. clarity, pass *triangles* via keyword argument.
  82. Parameters
  83. ----------
  84. triangulation : `.Triangulation`, optional
  85. An already created triangular grid.
  86. x, y, triangles, mask
  87. Parameters defining the triangular grid. See `.Triangulation`.
  88. This is mutually exclusive with specifying *triangulation*.
  89. z : array-like
  90. The height values over which the contour is drawn. Color-mapping is
  91. controlled by *cmap*, *norm*, *vmin*, and *vmax*.
  92. .. note::
  93. All values in *z* must be finite. Hence, nan and inf values must
  94. either be removed or `~.Triangulation.set_mask` be used.
  95. levels : int or array-like, optional
  96. Determines the number and positions of the contour lines / regions.
  97. If an int *n*, use `~matplotlib.ticker.MaxNLocator`, which tries to
  98. automatically choose no more than *n+1* "nice" contour levels between
  99. between minimum and maximum numeric values of *Z*.
  100. If array-like, draw contour lines at the specified levels. The values must
  101. be in increasing order.
  102. Returns
  103. -------
  104. `~matplotlib.tri.TriContourSet`
  105. Other Parameters
  106. ----------------
  107. colors : color string or sequence of colors, optional
  108. The colors of the levels, i.e., the contour %%(type)s.
  109. The sequence is cycled for the levels in ascending order. If the sequence
  110. is shorter than the number of levels, it is repeated.
  111. As a shortcut, single color strings may be used in place of one-element
  112. lists, i.e. ``'red'`` instead of ``['red']`` to color all levels with the
  113. same color. This shortcut does only work for color strings, not for other
  114. ways of specifying colors.
  115. By default (value *None*), the colormap specified by *cmap* will be used.
  116. alpha : float, default: 1
  117. The alpha blending value, between 0 (transparent) and 1 (opaque).
  118. %(cmap_doc)s
  119. This parameter is ignored if *colors* is set.
  120. %(norm_doc)s
  121. This parameter is ignored if *colors* is set.
  122. %(vmin_vmax_doc)s
  123. If *vmin* or *vmax* are not given, the default color scaling is based on
  124. *levels*.
  125. This parameter is ignored if *colors* is set.
  126. origin : {*None*, 'upper', 'lower', 'image'}, default: None
  127. Determines the orientation and exact position of *z* by specifying the
  128. position of ``z[0, 0]``. This is only relevant, if *X*, *Y* are not given.
  129. - *None*: ``z[0, 0]`` is at X=0, Y=0 in the lower left corner.
  130. - 'lower': ``z[0, 0]`` is at X=0.5, Y=0.5 in the lower left corner.
  131. - 'upper': ``z[0, 0]`` is at X=N+0.5, Y=0.5 in the upper left corner.
  132. - 'image': Use the value from :rc:`image.origin`.
  133. extent : (x0, x1, y0, y1), optional
  134. If *origin* is not *None*, then *extent* is interpreted as in `.imshow`: it
  135. gives the outer pixel boundaries. In this case, the position of z[0, 0] is
  136. the center of the pixel, not a corner. If *origin* is *None*, then
  137. (*x0*, *y0*) is the position of z[0, 0], and (*x1*, *y1*) is the position
  138. of z[-1, -1].
  139. This argument is ignored if *X* and *Y* are specified in the call to
  140. contour.
  141. locator : ticker.Locator subclass, optional
  142. The locator is used to determine the contour levels if they are not given
  143. explicitly via *levels*.
  144. Defaults to `~.ticker.MaxNLocator`.
  145. extend : {'neither', 'both', 'min', 'max'}, default: 'neither'
  146. Determines the ``%%(func)s``-coloring of values that are outside the
  147. *levels* range.
  148. If 'neither', values outside the *levels* range are not colored. If 'min',
  149. 'max' or 'both', color the values below, above or below and above the
  150. *levels* range.
  151. Values below ``min(levels)`` and above ``max(levels)`` are mapped to the
  152. under/over values of the `.Colormap`. Note that most colormaps do not have
  153. dedicated colors for these by default, so that the over and under values
  154. are the edge values of the colormap. You may want to set these values
  155. explicitly using `.Colormap.set_under` and `.Colormap.set_over`.
  156. .. note::
  157. An existing `.TriContourSet` does not get notified if properties of its
  158. colormap are changed. Therefore, an explicit call to
  159. `.ContourSet.changed()` is needed after modifying the colormap. The
  160. explicit call can be left out, if a colorbar is assigned to the
  161. `.TriContourSet` because it internally calls `.ContourSet.changed()`.
  162. xunits, yunits : registered units, optional
  163. Override axis units by specifying an instance of a
  164. :class:`matplotlib.units.ConversionInterface`.
  165. antialiased : bool, optional
  166. Enable antialiasing, overriding the defaults. For
  167. filled contours, the default is *True*. For line contours,
  168. it is taken from :rc:`lines.antialiased`.""" % _docstring.interpd.params)
  169. @_docstring.Substitution(func='tricontour', type='lines')
  170. @_docstring.dedent_interpd
  171. def tricontour(ax, *args, **kwargs):
  172. """
  173. %(_tricontour_doc)s
  174. linewidths : float or array-like, default: :rc:`contour.linewidth`
  175. The line width of the contour lines.
  176. If a number, all levels will be plotted with this linewidth.
  177. If a sequence, the levels in ascending order will be plotted with
  178. the linewidths in the order specified.
  179. If None, this falls back to :rc:`lines.linewidth`.
  180. linestyles : {*None*, 'solid', 'dashed', 'dashdot', 'dotted'}, optional
  181. If *linestyles* is *None*, the default is 'solid' unless the lines are
  182. monochrome. In that case, negative contours will take their linestyle
  183. from :rc:`contour.negative_linestyle` setting.
  184. *linestyles* can also be an iterable of the above strings specifying a
  185. set of linestyles to be used. If this iterable is shorter than the
  186. number of contour levels it will be repeated as necessary.
  187. """
  188. kwargs['filled'] = False
  189. return TriContourSet(ax, *args, **kwargs)
  190. @_docstring.Substitution(func='tricontourf', type='regions')
  191. @_docstring.dedent_interpd
  192. def tricontourf(ax, *args, **kwargs):
  193. """
  194. %(_tricontour_doc)s
  195. hatches : list[str], optional
  196. A list of crosshatch patterns to use on the filled areas.
  197. If None, no hatching will be added to the contour.
  198. Hatching is supported in the PostScript, PDF, SVG and Agg
  199. backends only.
  200. Notes
  201. -----
  202. `.tricontourf` fills intervals that are closed at the top; that is, for
  203. boundaries *z1* and *z2*, the filled region is::
  204. z1 < Z <= z2
  205. except for the lowest interval, which is closed on both sides (i.e. it
  206. includes the lowest value).
  207. """
  208. kwargs['filled'] = True
  209. return TriContourSet(ax, *args, **kwargs)