8000 [Bug]: broken 'proportional' colorbar when using contourf+cmap+norm+extend · Issue #20963 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

Skip to content
[Bug]: broken 'proportional' colorbar when using contourf+cmap+norm+extend #20963
Closed
< 8000 !--/$-->
@jypeter

Description

@jypeter

Bug summary

I get a broken colorbar (see Outcome below) when using contourf and specifiying colors with cmap and norm instead of colors, and requesting a proportional colorbar, and using extend

Code for reproduction

import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl

# Data definition and plot based on the Official contourf demo
# https://matplotlib.org/stable/gallery/images_contours_and_fields/contourf_demo.html

origin = 'lower'

delta = 0.025

x = y = np.arange(-3.0, 3.01, delta)
X, Y = np.meshgrid(x, y)
Z1 = np.exp(-X**2 - Y**2)
Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2)
Z = (Z1 - Z2) * 2

nr, nc = Z.shape

fig2, ax2 = plt.subplots()

# Original demo levels
#  levels = [-1.5, -1, -0.5, 0, 0.5, 1]

# Irregular levels because we want to use a colorbar with
#   spacing='proportional'
levels = [-1.25, -0.5, -0.125, 0.125, 0.5, 1.25]

# Define a colormap and norm instead of using 'colors=' in the
# contourf call, BECAUSE we want to use the same cmap and norm for
# scatter and pcolormesh plots
cmap = mpl.colors.ListedColormap(['r', 'g', 'white', 'g', 'r'])
cmap.set_under('yellow')
cmap.set_over('cyan')
norm = mpl.colors.BoundaryNorm(levels, cmap.N)

CS3 = ax2.contourf(X, Y, Z, levels,
                   
                   # NO PROBLEM with spacing='proportional' if we
                   # define the colors with 'colors='
                   #
                   # colors=('r', 'g', 'b'),
                   
                   # The problem appears when we use cmap and norm
                   cmap=cmap,
                   norm=norm,
                   origin=origin,
                   
                   # NO PROBLEM with spacing='proportional' if we dont
                   # use extend
                   # extend='min'
                   extend='both'
)

# Our data range extends outside the range of levels; make
# data below the lowest contour level yellow, and above the
# highest level cyan:
# CS3.cmap.set_under('yellow')
# CS3.cmap.set_over('cyan')

ax2.set_title('Listed colors')

# Notice that the colorbar gets all the information it
# needs from the ContourSet object, CS3.
fig2.colorbar(CS3,
              # BROKEN colorbar if we use proportional spacing
              spacing='proportional',
              # spacing='uniform',
)

fig2.savefig('test_cb.png')

plt.show()

Actual outcome

I get the following warning

/home/share/unix_files/cdat/miniconda3_21-02/envs/cdatm_py3/lib/python3.8/site-packages/matplotlib/colorbar.py:1083: RuntimeWarning: invalid value encountered in double_scalars
  automin = (y[2] - y[1]) / clen
/home/share/unix_files/cdat/miniconda3_21-02/envs/cdatm_py3/lib/python3.8/site-packages/matplotlib/colorbar.py:1084: RuntimeWarning: invalid value encountered in double_scalars
  automax = (y[-2] - y[-3]) / clen

and a broken colorbar looking like
test_cb_proportional

Expected outcome

The colorbar is OK if I do use not all the ands specified above. Example below with spacing='uniform' instead of proportional
test_cb_uniform

Operating system

CentOS Linux release 7.9.2009 (Core)

Matplotlib Version

3.3.4

Matplotlib Backend

'Qt5Agg' and 'Agg'

Python version

3.8.8

Jupyter version

No response

Other libraries

No response

Installation

conda

Conda channel

conda-forge

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0