Skip to content

Commit

Permalink
Tweak doc words further
Browse files Browse the repository at this point in the history
  • Loading branch information
ianthomas23 committed Feb 16, 2022
1 parent 7742134 commit 71e90e6
Show file tree
Hide file tree
Showing 36 changed files with 712 additions and 704 deletions.
114 changes: 57 additions & 57 deletions docs/_static/filled_random_1000.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
122 changes: 61 additions & 61 deletions docs/_static/filled_random_1000_render.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
118 changes: 59 additions & 59 deletions docs/_static/filled_simple_1000.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
126 changes: 63 additions & 63 deletions docs/_static/filled_simple_1000_render.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
110 changes: 55 additions & 55 deletions docs/_static/lines_random_1000.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
110 changes: 55 additions & 55 deletions docs/_static/lines_random_1000_render.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
98 changes: 49 additions & 49 deletions docs/_static/lines_simple_1000.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
110 changes: 55 additions & 55 deletions docs/_static/lines_simple_1000_render.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
110 changes: 55 additions & 55 deletions docs/_static/threaded_random_1000.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
118 changes: 59 additions & 59 deletions docs/_static/threaded_simple_1000.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 4 additions & 4 deletions docs/benchmarks/calculation.rst
Expand Up @@ -37,13 +37,13 @@ than ``mpl2014`` when ``z`` is masked but about 5% slower when ``z`` is not mask

Other ``LineType`` are faster. ``LineType.Separate`` has a speedup of about 1.4 compared to
``LineType.SeparateCode``; most of the difference here is the time taken to allocate the extra 850
thousand NumPy arrays (one per line) and a small amount is the time taken to calculate the
Matplotlib kind codes to put in them.
thousand `NumPy`_ arrays (one per line) and a small amount is the time taken to calculate the
`Matplotlib`_ kind codes to put in them.

Both ``LineType.ChunkCombinedCode`` and ``LineType.ChunkCombinedOffset`` have similar timings with
a speedup of 2.3-2.5 compared to ``LineType.SeparateCode``. The big difference here again is in
array allocation, for a single chunk these two ``LineType`` allocate just two large arrays whereas
``LineType.SeparateCode`` allocates 1.7 million NumPy arrays, i.e. two per each line returned.
``LineType.SeparateCode`` allocates 1.7 million `NumPy`_ arrays, i.e. two per each line returned.

Filled contours
^^^^^^^^^^^^^^^
Expand All @@ -63,7 +63,7 @@ outer and hole boundaries in an interleaved format which need to be reordered, a
scales badly for a large outer boundary containing many holes as occurs here for unmasked ``z``.

Other ``FillType`` are faster, although ``FillType.OuterOffset`` is only marginally so as it
creates the same number of NumPy arrays as ``FillType.OuterCode`` but the arrays are shorter.
creates the same number of `NumPy`_ arrays as ``FillType.OuterCode`` but the arrays are shorter.

The other four ``FillType`` can be grouped in pairs: ``FillType.ChunkCombinedCodeOffset`` and
``FillType.ChunkCombinedOffsetOffset`` have a speedup of 1.8-1.95 compared to
Expand Down
39 changes: 20 additions & 19 deletions docs/benchmarks/rendering.rst
@@ -1,7 +1,7 @@
Calculation and rendering
-------------------------

This section considers the time taken to calculate contours and render them using Matplotlib on a
This section considers the time taken to calculate contours and render them using `Matplotlib`_ on a
900x900 pixel canvas (using the Agg backend) and save them to PNG files.

Contour lines
Expand All @@ -22,17 +22,17 @@ For ``LineType.SeparateCode`` all three algorithms take about the same time. Th
for these was about 1.3 seconds, so here the rendering takes almost 90% of the total time. This is
much more than for ``simple`` as the rendering is much more complicated.

The ``LineType`` that do not include Matplotlib kind codes are slower. You must generate these
codes yourself or allow Matplotlib to generate them for you, either way is slower than asking
The ``LineType`` that do not include `Matplotlib`_ kind codes are slower. You must generate these
codes yourself or allow `Matplotlib`_ to generate them for you, either way is slower than asking
``contourpy`` to generate them for you in C++.

