Skip to content

Contour

1
contour(X, Y, Z);

example_contour_1

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#include <matplot/matplot.h>
#include <thread>

int main() {
    using namespace matplot;

    vector_1d x = linspace(-2 * pi, 2 * pi);
    vector_1d y = linspace(0, 4 * pi);
    auto [X, Y] = meshgrid(x, y);
    vector_2d Z =
        transform(X, Y, [](double x, double y) { return sin(x) + cos(y); });
    contour(X, Y, Z);

    show();
    return 0;
}

More examples

example_contour_2

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#include <matplot/matplot.h>

int main() {
    using namespace matplot;

    auto [X, Y, Z] = peaks();
    contour(X, Y, Z, 20);

    show();
    return 0;
}

example_contour_3

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#include <matplot/matplot.h>

int main() {
    using namespace matplot;

    auto [X, Y, Z] = peaks();
    contour(X, Y, Z, std::vector<double>{1});

    show();
    return 0;
}

example_contour_4

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#include <matplot/matplot.h>

int main() {
    using namespace matplot;

    auto [X, Y, Z] = peaks();
    contour(X, Y, Z, "--");

    show();
    return 0;
}

example_contour_5

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#include <matplot/matplot.h>

int main() {
    using namespace matplot;

    vector_1d x = iota(-3, 0.2, 3);
    vector_1d y = iota(-3, 0.2, 3);
    auto [X, Y] = meshgrid(x, y);
    vector_2d Z = transform(X, Y, [](double x, double y) {
        return x * exp(-pow(x, 2.) - pow(y, 2.));
    });
    contour(X, Y, Z)->contour_text(true);

    show();
    return 0;
}

example_contour_6

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#include <matplot/matplot.h>

int main() {
    using namespace matplot;

    auto [X, Y, Z] = peaks();
    contour(X, Y, Z)->line_width(3);

    show();
    return 0;
}

example_contour_7

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#include <matplot/matplot.h>

int main() {
    using namespace matplot;

    auto [X, Y, Z] = peaks();
    auto c = contour(X, Y, Z);
    c->contour_text(true);
    c->font_size(15);
    c->font_color("blue");
    c->font_weight("bold");

    show();
    return 0;
}

example_contour_8

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#include <matplot/matplot.h>

int main() {
    using namespace matplot;

    auto [X, Y, Z] = peaks();
    for (size_t i = 0; i < Z.size(); ++i) {
        Z[i][25] = NaN;
    }
    contour(X, Y, Z)->contour_text(true);

    show();
    return 0;
}

All these subcategories depend on the contours type. They also depend on lazy evaluation for generating the contour lines. When the function draw is called in the contours class, it preprocesses all contour lines for a three-dimensional function.

Although it is relatively simple to show a heatmap with the values for the -axis, calculating contour lines relative to the -axis is more complex than it might seem at first. We provide the function contourc for calculating contour lines. This function uses an adaptation of the algorithm adopted by Matplotlib.

The algorithm creates a quad grid defined by the and values. It uses this grid to infer a contour line passing through positions with the same value. The algorithm sweeps through the grid twice to generate these lines. The first sweep looks for lines that start on the boundaries. The second sweep looks for interior closed loops.

Filled contours are closed polygons for pairs of contour levels. Some polygons for filled contours might be holes inside other polygons. The algorithm needs to keep track of these relationships so that we can render the polygons in their accurate order. To avoid an extra step that identifies this relationship between the polygons, the sweeping algorithm already identifies which polygons are holes for each level.

Once we find the quads with the contour line, the line is generated by interpolating the values around that quad.