Search code examples
pythonloopscartopy

Loop to create subplot /Python


i have a little problem to create a subplot loop.

The following code show my result for one plot.... So it starts with a dayloop than with a hour loop (8 timesteps).

If i run the code i get a nice QUiver plot with the colorbar.

for dd in range(1,15):
  day=str(dd)
  readfile=fns[files_indizes[dd]]
  if dd < 10:
      nc_u_comp = NetCDFFile(ROOT+u_comp1+'0'+day+comp)
      nc_v_comp = NetCDFFile(ROOT+v_comp1+'0'+day+comp)
  else:
      nc_u_comp = NetCDFFile(ROOT+u_comp1+day+comp)
      nc_v_comp = NetCDFFile(ROOT+v_comp1+day+comp)

  time = nc_u_comp.variables['time'][:]

  index=readfile.find(comp)
  index=index+len(comp)
  date=readfile[index-14:index-6]
  plt.clf()

  for tt in range(0,len(time)):
      if tt < 10:
          h =str(0)+str(tt)
      else:
          h=str(tt)

      varU=nc_u_comp.variables['u10'][tt,:,:]
      varV=nc_v_comp.variables['v10'][tt,:,:]
      lat = nc_u_comp.variables['latitude'][:]
      lon = nc_u_comp.variables['longitude'][:]

      plt.rcParams["figure.figsize"] = [10,10]
      #plane projection of the world
      #map with box size (defintion on the top)
      box = sgeom.box(minx=llcrnrlon, maxx=urcrnrlon, miny=llcrnrlat, maxy=urcrnrlat)
      x0, y0, x1, y1 = box.bounds

      #Map plot. The middel of the map is central_longitude 
      #proj = ccrs.PlateCarree(central_longitude=0)
      proj=ccrs.PlateCarree()

      #Change middelpoint of the map
      box_proj = ccrs.PlateCarree(central_longitude=0)


      ax2 = plt.axes(projection=proj)
      ax2.set_extent([x0, x1, y0, y1], box_proj)
      ax2.add_feature(cartopy.feature.BORDERS, linestyle='-', alpha=.5)
      ax2.coastlines(resolution='50m')

      #Definition of the scale_bar
      gl = ax2.gridlines(ccrs.PlateCarree(), \
                      linestyle='--', alpha=1, linewidth=0.5, draw_labels=True)
      gl.xlabels_top = False
      gl.ylabels_right = False
      gl.xformatter = LONGITUDE_FORMATTER
      gl.yformatter = LATITUDE_FORMATTER

      magnitude = (varU ** 2 + varV ** 2) ** 0.5
      strm =plt.streamplot(lon , lat , varU, varV, linewidth=2, density=2, color=magnitude)
      cbar= plt.colorbar()
      cbar.set_label('$m/s$')
      name='Wind in 10 m '+ date + h+' UTC'
      ax2.set_aspect('auto')
      plt.title(name, y=1)

Now i want to create an 2x4 Subplot array with a colorbar allocate to the complete Subplot array.

I find some infromation in the internet, but it doesn't run with my code. Maybe someone can help me?


Solution

  • This shows how to plot an array of simple Cartopy maps in 4 rows 2 columns. Also shows how to plot a colorbar to accompany the maps array. Hope it helps.

    import numpy as np
    import cartopy.crs as ccrs
    import matplotlib.pyplot as plt
    import matplotlib as mpl
    
    # create figure with figsize big enough to accomodate all maps, labels, etc.
    fig = plt.figure(figsize=(8, 10), tight_layout=False)
    
    # define plot array's arrangement
    columns = 2
    rows = 4
    # set projection to use
    projex = ccrs.PlateCarree()
    
    # set the colormap and norm for
    # the colorbar to use
    cmap1 = mpl.cm.magma
    norm1 = mpl.colors.Normalize(vmin=0, vmax=100)
    
    def plotmymap(axs):
        # your plot specs of each map should replace this
        img = np.random.randint(100, size=(15, 30))  # 2d array of random values (1-100)
        # render image on current axis
        plims = plt.imshow(img, extent=[-180,180,-90,90], alpha=0.5, cmap=cmap1, norm=norm1)
        axs.set_global()
        axs.coastlines()
        # add title to the map
        axs.set_title("Map_"+str(i))
        return plims  # for use by colorbar
    
    for i in range(1, columns*rows +1):
        # add a subplot into the array of plots
        ax = fig.add_subplot(rows, columns, i, projection=projex)
        plims = plotmymap(ax)  # a simple maps is created on subplot
    
    # add a subplot for vertical colorbar
    bottom, top = 0.1, 0.9
    left, right = 0.1, 0.8
    fig.subplots_adjust(top=top, bottom=bottom, left=left, right=right, hspace=0.15, wspace=0.25)
    cbar_ax = fig.add_axes([0.85, bottom, 0.05, top-bottom])
    fig.colorbar(plims, cax=cbar_ax)  # plot colorbar
    
    plt.show()  # this plot all the maps
    

    The resulting plots:

    map_array