Repository: matplotlib/matplotlib
File: lib/matplotlib/tests/test_contour.py (Python)

Code before:
            c = ax.contour(data, colors=colors[:-1],
                           levels=levels, extend=extend)

        plt.colorbar(c, ax=ax)

    _maybe_split_collections(split_collections)


@pytest.mark.parametrize("split_collections", [False, True])
@image_comparison(['contour_log_locator.svg'], style='mpl20', remove_text=False)
def test_log_locator_levels(split_collections):

    fig, ax = plt.subplots()

    N = 100
    x = np.linspace(-3.0, 3.0, N)
    y = np.linspace(-2.0, 2.0, N)

    X, Y = np.meshgrid(x, y)

    Z1 = np.exp(-X**2 - Y**2)
    Z2 = np.exp(-(X * 10)**2 - (Y * 10)**2)
    data = Z1 + 50 * Z2

    c = ax.contourf(data, locator=ticker.LogLocator())
    assert_array_almost_equal(c.levels, np.power(10.0, np.arange(-6, 3)))
    cb = fig.colorbar(c, ax=ax)
    assert_array_almost_equal(cb.ax.get_yticks(), c.levels)

    _maybe_split_collections(split_collections)


@pytest.mark.parametrize("n_levels", [2, 3, 4, 5, 6])
def test_lognorm_levels(n_levels):
    x = np.arange(100) + 1
    y = np.arange(100) + 1
    x, y = np.meshgrid(x, y)
    data = x**2 + y**2

    fig, ax = plt.subplots()
    im = ax.contour(x, y, data, norm=LogNorm(), levels=n_levels)
    cbar = fig.colorbar(im, ax=ax)

    levels = im.levels
    visible_levels = levels[(levels <= data.max()) & (levels >= data.min())]
    # levels parameter promises "no more than n+1 "nice" contour levels "
    assert len(visible_levels) <= n_levels + 1


@pytest.mark.parametrize("split_collections", [False, True])
@image_comparison(['contour_datetime_axis.png'], style='mpl20')

Review comment (bug):
FWIW, only the `n_levels=2` case fails on `main`. 

On main, the `levels` argument doesn't seem to do much of anything, there are always 4 `visible_levels`.

On the PR branch it still is a bit odd, there are only ever 2 (for levels= 2 or 3) or 4 (for levels>=4)

Is this expected? 

Code after:
    for c in cs.get_edgecolors():
        assert same_color(c, color)


@image_comparison(['contour_log_locator.svg'], style='mpl20', remove_text=False)
def test_log_locator_levels():

    fig, ax = plt.subplots()

    N = 100
    x = np.linspace(-3.0, 3.0, N)
    y = np.linspace(-2.0, 2.0, N)

    X, Y = np.meshgrid(x, y)

    Z1 = np.exp(-X**2 - Y**2)
    Z2 = np.exp(-(X * 10)**2 - (Y * 10)**2)
    data = Z1 + 50 * Z2

    c = ax.contourf(data, locator=ticker.LogLocator())
    assert_array_almost_equal(c.levels, np.power(10.0, np.arange(-6, 3)))
    cb = fig.colorbar(c, ax=ax)
    assert_array_almost_equal(cb.ax.get_yticks(), c.levels)


@pytest.mark.parametrize("n_levels", [2, 3, 4, 5, 6])
def test_lognorm_levels(n_levels):
    x, y = np.mgrid[1:10:0.1, 1:10:0.1]
    data = np.abs(np.sin(x)*np.exp(y))

    fig, ax = plt.subplots()
    im = ax.contour(x, y, data, norm=LogNorm(), levels=n_levels)
    fig.colorbar(im, ax=ax)

    levels = im.levels
    visible_levels = levels[(levels <= data.max()) & (levels >= data.min())]
    # levels parameter promises "no more than n+1 "nice" contour levels "
    assert len(visible_levels) <= n_levels + 1


@image_comparison(['contour_datetime_axis.png'], style='mpl20')
def test_contour_datetime_axis():
    fig = plt.figure()
    fig.subplots_adjust(hspace=0.4, top=0.98, bottom=.15)
    base = datetime.datetime(2013, 1, 1)
    x = np.array([base + datetime.timedelta(days=d) for d in range(20)])
    y = np.arange(20)
    z1, z2 = np.meshgrid(np.arange(20), np.arange(20))
    z = z1 * z2
    plt.subplot(221)
    plt.contour(x, y, z)