创建自定义颜色条的问题

问题描述 投票:0回答:1

我正在尝试使用此资源创建具有离散间隔的自定义颜色条(https://matplotlib.org/3.1.1/tutorials/colors/colorbar_only.html),但我遇到了此错误,该错误引用了我的'我的代码中的 cb2' 行:

错误:“AttributeError:‘GeoContourSet’对象没有属性‘set’”

import xarray as xr
from sklearn.linear_model import LinearRegression
import proplot as pplt
import cartopy as ct
import matplotlib as mpl
import matplotlib.pyplot as plt
import colormaps as cmaps
import matplotlib.colors as colors

fig, axs = pplt.subplots(ncols = 2, nrows = 1, axwidth = 7, proj='pcarree')
ax1, ax2 = axs


a = ax1.contourf(era_cape['lon'], era_cape['lat'], regression,  add_colorbar = False, extend = 'both')

axs.format(coast=True, latlim = (20,51), lonlim = (234,293), innerborders = True)
axs.add_feature(ct.feature.OCEAN, zorder=100, edgecolor='k', color = 'white')
axs.add_feature(ct.feature.COASTLINE, zorder=100, edgecolor='k')

cmap1 = mpl.colors.ListedColormap(['purple','navy','slateblue','blue','skyblue','lightblue','aliceblue','yellow','gold','orange','orangered','red','firebrick','darksalmon'])
bounds = [-600, -480, -320, -160, -80, -40, -20, 0, 20, 40, 80, 160, 320, 480, 600]
norm = mpl.colors.BoundaryNorm(bounds, cmap1.N, extend = 'neither')
cb2 = mpl.colorbar.ColorbarBase(a, cmap = cmap1, norm = norm, ticks = bounds, spacing = 'uniform')

在这个例子中, 我对编码相对较新,我不确定是否需要对我的数据执行任何操作才能使其“适合”我的自定义颜色条。

如果我将 cb2 行更改为:

cb2 = fig.colorbar(a, cmap = cmap, norm = norm, ticks = bounds)

这给了我一个颜色条,但它设置为旧的 cmap (RdBu),而不是我创建的新颜色条。刻度线可见,但仅在颜色条上上升约 1/4。如果我把线路改回

cb2 = mpl.colorbar.ColorbarBase()

我再次收到上面提到的属性错误。在此示例中,era_cape['lat'] 和era_cape['lon'] 是美国的 2D 数据,数据范围约为 -600 到 600。

{'coords': {'lon': {'dims': ('lon',), 'attrs': {'units': 
'degrees_east', 'short_name': 'lon', 'long_name': 'longitude'}, 
'data': [0.0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0, 2.25, 
2.5, 2.75, 3.0, 3.25, 3.5, 3.75, 4.0, 4.25, 4.5, 4.75, 5.0, 5.25, 
5.5, 5.75, 6.0, 6.25, 6.5, 6.75, 7.0, 7.25, 7.5, 7.75, 8.0, 8.25, 
8.5, 8.75, 9.0, 9.25, 9.5, 9.75]}, 'lat': {'dims': ('lat',), 
'attrs': {'qualifier': 'Gaussian', 'units': 'degrees_north', 
'short_name': 'lat', 'long_name': 'latitude'}, 'data': [90.0, 
89.75, 89.5, 89.25, 89.0, 88.75, 88.5, 88.25, 88.0, 87.75, 87.5, 
87.25, 87.0, 86.75, 86.5, 86.25, 86.0, 85.75, 85.5, 85.25, 85.0, 
84.75, 84.5, 84.25, 84.0, 83.75, 83.5, 83.25, 83.0, 82.75, 82.5, 
82.25, 82.0, 81.75, 81.5, 81.25, 81.0, 80.75, 80.5, 80.25]}}, 
'attrs': {'title': 'p_cal_daily2monthly_era5.ncl', 'program'
python matplotlib colorbar cartopy
1个回答
0
投票

您的示例代码中发生了很多事情,并且没有数据来复制错误,因此需要进行一些猜测。那么也许您可以稍微简化一下并使用玩具数据(或公开可用的其他数据)?

我怀疑错误来自于您将结果从

ax.contourf
传递到
mpl.colorbar.ColorBase
。后者需要一个轴对象作为参数,并且应该是颜色条的专用轴,而不是实际绘图的轴。通常使用更高级的函数来避免显式创建颜色条轴(“cax”)(见下文)。

我自己对 Proplot 并不熟悉,因此在下面的示例中,为了简单起见,我将其删除了。我认为这最终并不重要,您可能可以将其添加回您需要的功能。

下面显示了一个简化的示例,特别关注颜色条:

import cartopy.crs as ccrs
import cartopy.feature as cfeature
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np

# generate toy data, example data from:
# https://matplotlib.org/stable/gallery/images_contours_and_fields/contourf_demo.html
x = y = np.arange(-3.0, 3.01, 0.025)
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

# scale toy example data to global
lon = x * 180/3
lat = y * 90/3
regression = Z * 300

# define the colormap and scaling
cmap = mpl.colors.ListedColormap([
    'purple','navy','slateblue','blue','skyblue','lightblue', 'aliceblue',
    'yellow','gold','orange','orangered','red','firebrick','darksalmon',
])
bounds = [-600, -480, -320, -160, -80, -40, -20, 0, 20, 40, 80, 160, 320, 480, 600]
norm = mpl.colors.BoundaryNorm(bounds, cmap.N)

# create the figure and axes
fig, ax = plt.subplots(
    1,1, figsize=(8,5), facecolor="w", layout="compressed", 
    subplot_kw=dict(projection=ccrs.PlateCarree()),
)

# plot the contours, note that "cf" is also a mappable that could 
# be used instead of "im" below
cf = ax.contourf(
    lon, lat, regression, cmap=cmap, norm=norm, 
    transform=ccrs.PlateCarree(),
)

# create the colorbar
im = mpl.cm.ScalarMappable(cmap=cmap, norm=norm)
cb = fig.colorbar(
    im, ax=ax, ticks=bounds, spacing="uniform", 
    orientation="horizontal", shrink=0.8,
)

ax.add_feature(cfeature.OCEAN, ec="k", fc="w", zorder=100)
ax.add_feature(cfeature.COASTLINE, ec="k", zorder=100)

结果是:

使用

fig.colorbar
允许您传递主轴(用于绘图),并使 Matplotlib 自动为您创建合理的颜色条轴。您还可以自己提供该轴 (
cax=cax
),但这在您需要对特定位置进行更多控制(例如将其放置在主轴中/上方)时非常有用。

© www.soinside.com 2019 - 2024. All rights reserved.