File: quad_as_tri.rst

package info (click to toggle)
contourpy 1.3.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 16,688 kB
  • sloc: python: 7,998; cpp: 6,241; makefile: 13
file content (87 lines) | stat: -rw-r--r-- 3,267 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
.. _quad_as_tri:

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 :ref:`serial` and :ref:`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::
   :separate-modes:
   :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, color="gray", alpha=0.2, 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)
      multi_lines = cont_gen.multi_lines(np.arange(0.5, 2.51, 0.5))
      renderer.multi_lines(multi_lines, cont_gen.line_type, ax=ax, 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::
   :separate-modes:
   :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, color="gray", alpha=0.2, 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)
      multi_lines = cont_gen.multi_lines(np.arange(0.0, 4.0, 0.4))
      renderer.multi_lines(multi_lines, cont_gen.line_type, ax=ax, 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``.