Skip to content

Latest commit

 

History

History
87 lines (61 loc) · 3.17 KB

quad_as_tri.rst

File metadata and controls

87 lines (61 loc) · 3.17 KB

Quad as triangles

A contour line within a quad is, by default, a straight line between points on two of its edges. The quad_as_tri option divides each quad into four triangles using a virtual point at the centre (mean x, y of the corner points) and extra contour points are inserted where the contour level intersects the diagonals so that contour lines are piecewise linear within the triangles.

The z value of the central point is calculated depending on the :ref:`z_interp` setting; for the default z_interp=ZInterp.Linear this is the mean of the z values of the corner points. Corner masked triangles are not affected by this setting, only full unmasked quads.

.. name_supports::
   :filter: quad_as_tri

quad_as_tri is available for the serial and threaded algorithms. It is always disabled by default, so if required it must be explicitly requested:

>>> cont_gen = contour_generator(quad_as_tri=True, ...)

Note

quad_as_tri produces more detailed contours, but not necessarily smoother ones.

Here is an example of the difference between quad_as_tri=False and True for z values on a coarse grid that are given by z = np.sqrt(x**2 + y**2). On a finer grid the contours would be semicircular.

.. plot::
   :source-position: below

   from contourpy import contour_generator
   from contourpy.util.mpl_renderer import MplRenderer as Renderer
   import numpy as np

   x, y = np.meshgrid([-2, -1, 0, 1, 2], [0, 1, 2])
   z = np.sqrt(x**2 + y**2)

   renderer = Renderer(ncols=2, figsize=(8, 2.4))
   for ax in range(2):
      quad_as_tri = bool(ax)
      renderer.grid(x, y, ax=ax, quad_as_tri_alpha=ax*0.1)
      renderer.title(f"quad_as_tri={quad_as_tri}", ax=ax)

      cont_gen = contour_generator(x, y, z, quad_as_tri=quad_as_tri)
      for i, level in enumerate(np.arange(0.5, 2.51, 0.5)):
         lines = cont_gen.lines(level)
         renderer.lines(lines, cont_gen.line_type, ax=ax, color=f"C{i}", linewidth=2)

      renderer.z_values(x, y, z, ax=ax, quad_as_tri=quad_as_tri, fmt="0.2f")

   renderer.show()

Another situation in which quad_as_tri may be useful is shown below. The quad has three corners at the same z level so without quad_as_tri contour lines cut across diagonally.

.. plot::
   :source-position: below

   from contourpy import contour_generator
   from contourpy.util.mpl_renderer import MplRenderer as Renderer
   import numpy as np

   x = y = [0, 1]
   z = [[0, 0], [0, 4]]

   renderer = Renderer(ncols=2, figsize=(6, 3))
   for ax in range(2):
      quad_as_tri = bool(ax)
      renderer.grid(x, y, ax=ax, quad_as_tri_alpha=ax*0.1)
      renderer.title(f"quad_as_tri={quad_as_tri}", ax=ax)

      cont_gen = contour_generator(x, y, z, quad_as_tri=quad_as_tri)
      for i, level in enumerate(np.arange(0.0, 4.0, 0.4)):
         lines = cont_gen.lines(level)
         renderer.lines(lines, cont_gen.line_type, ax=ax, color=f"C{i}", linewidth=2)

      renderer.z_values(x, y, z, ax=ax, quad_as_tri=quad_as_tri)

   renderer.show()

Note

quad_as_tri=True produces contour lines and filled contours typically containing about three times as many points as quad_as_tri=False.