Basemap 中的 drawparallels 参数问题
Issue with drawparallels argument in Basemap
这似乎应该是一个简单的修复,但我无法让它工作。我希望在附图中显示 40°N,但将 drawparallels 中的标签参数设置为 [1,0,1,1] 并不能解决问题。根据文档,这应该绘制平行线标签,它们与图的左侧、顶部和底部相交。我还希望 0° 再次出现在右下角。知道如何解决这 2 个问题吗?
from netCDF4 import Dataset as NetCDFFile
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.basemap import Basemap
from mpl_toolkits.basemap import addcyclic
nc = NetCDFFile('C:/myfile.nc')
lat = nc.variables['lat'][:]
lon = nc.variables['lon'][:]
time = nc.variables['time'][:]
olr = nc.variables['olr'][:]
olr,lon = addcyclic(olr,lon)
map = Basemap(llcrnrlon=0.,llcrnrlat=-40.,urcrnrlon=360.,urcrnrlat=40.,resolution='l')
lons,lats = np.meshgrid(lon,lat)
x,y = map(lons,lats)
levels = np.arange(-19.5,20.0,0.5)
levels = levels[levels!=0]
ticks = np.arange(-20.0,20.0,4.0)
cs = map.contourf(x,y,olr[0],levels, cmap='bwr')
cbar = plt.colorbar(cs, orientation='horizontal', cmap='bwr', spacing='proportional', ticks=ticks)
cbar.set_label('Outgoing Longwave Radiation Anomalies $\mathregular{(W/m^2)}$')
map.drawcoastlines()
map.drawparallels(np.arange(-40,40,20),labels=[1,0,1,1], linewidth=0.5, fontsize=7)
map.drawmeridians(np.arange(0,360,40),labels=[1,1,0,1], linewidth=0.5, fontsize=7)
问题的第一部分很简单。为了显示标签,您必须实际绘制平行线,但 np.arange(-40,40,20)
不包括 40
。因此,如果您将该语句更改为 np.arange(-40,41,20)
,您的 40N
标签将会显示。
第二部分原则上应该可以用同样的方法求解,但是 Basemap 显然使用经度的模数来计算标签的位置,所以在绘制子午线时只使用 np.arange(0,361,40)
会导致两个 0
标签相互叠加。但是,我们可以捕获 drawmeridians
生成的标签并手动更改第二个 0
标签的位置。标签存储在字典中,因此很容易处理。为了计算最后一个标签的 x 位置,我计算了第一个和第二个标签之间 x 位置的差异,将其乘以要绘制的子午线数量 (360/40),然后加上第一个标签的 x 位置标签。
这里是完整的例子:
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.basemap import Basemap
map = Basemap(llcrnrlon=0.,llcrnrlat=-40.,urcrnrlon=360.,urcrnrlat=40.,resolution='l')
map.drawcoastlines()
yticks = map.drawparallels(
np.arange(-40,41,20),labels=[1,0,1,1], linewidth=0.5, fontsize=7
)
xticks = map.drawmeridians(
np.arange(0,361,40),labels=[1,1,0,1], linewidth=0.5, fontsize=7
)
first_pos = xticks[0][1][0].get_position()
second_pos = xticks[40][1][0].get_position()
last_x = first_pos[0]+(second_pos[0]-first_pos[0])*360/40
xticks[360][1][0].set_position((last_x,first_pos[1]))
plt.show()
这里是结果图:
希望对您有所帮助。
这似乎应该是一个简单的修复,但我无法让它工作。我希望在附图中显示 40°N,但将 drawparallels 中的标签参数设置为 [1,0,1,1] 并不能解决问题。根据文档,这应该绘制平行线标签,它们与图的左侧、顶部和底部相交。我还希望 0° 再次出现在右下角。知道如何解决这 2 个问题吗?
from netCDF4 import Dataset as NetCDFFile
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.basemap import Basemap
from mpl_toolkits.basemap import addcyclic
nc = NetCDFFile('C:/myfile.nc')
lat = nc.variables['lat'][:]
lon = nc.variables['lon'][:]
time = nc.variables['time'][:]
olr = nc.variables['olr'][:]
olr,lon = addcyclic(olr,lon)
map = Basemap(llcrnrlon=0.,llcrnrlat=-40.,urcrnrlon=360.,urcrnrlat=40.,resolution='l')
lons,lats = np.meshgrid(lon,lat)
x,y = map(lons,lats)
levels = np.arange(-19.5,20.0,0.5)
levels = levels[levels!=0]
ticks = np.arange(-20.0,20.0,4.0)
cs = map.contourf(x,y,olr[0],levels, cmap='bwr')
cbar = plt.colorbar(cs, orientation='horizontal', cmap='bwr', spacing='proportional', ticks=ticks)
cbar.set_label('Outgoing Longwave Radiation Anomalies $\mathregular{(W/m^2)}$')
map.drawcoastlines()
map.drawparallels(np.arange(-40,40,20),labels=[1,0,1,1], linewidth=0.5, fontsize=7)
map.drawmeridians(np.arange(0,360,40),labels=[1,1,0,1], linewidth=0.5, fontsize=7)
问题的第一部分很简单。为了显示标签,您必须实际绘制平行线,但 np.arange(-40,40,20)
不包括 40
。因此,如果您将该语句更改为 np.arange(-40,41,20)
,您的 40N
标签将会显示。
第二部分原则上应该可以用同样的方法求解,但是 Basemap 显然使用经度的模数来计算标签的位置,所以在绘制子午线时只使用 np.arange(0,361,40)
会导致两个 0
标签相互叠加。但是,我们可以捕获 drawmeridians
生成的标签并手动更改第二个 0
标签的位置。标签存储在字典中,因此很容易处理。为了计算最后一个标签的 x 位置,我计算了第一个和第二个标签之间 x 位置的差异,将其乘以要绘制的子午线数量 (360/40),然后加上第一个标签的 x 位置标签。
这里是完整的例子:
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.basemap import Basemap
map = Basemap(llcrnrlon=0.,llcrnrlat=-40.,urcrnrlon=360.,urcrnrlat=40.,resolution='l')
map.drawcoastlines()
yticks = map.drawparallels(
np.arange(-40,41,20),labels=[1,0,1,1], linewidth=0.5, fontsize=7
)
xticks = map.drawmeridians(
np.arange(0,361,40),labels=[1,1,0,1], linewidth=0.5, fontsize=7
)
first_pos = xticks[0][1][0].get_position()
second_pos = xticks[40][1][0].get_position()
last_x = first_pos[0]+(second_pos[0]-first_pos[0])*360/40
xticks[360][1][0].set_position((last_x,first_pos[1]))
plt.show()
这里是结果图:
希望对您有所帮助。