matplotlib 在子图中作为制图投影绘制时,不显示颜色条标签

tgabmvqs  于 2023-10-24  发布在  其他
关注(0)|答案(2)|浏览(118)

颜色条显示得很好,但是没有值。请参见下面的代码。
代码显示了2列,每列有4行Map和一行颜色条。颜色条上的标签没有出现,我不知道为什么。

import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
from cartopy.mpl.ticker import LatitudeFormatter, LongitudeFormatter

# for labeling lat and lon
lon_formatter = LongitudeFormatter(zero_direction_label=True)
lat_formatter = LatitudeFormatter()

# lon and lat
lon = np.linspace(-180,180,360)
lat = np.linspace(0,90,90)

# initate figure
fig, ax = plt.subplots(5,2,subplot_kw={'projection':  ccrs.PlateCarree(central_longitude=180)}, \
                       gridspec_kw={'height_ratios': [0.33,0.33,0.33,0.33,0.05],'width_ratios': [1, 1], 'wspace': 0.1, 'hspace': 0.1},figsize=[15,10])

# mundhenk plotting
for i in range(0,4):

    # create map
    referenced_data = 20.0 * np.random.rand(90,360)
    im1 = ax[i,0].contourf(lon,lat,referenced_data,cmap='Blues',levels=np.linspace(0,20,6),extend='max')
    ax[i,0].coastlines()
    ax[i,0].set_xticks([0, 60, 120, 180, 240, 300, 360], crs=ccrs.PlateCarree())
    ax[i,0].set_yticks([0, 20, 40, 60, 80], crs=ccrs.PlateCarree())
    if i < 3:
        ax[i,0].set_xticklabels([])
        ax[i,0].yaxis.set_major_formatter(lat_formatter)
    else:
        ax[i,0].xaxis.set_major_formatter(lon_formatter)
        ax[i,0].yaxis.set_major_formatter(lat_formatter)
    ax[i,0].set_ylim(20,80)
    ax[i,0].set_xlim(-100,150)

# Add a colorbar for all subplots
cbar1 = plt.colorbar(im1, cax=ax[4,0], orientation='horizontal', label='(AR Day) / day')
cbar1.ax.set_aspect(0.075)

# tempestextreme plotting
for i in range(0,4):

    # create map
    referenced_data = 20.0 * np.random.rand(90,360)
    im2 = ax[i,1].contourf(lon,lat,referenced_data,cmap='Blues',levels=np.linspace(0,20,6),extend='max')
    ax[i,1].coastlines()
    ax[i,1].set_xticks([0, 60, 120, 180, 240, 300, 360], crs=ccrs.PlateCarree())
    ax[i,1].set_yticks([0, 20, 40, 60, 80], crs=ccrs.PlateCarree())
    if i < 3:
        ax[i,1].set_xticklabels([])
    else:
        ax[i,1].xaxis.set_major_formatter(lon_formatter)
    ax[i,1].set_yticklabels([])
    ax[i,1].set_ylim(20,80)
    ax[i,1].set_xlim(-100,150)

cbar2 = plt.colorbar(im2,cax=ax[4,1],orientation='horizontal')
cbar2.ax.set_aspect(0.075)

yrdbyhpb

yrdbyhpb1#

1.像使用gridspec一样创建子图,这样就会为颜色条分配一个位置。
1.删除分配给颜色条的两个Axes
1.在相同的位置添加新的子图,这些子图不是投影。

  • 这是最简单的,因为它不需要改变现有的循环。
import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
from cartopy.mpl.ticker import LatitudeFormatter, LongitudeFormatter

# for labeling lat and lon
lon_formatter = LongitudeFormatter(zero_direction_label=True)
lat_formatter = LatitudeFormatter()

# lon and lat
lon = np.linspace(-180, 180, 360)
lat = np.linspace(0, 90, 90)