``LineType.ChunkCombinedCode`` is significantly faster than ``LineType.SeparateCode`` with a speedup
of 1.9-2.3. This means that use of the ``serial`` algorithm with ``LineType.ChunkCombinedCode``
could halve the calculation and rendering time in Matplotlib for such complicated datasets.
The benefit here is in just having two NumPy arrays per chunk, one for points and one for codes,
which are ultimately used by Matplotlib's Agg renderer. Compare this with ``LineType.SeparateCode``
which passes 850 thousand pairs of NumPy arrays that need to be iterated over and shuffled in and
out of memory.
could halve the calculation and rendering time in `Matplotlib`_ for such complicated datasets.
The benefit here is in just having two `NumPy`_ arrays per chunk, one for points and one for codes,
which are ultimately used by `Matplotlib`_'s Agg renderer. Compare this with
``LineType.SeparateCode`` which passes 850 thousand pairs of `NumPy`_ arrays that need to be
iterated over.

Filled contours
^^^^^^^^^^^^^^^
Expand All @@ -50,36 +50,37 @@ For the ``random`` dataset above the performance of ``serial`` varies significan
For ``FillType.OuterCode`` it is faster than ``mpl2014`` by about 10-15%. The calculation for
``serial`` here was about 1.8 s so the rendering takes about four times as long as the calculation.

Three of the other ``serial`` ``FillType`` take longer because they either have to create Matplotlib
kind codes anyway, in a less efficient way than allowing ``contourpy`` to do so in C++, or in the
case of ``FillType.ChunkCombinedCodeOffset`` by breaking up the large points and codes arrays into
many smaller arrays, one per polygon (outer plus holes).
Three of the other ``serial`` ``FillType`` take longer because they either have to create
`Matplotlib`_ kind codes anyway, in a less efficient way than allowing ``contourpy`` to do so in
C++, or in the case of ``FillType.ChunkCombinedCodeOffset`` by breaking up the large points and
codes arrays into many smaller arrays, one per polygon (outer plus holes).

``FillType.ChunkCombinedCode`` and ``FillType.ChunkCombinedOffset`` are significantly faster than
``FillType.OuterCode`` with a speedup of 2.7-3.1 compared to ``serial`` and 3.1-3.5 compared to
``mpl2014``. Again this only has to send two NumPy arrays to Matplotlib for rendering rather than
850 thousand pairs of them.
``mpl2014``. Again this only has to send two `NumPy`_ arrays to `Matplotlib`_ for rendering rather
than 850 thousand pairs of them.

Care would be needed in switching to use ``FillType.ChunkCombinedCode`` in Matplotlib. Rendering of
filled polygons is much more computationally expensive than lines because with lines each is
Care would be needed in switching to use ``FillType.ChunkCombinedCode`` in `Matplotlib`_. Rendering
of filled polygons is much more computationally expensive than lines because with lines each is
independent and they can just be rendered in turn, whereas with polygons all of the boundaries need
to be processed at the same time so that each hole is associated with its corresponding outer
boundary. With ``FillType.OuterCode`` each polygon (outer plus holes) is passed to the renderer
separately, so the renderers task is easy. But with ``FillType.ChunkCombinedCode`` all of a chunk's
boundaries are passed together. Typically such a renderer uses a sweep line algorithm which is
O(N log N) where N is the number of points, so the sweep lines would be faster overall if sent a
large number of small arrays rather than one, but this speed advantage is much less than the
disadvantage of having to create and manipulate a large number of NumPy arrays.
disadvantage of having to create and manipulate a large number of `NumPy`_ arrays.

.. warning::

Although ``FillType.ChunkCombinedCode`` is empirically a good choice for the Agg renderer it may
not be so good for other backends.

If Matplotlib renderers could accept ``FillType.ChunkCombinedCodeOffset`` then we would have the
If `Matplotlib`_ renderers could accept ``FillType.ChunkCombinedCodeOffset`` then we would have the
best of both worlds. Only three arrays would need to passed per chunk, but the offsets could be
used to divide up the points and codes into individual polygons to be rendered separately. If this
could be done without creating extra NumPy arrays, e.g. at the C++ level, this would be very fast.
could be done without creating extra `NumPy`_ arrays, e.g. at the C++ level, this would be very
fast.

