如何使用contourf设置Colorbar范围

10
如何在使用contourf时减小色条限制?图形本身的颜色边界已经通过"vmin"和"vmax"很好地设置,但色条边界没有被修改。
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://dev59.com/A1QJ5IYBdhLWcg3wiWeb
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

从 "在matplotlib中设置Colorbar范围" 的解决方案适用于pcolormesh,但不适用于contourf。我想要的结果看起来像下面这样,但是要使用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

如果限制被扩大,那么从 "set colorbar range with contourf" 的解决方案可能还可以接受,但如果限制被缩小,就不行了。
我正在使用 matplotlib 3.0.2。

2
第二种解决方案有什么问题吗?在我看来,它看起来就是期望的结果。 - ImportanceOfBeingErnest
我已经编辑了我的问题以使其更清晰。我想要一个结果,看起来像使用pcolormesh的结果,但是使用contourf。 - Guillaume
2
看起来你想把背景变成黄色。ax.set_facecolor(plt.cm.viridis(1.0)) - ImportanceOfBeingErnest
1
在传递给等高线之前,您还可以将数据剪切到vmax或略高的位置。 - Jody Klymak
2
谢谢,ax.set_facecolor(plt.cm.viridis(1.0)) 可以解决问题,但只适用于下限或上限(在上面的示例中,它无法与vmin=3和vmax=15一起使用)。 - Guillaume
2个回答

4

我不确定它已经存在多久了,但在 matplotlib 3.5.0 中的 contourf 中有一个“扩展”选项,可以在色条上制作一个可爱的小箭头。请参见 contourf 帮助页面。在您的情况下,我们可以执行以下操作:

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


4
以下内容始终会生成一个具有与图表中颜色相对应的颜色条,但不会显示范围之外的值的颜色。
它可以进行编辑(请参见内联注释),以便为您提供所需的确切结果,但是颜色条的颜色仍然与图表中的颜色相对应,这仅是由于使用的特定颜色映射(我想)。
# 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,
)

针对不能处理超出 [vmin,vmax] 范围内的值的情况,永远正确的解决方案: 永远正确的解决方案,无法处理超出 [vmin,vmax] 范围内的值

请求的解决方案: 请求的解决方案


谢谢!非常有帮助。实际上,将ScalarMappable传递给colorbar()(而不是轮廓)就足以解决问题。没有必要显式设置级别和值。 - Guillaume
啊,没错!尽管当您想要一个“分段”的颜色尺度仅包含10个级别时,您还必须传递级别和值:否则,颜色条将是连续的,而不仅仅显示这10个级别。 - Martin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接