# initate figure
fig, ax = plt.subplots(5, 2, subplot_kw={'projection': ccrs.PlateCarree(central_longitude=180)},
                       gridspec_kw={'height_ratios': [0.33, 0.33, 0.33, 0.33, 0.05],
                                    'width_ratios': [1, 1],
                                    'wspace': 0.1, 'hspace': 0.1},
                       figsize=[15, 10])

# remove the Axes with a projection
ax[4, 0].remove()
ax[4, 1].remove()

# add new subplots that aren't projections
ax9 = fig.add_subplot(5, 2, 9)
ax10 = fig.add_subplot(5, 2, 10)

# mundhenk plotting
for i in range(0, 4):

    # create map
    referenced_data = 20.0 * np.random.rand(90,360)
    im1 = ax[i,0].contourf(lon,lat,referenced_data,cmap='Blues',levels=np.linspace(0,20,6),extend='max')
    ax[i,0].coastlines()
    ax[i,0].set_xticks([0, 60, 120, 180, 240, 300, 360], crs=ccrs.PlateCarree())
    ax[i,0].set_yticks([0, 20, 40, 60, 80], crs=ccrs.PlateCarree())
    if i < 3:
        ax[i,0].set_xticklabels([])
        ax[i,0].yaxis.set_major_formatter(lat_formatter)
    else:
        ax[i,0].xaxis.set_major_formatter(lon_formatter)
        ax[i,0].yaxis.set_major_formatter(lat_formatter)
    ax[i,0].set_ylim(20,80)
    ax[i,0].set_xlim(-100,150)

# Add a colorbar for all subplots
cbar1 = fig.colorbar(im1, cax=ax9, orientation='horizontal', label='(AR Day) / day')
cbar1.ax.set_aspect(0.075)

# tempestextreme plotting
for i in range(0, 4):

    # create map
    referenced_data = 20.0 * np.random.rand(90,360)
    im2 = ax[i,1].contourf(lon,lat,referenced_data,cmap='Blues',levels=np.linspace(0,20,6),extend='max')
    ax[i,1].coastlines()
    ax[i,1].set_xticks([0, 60, 120, 180, 240, 300, 360], crs=ccrs.PlateCarree())
    ax[i,1].set_yticks([0, 20, 40, 60, 80], crs=ccrs.PlateCarree())
    if i < 3:
        ax[i,1].set_xticklabels([])
    else:
        ax[i,1].xaxis.set_major_formatter(lon_formatter)
    ax[i,1].set_yticklabels([])
    ax[i,1].set_ylim(20,80)
    ax[i,1].set_xlim(-100,150)

cbar2 = fig.colorbar(im2, cax=ax10, orientation='horizontal')
cbar2.ax.set_aspect(0.075)

1.正如RuthC所指出的,matplotlib.pyplot.subplot_mosaic可以用来创建每个轴的子图关键字参数。
1.请注意以下方面的差异:
1.创建Axes对象

  1. Axes对象是如何被引用和迭代的
# for labeling lat and lon
lon_formatter = LongitudeFormatter(zero_direction_label=True)
lat_formatter = LatitudeFormatter()

# lon and lat
lon = np.linspace(-180, 180, 360)
lat = np.linspace(0, 90, 90)

# create subplot mosaic with different keyword arguments
fig, ax = plt.subplot_mosaic("AB;CD;EF;GH;IJ",
                             per_subplot_kw={('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'): {'projection': ccrs.PlateCarree(central_longitude=180)}},
                             gridspec_kw={'height_ratios': [0.33, 0.33, 0.33, 0.33, 0.05],
                                          'width_ratios': [1, 1],
                                          'wspace': 0.1, 'hspace': 0.1},
                             figsize=[15, 10])