.. note::

Expand Down
4 changes: 2 additions & 2 deletions docs/benchmarks/threads.rst
Expand Up @@ -21,7 +21,7 @@ Using 6 threads the speedup is between 4.1 for ``lines`` and 4.7 for ``filled``.

Whether it is worth using ``threaded`` rather than ``serial`` for a particular problem depends on
the complexity of the dataset and what the calculated contours are to be used for. If they are
only needed for rendering using the Matplotlib Agg renderer, then for complicated problems the
only needed for rendering using the `Matplotlib`_ Agg renderer, then for complicated problems the
rendering time usually far exceeds the calculation time so a reduction in calculation time may
not be of much real-world benefit.

Expand All @@ -30,4 +30,4 @@ Using 6 threads the speedup is between 4.1 for ``lines`` and 4.7 for ``filled``.
The threaded algorithm is work in progress and should be considered experimental. It works fine
in an isolated environment using the ``contourpy`` tests and benchmarks, but needs to be
rigorously tested in real-world environments that that include mixed Python/C++ code and multiple
threads.
threads before it can be considered production quality.
24 changes: 12 additions & 12 deletions docs/changelog.rst
Expand Up @@ -6,18 +6,18 @@ Changelog
v0.0.5 (2022-02-13)
-------------------

* All ContourGenerator classes implement the same readonly properties (#91)
* Support string to enum conversion in contour_generator (#92)
* Default line/fill type for serial/threaded (#96)
* Check for negative z if using log interp (#97)
* contour_generator args vs kwargs (#99)
* String to enum moved from C++ to python (#100)
* Don't store mask in mpl2005 (#101)
* Sphinx documentation (#102)
* Fixed missing SW corner mask starts (#105)
* Finalise enum spellings (#106)
* Complete mask render function (#107)
* Test filled compare slow (#108)
* All ContourGenerator classes implement the same readonly properties `#91 <https://github.com/contourpy/contourpy/pull/91>`_
* Support string to enum conversion in contour_generator `#92 <https://github.com/contourpy/contourpy/pull/92>`_
* Default line/fill type for serial/threaded `#96 <https://github.com/contourpy/contourpy/pull/96>`_
* Check for negative z if using log interp `#97 <https://github.com/contourpy/contourpy/pull/97>`_
* contour_generator args vs kwargs `#99 <https://github.com/contourpy/contourpy/pull/99>`_
* String to enum moved from C++ to python `#100 <https://github.com/contourpy/contourpy/pull/100>`_
* Don't store mask in mpl2005 `#101 <https://github.com/contourpy/contourpy/pull/101>`_
* Sphinx documentation `#102 <https://github.com/contourpy/contourpy/pull/102>`_
* Fixed missing SW corner mask starts `#105 <https://github.com/contourpy/contourpy/pull/105>`_
* Finalise enum spellings `#106 <https://github.com/contourpy/contourpy/pull/106>`_
* Complete mask render function `#107 <https://github.com/contourpy/contourpy/pull/107>`_
* Test filled compare slow `#108 <https://github.com/contourpy/contourpy/pull/108>`_

v0.0.4 (2021-11-07)
-------------------
Expand Down
8 changes: 4 additions & 4 deletions docs/conf.py
Expand Up @@ -72,11 +72,11 @@
}

rst_epilog = """
.. _Bokeh: https://www.github.com/bokeh/bokeh/
.. _Matplotlib: https://www.github.com/matplotlib/matplotlib/
.. _NumPy: https://www.github.com/numpy/numpy/
.. _Bokeh: https://bokeh.org/
.. _Matplotlib: https://matplotlib.org/
.. _NumPy: https://numpy.org/
.. _PyPI: https://pypi.org/project/contourpy/
.. _conda-forge: https://anaconda.org/conda-forge/contourpy/
.. _github: https://www.github.com/contourpy/contourpy/
.. _pybind11: https://www.github.com/pybind/pybind11/
.. _pybind11: https://pybind11.readthedocs.io/
"""
5 changes: 3 additions & 2 deletions docs/config.rst
Expand Up @@ -4,14 +4,15 @@ Configurations
This page shows in graphical form all of the valid configurations of corner points being above or
below contour levels and their corresponding contour lines. These configurations are used in the
``serial`` and ``threaded`` algorithms, and also help to explain the contouring process.
The diagrams are generated by ``contourpy``'s test suite.
The diagrams are generated by ``contourpy``'s test suite to show that the code correctly deals with
all configurations.

Contour lines
-------------

The notation used for quad configurations is of the form 1001=9(1). The first 4 bits are the
z-levels of each of the corners with 0 being below the contour level and 1 above. The order
of the corners is, using compass directions (which is what is used in the C++ source code):
of the corners using compass directions (which is what is used in the C++ source code) is
NW, NE, SW and SE. This is followed by an equals sign and the decimal equivalent of the 4-bit binary
number in the range 0 to 15 inclusive for quads.

Expand Down
6 changes: 4 additions & 2 deletions docs/description.rst
@@ -1,3 +1,5 @@
.. _algorithm_description:

Algorithm description
=====================

Expand All @@ -19,8 +21,8 @@ and the other below, then the contour crosses that edge. The (x, y) position whe
level crosses the edge is determined by interpolation (see :ref:`z_interp`).

A single quad can have 0, 2 or 4 contour points, up to one per edge, depending upon how the contour
line intersects it. The contour points are connected in a predictable order with higher ``z`` on the
left as you follow them.
line intersects it. The contour points are connected together in a predictable order with higher
``z`` on the left as you follow them around.

If ``quad_as_tri=False`` then the points are connected with straight lines across each quad. The
only complexity here are quads that intersect the contour line on all four edges. Here the two
Expand Down
2 changes: 1 addition & 1 deletion docs/index.rst
Expand Up @@ -11,7 +11,7 @@ Matplotlib as a dependency.

Advantages of the new algorithm compared to Matplotlib's default algorithm of 2014 - 2022:

#. Improved performance in most situations (see :ref:`benchmarks`).
#. Improved performance in many situations (see :ref:`benchmarks`).
#. Multiple return types for both contour lines and filled contours, with different complexity and
performance tradeoffs (see :ref:`line_type` and :ref:`fill_type`).
#. Multiple ways to specify chunk sizes and/or counts (see :ref:`chunks`).
Expand Down
10 changes: 5 additions & 5 deletions docs/installation.rst
Expand Up @@ -21,7 +21,7 @@ macOS and Windows.
The only compulsory runtime dependency is `NumPy`_.

If you want to make use of one of contourpy's utility renderers int the :mod:`contourpy.util` module
If you want to make use of one of contourpy's utility renderers in the :mod:`contourpy.util` module
you will also have to install either `Matplotlib`_ or `Bokeh`_.

Installing from source
Expand Down Expand Up @@ -50,15 +50,15 @@ using:
$ pip install -ve .
To build in debug mode which enables ``assert`` statements in the C++ code use the
``CONTOURPY_DEBUG`` environment variable as follows:
To build in debug mode, which enables ``assert`` statements in the C++ code, use the
``CONTOURPY_DEBUG`` environment variable:

.. code-block:: console
$ CONTOURPY_DEBUG=1 pip install -ve .
To run the test suite, ensure that the required dependencies are installed and then run the tests
using ``pytest``:
To run the test suite, first ensure that the required dependencies are installed and then run the
tests using ``pytest``:

.. code-block:: console
Expand Down
19 changes: 9 additions & 10 deletions docs/quickstart.rst
Expand Up @@ -18,7 +18,7 @@ Import the :func:`~contourpy.contour_generator` function and call it to create a
>>> cont_gen
<contourpy._contourpy.SerialContourGenerator object at 0x7ff827fc4a30>

The hexadecimal number will be different, it is the address of the pybind11-wrapped C++ object.
The hexadecimal number will be different, it is the address of the `pybind11`_-wrapped C++ object.

Contour lines
-------------
Expand All @@ -30,7 +30,7 @@ Create some contour lines at a z-level of ``0.25``:
[array([[0.5, 1.0],
[1. , 0.75]])]

The output is a list of lines, here just one line that is a numpy array of shape ``(2, 2)``
The output is a list of lines, here just one line that is a `NumPy`_ array of shape ``(2, 2)``
consisting of two ``(x, y)`` points from ``(0.5, 1)`` to ``(1, 0.75)``.

.. note::
Expand All @@ -54,11 +54,11 @@ Create some filled contours between the z-levels of ``0.15`` and ``0.25``:
[array([0, 6], dtype=uint32)])

The output data is more complicated, it is a tuple of two lists each of which has a length of one
corresponding to a single polygon. The first numpy array has shape ``(6, 2)`` and is the
corresponding to a single polygon. The first `NumPy`_ array has shape ``(6, 2)`` and is the
``(x, y)`` coordinates of the 6 points that make up the polygon; the first and last points are the
same. The second numpy array is an integer array of offsets
into the points array; here the offsets cover the whole length of the points array indicating that
it is a single polygon. This is explained further in section XXX.
same. The second `NumPy`_ array is an integer array of offsets into the points array; here the
offsets cover the whole length of the points array indicating that it is a single polygon. This is
explained further in :ref:`fill_type`.

.. note::

Expand All @@ -69,8 +69,7 @@ Graphical output
----------------

It is easier to understand the contour lines and filled contours by looking at graphical output.
Here is the full example using the ``matplotlib`` renderer from the
:mod:`contourpy.util` module:
Here is the full example using the `Matplotlib`_ renderer from the :mod:`contourpy.util` module:

.. plot::
:source-position: below
Expand All @@ -88,7 +87,7 @@ Here is the full example using the ``matplotlib`` renderer from the
renderer.lines(lines, cont_gen.line_type, color="red", linewidth=2)
renderer.show()

Alternatively you can use the ``bokeh`` renderer from the :mod:`contourpy.util.bokeh_renderer`
Alternatively you can use the `Bokeh`_ renderer from the :mod:`contourpy.util.bokeh_renderer`
module. In the example above change the line

.. code-block:: python
Expand All @@ -101,4 +100,4 @@ into
from contourpy.util.bokeh_renderer import BokehRenderer as Renderer
Output for the ``bokeh`` renderer is sent to your web browser.
Output for the `Bokeh`_ renderer is sent to your web browser.
13 changes: 7 additions & 6 deletions docs/usage.rst
Expand Up @@ -9,22 +9,23 @@ The standard approach to use ``contourpy`` is to:

#. Call ``ContourGenerator`` member functions :meth:`~contourpy.SerialContourGenerator.lines` and/or
:meth:`~contourpy.SerialContourGenerator.filled` repeatedly to calculate and return contours for
that grid:
that (x, y, z) grid:

a. :meth:`~contourpy.SerialContourGenerator.lines` calculates contour lines at a particular
z-level.

b. :meth:`~contourpy.SerialContourGenerator.filled` calculates filled contours (polygons)
between two z-levels.

There are many options for :func:`~contourpy.contour_generator` but only ``z`` is compulsory and
There are many arguments for :func:`~contourpy.contour_generator` but only ``z`` is compulsory and
there are sensible defaults for the others.

.. note::

Although it is possible to create ``ContourGenerator`` objects directly from the pybind11-wrapped
C++ code in ``wrap.cpp``, this is discouraged as :func:`~contourpy.contour_generator` provides
better argument checking and also support for numpy masked ``z`` arrays.
Although it is possible to create ``ContourGenerator`` objects directly from the
`pybind11`_-wrapped C++ code in ``wrap.cpp``, this is discouraged as
:func:`~contourpy.contour_generator` provides better argument checking and also support for
numpy masked ``z`` arrays.

There are some utility functions in the :mod:`contourpy.util` module for testing and examples,
including producing graphical output using `Matplotlib`_ and `Bokeh`_.
including producing graphical output using `Matplotlib`_ and `Bokeh`_.
2 changes: 1 addition & 1 deletion docs/user_guide/chunks.rst
Expand Up @@ -13,7 +13,7 @@ Advantages of using chunks:

Disadvantages:

* There is a performance overhead of using chunks.
* There is a slight performance cost of using chunks.
* Some rendering algorithms show faint lines between neighbouring chunks.

.. note::
Expand Down

0 comments on commit 71e90e6

Please sign in to comment.