How to set Colorbar range with contourf [duplicate]
Asked Answered
C

2

10

How to reduce the colorbar limit when used with contourf ? The color bound from the graphs itself are well set with "vmin" and "vmax", but the colorbar bounds are not modified.

import numpy as np
import matplotlib.pyplot as plt
x = np.arange(20)
y = np.arange(20)
data = x[:,None]+y[None,:]

X,Y = np.meshgrid(x,y)
vmin = 0
vmax = 15

#My attempt
fig,ax = plt.subplots()
contourf_ = ax.contourf(X,Y,data, 400, vmin=vmin, vmax=vmax)
cbar = fig.colorbar(contourf_)
cbar.set_clim( vmin, vmax )

enter image description here

# With solution from https://mcmap.net/q/679177/-set-colorbar-range-with-contourf
levels = np.linspace(vmin, vmax, 400+1)
fig,ax = plt.subplots()
contourf_ = ax.contourf(X,Y,data, levels=levels, vmin=vmin, vmax=vmax)
cbar = fig.colorbar(contourf_)
plt.show()

enter image description here

solution from "Set Colorbar Range in matplotlib" works for pcolormesh, but not for contourf. The result I want looks like the following, but using contourf.

fig,ax = plt.subplots()
contourf_ = ax.pcolormesh(X,Y,data[1:,1:], vmin=vmin, vmax=vmax)
cbar = fig.colorbar(contourf_)

enter image description here

Solution from "set colorbar range with contourf" would be ok if the limit were extended, but not if they are reduced.

I am using matplotlib 3.0.2

Contraindicate answered 4/3, 2019 at 9:12 Comment(5)
What is wrong with the second solution? It looks like the desired outcome to me.Turnspit
I have edited my question for it to be clearer. I would like a results looking as the one using pcolormesh, but with contourfContraindicate
So it seems you want to make the background yellow. ax.set_facecolor(plt.cm.viridis(1.0))Turnspit
You can also clip the data at vmax or a bit higher before passing to contour.Interloper
Thanks, ax.set_facecolor(plt.cm.viridis(1.0)) does the trick, but only for either the lower or upper limit (in the above example, it would not work with vmin=3 and vmax=15 )Contraindicate
F
4

The following always produces a bar with colours that correspond to the colours in the graph, but shows no colours for values outside of the [vmin,vmax] range.

It can be edited (see inline comment) to give you exactly the result you want, but that the colours of the bar then still correspond to the colours in the graph, is only due to the specific colour map that's used (I think):

# Start copied from your attempt
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(20)
y = np.arange(20)
data = x[:, None] + y[None, :]

X, Y = np.meshgrid(x, y)
vmin = 0
vmax = 15


fig, ax = plt.subplots()

# Start of solution
from matplotlib.cm import ScalarMappable
levels = 400

level_boundaries = np.linspace(vmin, vmax, levels + 1)

quadcontourset = ax.contourf(
    X, Y, data,
    level_boundaries,  # change this to `levels` to get the result that you want
    vmin=vmin, vmax=vmax
)


fig.colorbar(
    ScalarMappable(norm=quadcontourset.norm, cmap=quadcontourset.cmap),
    ticks=range(vmin, vmax+5, 5),
    boundaries=level_boundaries,
    values=(level_boundaries[:-1] + level_boundaries[1:]) / 2,
)

Always correct solution that can't handle values outside [vmin,vmax]: always correct solution that can't handle values outside [vmin,vmax]

Requested solution: requested solution

Ferdinande answered 30/6, 2020 at 14:28 Comment(2)
Thanks! Really helps. Actually passing the ScalarMappable to colorbar() (instead of the contour) is enough to solve the issue. There is no need to explicitly set the levels and values.Contraindicate
Ah yes, agreed! Although you must also pass the levels and values when you want a "chunked" colour scale with only say 10 levels: otherwise the colour bar will be continuous instead of only showing the 10 levels.Ferdinande
R
4

I am not sure how long it has been there, but in matplotlib 3.5.0 in contourf there is an "extend" option which makes a cutesy little arrow on the colorbar. See the contourf help page. In your scenario we can do

fig,ax = plt.subplots()
contourf_ = ax.contourf(X,Y,data, levels=np.linspace(vmin,vmax,400),extend='max')
cbar = fig.colorbar(contourf_,ticks=range(vmin, vmax+3, 3))

enter image description here

Ramiah answered 11/12, 2021 at 13:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.