本节提要:关于标题包含的三个功能的补充。
三个问题都是一些历史遗留问题,专门留待这一节来解决。包括画指定的等值线(如588)、如何在一个子图里绘制多个contourf、cartopy的刊误。
一、如何画指定的等值线
以前也有人问过,不知道怎么给忘了,昨天又有个同学来问,于是就解决了。作为气象上的常用手段,单独绘制588线的南北东西跳跃伸展有极特殊的意义,但是常规方法并不适用。我第一个想到的方法是在contour里的levels参数强制指定levels=[588]来绘制这一根线。这个方法在最新的matplotlib中是可行的。但是不知道在较低版本的matplotlib与cartopy中是否可行,因为之前曾报错levels的列表中至少要有两个元素。
代码语言:javascript复制ac=ax.contour(X, Y, Z,levels=[0])
第二种方法是通过判断levels来存放一个颜色列表,使在绘图时,除了指定的值外不填充颜色。因为画588这种特种线条,其区间固定为4,所以必定要手动设置levels。
代码语言:javascript复制import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
x = np.linspace(-3.0, 3.0, 100)
y = np.linspace(-3.0, 3.0, 100)
X, Y = np.meshgrid(x, y)
z=X**2 Y**2
fig=plt.figure(figsize=(2,2),dpi=500)
ax=fig.add_axes([0,0,1,1])
levels=np.arange(0,22.5,2.5)
###################################################
colors=[] #空列表
for i in levels:
if i==5:
colors.append('r')
else:
colors.append('none')
cs=ax.contour(X, Y, z,colors=colors)
########################################################
ac=ax.clabel(cs,fontsize=3)
plt.show()
第二种办法在任何场景均适用。还可以通过多样化的手段来扩充适用场景。
二、同一张子图中使用两个contourf,尽量少冲突或无冲突
这个问题的出现那就是非常非常久远了,估摸着得有七八个月了。出现的原因是水的相态不同,需要给降雪赋予灰色色系,需要给降雨附上降水色系。我尝试过一些方法,但是除了挖补之后赋予nan值使其不再绘制,实在是想不出还有什么更好的办法了。
这是不使用挖改时两个contourf的遮盖。
代码语言:javascript复制x = np.linspace(-3.0, 3.0, 100)
y = np.linspace(-3.0, 3.0, 100)
X, Y = np.meshgrid(x, y)
z=X**2 Y**2
z2=X**3 Y**2
########################################################33
fig=plt.figure(figsize=(2,2),dpi=500)
ax=fig.add_axes([0,0,1,1])
levels=np.arange(0,20,1)
ac1=ax.contourf(X, Y, z,levels=levels,cmap='Spectral_r')
ac2=ax.contourf(X, Y, z2,levels=levels,cmap='Blues_r')
这是使用官网示例后挖改的两个contourf
代码语言:javascript复制x = np.linspace(-3.0, 3.0, 100)
y = np.linspace(-3.0, 3.0, 100)
X, Y = np.meshgrid(x, y)
z=X**2 Y**2
########################################################33
zm=np.ma.masked_where(z<5,z)
#######################################
zm2=np.ma.masked_where(z>5,z)
################################################3
fig=plt.figure(figsize=(2,2),dpi=500)
ax=fig.add_axes([0,0,1,1])
levels=np.arange(0,20,1)
ac1=ax.contourf(X, Y, zm,levels=levels,cmap='Spectral_r')
ac2=ax.contourf(X, Y, zm2,levels=levels,cmap='Blues_r')
出现锯齿状误差是因为牵涉到割圆术的问题,当x,y初始划分100份时会出现锯齿。当分为1000份时这种现象基本消失。
代码语言:javascript复制x = np.linspace(-3.0, 3.0, 1000)
y = np.linspace(-3.0, 3.0, 1000)
还可以用常用的array方法赋予nan值,也可以实现上述效果。
代码语言:javascript复制x = np.linspace(-3.0, 3.0, 1000)
y = np.linspace(-3.0, 3.0, 1000)
X, Y = np.meshgrid(x, y)
z=X**2 Y**2
z2=X**2 Y**2
########################################################33
z[z<5]=np.nan
#######################################
z2[z2>5]=np.nan
################################################3
fig=plt.figure(figsize=(2,2),dpi=500)
ax=fig.add_axes([0,0,1,1])
levels=np.arange(0,20,1)
ac1=ax.contourf(X, Y, zm,levels=levels,cmap='Spectral_r')
ac2=ax.contourf(X, Y, z2,levels=levels,cmap='Blues_r')
这只是简单的讲述一个看法,但是实际上用,可能需要更多的判断条件。但是不进行挖改的话,必然会出现下一个等值线填色覆盖上一个等值线填色的问题。使用了一个再分析资料,绘制了两种contourf同时存在的一种场景:
代码语言:javascript复制uv=np.sqrt(U**2 V**2)
#先通过经纬向风算出实际风速
UV=np.ma.masked_where(uv<12,uv)
#使12米每秒以下的风缺测
rh=np.ma.masked_where(RH<70,RH)
#使70%以下的相对湿度缺测
ac=ax.contourf(lons[:,:],lats[:,:],UV[:,:],
levels=np.arange(12,40,4),cmap='Reds',
zorder=2,alpha=0.5) #这里使其位于上层,并调整透明度为0.5
ad=ax.contourf(lons[:,:],lats[:,:],rh[:,:],cmap='Greens')
在一定程度上解决了很久之前的那个问题。
三、cartopy补充
在Python气象绘图教程(二十一)—Cartopy_10我提到过兰勃脱投影下不能强制对齐标签的说法,这是错误的。只要关闭rotation即可使全部经纬度正常对齐。
代码语言:javascript复制gl.rotate_labels = None
全部对齐,不会歪七扭八的了。
针对两个contourf的混合绘制,如果有更好的办法可以后台留言。