底图:保存具有多个时间步长的图形并保存为唯一的文件名
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()
几件事:
- 我将网格操作和角度数组移到了我添加的循环之外,因为它们只需要完成一次
- 我将矢量旋转部分制作成一个函数,您可以调用循环的每次迭代
- 当你循环遍历时间步长时,我使用相同的速度数组,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,)
我有一个包含当前数据的 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()
几件事:
- 我将网格操作和角度数组移到了我添加的循环之外,因为它们只需要完成一次
- 我将矢量旋转部分制作成一个函数,您可以调用循环的每次迭代
- 当你循环遍历时间步长时,我使用相同的速度数组,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,)