底图:保存具有多个时间步长的图形并保存为唯一的文件名

Basemap: save figure with several time-steps and to unique file name

我有一个包含当前数据的 netCDF 文件,我正在 Python3.5.

中使用底图模块绘制

当前数据的文件包含大约 2000 个时间步长(每小时),我希望它绘制所有时间步长,并将图形保存为一个唯一的文件名。这可能吗?

u = data.variables['u'][0,0,:,:]
v = data.variables['v'][0,0,:,:]
Where the first 0 is the time step variable.

子问题:如何做一个常量colorbar,这样plot之间的对比才会准确?

编辑:我继续修改您嵌入的代码以实现您的目标。我没有办法测试这个,因为我没有你的数据集,所以如果这没有帮助,请回复。我在整个过程中都发表了评论,希望有助于破译我所做的更改。很高兴回答任何问题。

EDIT2:解决颜色条一致问题的不同方法。计算第一时间步的速度,并将其用于每个绘图的颜色数组。

import netCDF4
from mpl_toolkits.basemap import Basemap
import numpy as np
import matplotlib.pyplot as plt

def u_v_components(u,v,angle):
        """ Rotate the u, v vectors from model grid to east/north coords """
        u_east = (np.cos(angle)*u - np.sin(angle)*v)
        v_north = (np.sin(angle)*u + np.cos(angle)*v)
        return u_east, v_north

# Setting the map
scale  = 0.6
width  = 1800000
height = 2300000
lat_0  = 70.8
lon_0  = 25
fig, ax = plt.subplots(figsize = (10, 10))
m = Basemap(width=width*scale,height=height*scale,
        resolution='i',projection='stere',\
        lat_ts=70,lat_0=lat_0,lon_0=lon_0)

m.fillcontinents(color='#aaaaaa',lake_color='#cccccc')
m.drawcountries(linewidth=0.2)
m.drawmapboundary(fill_color='#cccccc')

m.drawparallels(np.arange(-80.,81.,5.),labels=[False,True,True,False])
m.drawmeridians(np.arange(-180.,181.,10.),labels=[True,False,False,True])

dataurl = '/Users/JDMac/norkyst_800m_surfcurr_MAY-JUL_2010_NordNorge_middel.nc'
data = netCDF4.Dataset(dataurl)

# I moved the angle and grid operations out of the loop since they
# only need to be done once.
#angle array in dataset
angle = data.variables['angle'][:,:]

#gridlons and gridlats tell us the lon and lat of each
# point in the grid. This is necessary for drawing on
# the map.
gridlons = data.variables['lon'][:,:]
gridlats = data.variables['lat'][:,:]

X, Y = m(gridlons, gridlats)

YY = np.arange(0, Y.shape[0], 10)
XX = np.arange(0, X.shape[1], 10)
points = np.meshgrid(YY, XX)

#current u-v component [time, depth, lon, lat]
u = data.variables['u'][0,0,:,:]
v = data.variables['v'][0,0,:,:]

#rotate current u-v components from model grid to east-north coordinates
u_east, v_north = u_v_components(u,v,angle)

#pytagoras' theorem to calculate the current velocity and direction
# Calculate speed for time step 0, then maintain this array to
# consistently colorize your vector plot.
speed = np.sqrt(u_east**2 + v_north**2)

# Iterate through the time steps, subsetting the data
# by time step as you go.
# I don't know what the time dimension in your dataset is named,
# so you may have to change it.
for time in range(data.dimensions['time'].size):
    #current u-v component [time, depth, lon, lat]
    u = data.variables['u'][time,0,:,:]
    v = data.variables['v'][time,0,:,:]

    #rotate current u-v components from model grid to east-north coordinates
    u_east, v_north = u_v_components(u,v,angle)

    # Added the cmap kwarg which will define what colormap is
    # used to color the arrows. Depending on your version of
    # matplotlib, jet or viridis is the default if cmap is not specified.
    m.quiver(X[points], Y[points],
                     u_east[points], v_north[points],
                     speed[points],
                     cmap=plt.cm.get_cmap('viridis'))

    # I recommend using the Basemap colorbar method
    # unless for some reason you need more control over all
    # of the colorbar properties. The colorbar method allwos you to
    # manipulate the relative size of the colorbar, the padding
    # between it and the axes, as well as the location on the map.
    cb = m.colorbar(mappable=plt.cgi(),
                       location='right')
    cb.set_label('Strømhastighet i m/s')

    plt.tight_layout()

    # Give each output file a unique filename
    # bbox_inches='tight' will remove as much whitespace as it can
    plt.savefig('current{}.png'.format(time),
                            bbox_inches='tight',
                            dpi = 300)
    # Clear the figure before re-use
    plt.clf()

# Garbage collection should close any open figures and datasets, but
# it's good practice to do so explicitly
plt.close('all')
data.close()

几件事:

  1. 我将网格操作和角度数组移到了我添加的循环之外,因为它们只需要完成一次
  2. 我将矢量旋转部分制作成一个函数,您可以调用循环的每次迭代
  3. 当你循环遍历时间步长时,我使用相同的速度数组,matplotlib 将颜色映射映射到(希望)解决你的常量颜色条问题。

编辑:

  File "current.py", line 75, in <module>
    speed[:])
  File "/usr/local/lib/python3.5/site-packages/mpl_toolkits/basemap/__init__.py", line 560, in with_transform
    return plotfunc(self,x,y,u,v,*args,**kwargs)
  File "/usr/local/lib/python3.5/site-packages/mpl_toolkits/basemap/__init__.py", line 3712, in quiver
    ret =  ax.quiver(x,y,u,v,*args,**kwargs)
  File "/usr/local/lib/python3.5/site-packages/matplotlib/__init__.py", line 1812, in inner
    return func(ax, *args, **kwargs)
  File "/usr/local/lib/python3.5/site-packages/matplotlib/axes/_axes.py", line 4433, in quiver
    q = mquiver.Quiver(self, *args, **kw)
  File "/usr/local/lib/python3.5/site-packages/matplotlib/quiver.py", line 460, in __init__
    self.set_UVC(U, V, C)
  File "/usr/local/lib/python3.5/site-packages/matplotlib/quiver.py", line 541, in set_UVC
    mask = ma.mask_or(mask, C.mask, copy=False, shrink=True)
  File "/usr/local/lib/python3.5/site-packages/numpy/ma/core.py", line 1693, in mask_or
    return make_mask(umath.logical_or(m1, m2), copy=copy, shrink=shrink)
ValueError: operands could not be broadcast together with shapes (7200,) (8,)