# mundhenk plotting; iterate through the left Axes letters
for v, i in enumerate(['A', 'C', 'E', 'G']):

    # create map
    referenced_data = 20.0 * np.random.rand(90,360)
    im1 = ax[i].contourf(lon,lat,referenced_data,cmap='Blues',levels=np.linspace(0,20,6),extend='max')
    ax[i].coastlines()
    ax[i].set_xticks([0, 60, 120, 180, 240, 300, 360], crs=ccrs.PlateCarree())
    ax[i].set_yticks([0, 20, 40, 60, 80], crs=ccrs.PlateCarree())
    if v < 3:
        ax[i].set_xticklabels([])
        ax[i].yaxis.set_major_formatter(lat_formatter)
    else:
        ax[i].xaxis.set_major_formatter(lon_formatter)
        ax[i].yaxis.set_major_formatter(lat_formatter)
    ax[i].set_ylim(20,80)
    ax[i].set_xlim(-100,150)

# Add a colorbar for all subplots
cbar1 = fig.colorbar(im1, cax=ax['I'], orientation='horizontal', label='(AR Day) / day')
cbar1.ax.set_aspect(0.075)

# tempestextreme plotting; iterate through the right Axes letters
for v, i in enumerate(['B', 'D', 'F', 'H']):

    # create map
    referenced_data = 20.0 * np.random.rand(90,360)
    im2 = ax[i].contourf(lon,lat,referenced_data,cmap='Blues',levels=np.linspace(0,20,6),extend='max')
    ax[i].coastlines()
    ax[i].set_xticks([0, 60, 120, 180, 240, 300, 360], crs=ccrs.PlateCarree())
    ax[i].set_yticks([0, 20, 40, 60, 80], crs=ccrs.PlateCarree())
    if v < 3:
        ax[i].set_xticklabels([])
    else:
        ax[i].xaxis.set_major_formatter(lon_formatter)
    ax[i].set_yticklabels([])
    ax[i].set_ylim(20,80)
    ax[i].set_xlim(-100,150)

cbar2 = fig.colorbar(im2, cax=ax['J'], orientation='horizontal')
cbar2.ax.set_aspect(0.075)
sycxhyv7

sycxhyv72#

接受的答案是有用的,因为它显示了两种工作方法来实现这一点,但是如果你只是让颜色条创建自己的轴,而不是试图直接将轴作为gridspec的一部分,那就更容易了。你只需在调用colorbar时指定ax=ax[:, 0]即可。
请注意,您还可以使用label_outer来摆脱标记记号的麻烦。

import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs

# lon and lat
lon = np.linspace(-180, 180, 360)
lat = np.linspace(0, 90, 90)

# initate figure
fig, ax = plt.subplots(4, 2, subplot_kw={'projection': ccrs.PlateCarree(central_longitude=180)},
                       figsize=[15, 10], layout='compressed')

for i in range(0, 4):
    referenced_data = 20.0 * np.random.rand(90,360)
    im1 = ax[i,0].contourf(lon,lat,referenced_data,cmap='Blues',levels=np.linspace(0,20,6),extend='max')
    ax[i,0].set_ylim(20, 80)
    ax[i,0].set_xlim(-100, 150)
    ax[i,0].set_xticks([0, 60, 120, 180, 240, 300, 360], crs=ccrs.PlateCarree())
    ax[i,0].set_yticks([0, 20, 40, 60, 80], crs=ccrs.PlateCarree())

# Add a colorbar for all subplots in first column
cbar1 = fig.colorbar(im1, ax=ax[:, 0], orientation='horizontal', shrink=0.6, label='(AR Day) / day')

for i in range(0, 4):
    # create map
    referenced_data = 40.0 * np.random.rand(90,360)
    im2 = ax[i,1].contourf(lon,lat,referenced_data,cmap='Blues',levels=np.linspace(0,40,12),extend='max')
    ax[i,1].set_ylim(20, 80)
    ax[i,1].set_xlim(-100, 150)
    ax[i,1].set_xticks([0, 60, 120, 180, 240, 300, 360], crs=ccrs.PlateCarree())
    ax[i,1].set_yticks([0, 20, 40, 60, 80], crs=ccrs.PlateCarree())

# remove inner tick labels:
for axx in ax.flat:
    axx.label_outer()

# Add a colorbar for all subplots in second column
cbar2 = fig.colorbar(im2, ax=ax[:, 1], orientation='horizontal', shrink=0.6)

相关问题