Python自学笔记Matplotlib风羽自定义.docx
- 文档编号:4266509
- 上传时间:2023-05-06
- 格式:DOCX
- 页数:16
- 大小:21.18KB
Python自学笔记Matplotlib风羽自定义.docx
《Python自学笔记Matplotlib风羽自定义.docx》由会员分享,可在线阅读,更多相关《Python自学笔记Matplotlib风羽自定义.docx(16页珍藏版)》请在冰点文库上搜索。
Python自学笔记Matplotlib风羽自定义
Python自学笔记——Matplotlib风羽自定义
Python自学笔记——Matplotlib风羽自定义
对于气象专业的小学生来说,风场是预报重要的参考数据,我们所知的风羽有四种:
短线代表风速2m/s,长线代表风速4m/s,空心三角代表风速20m/s,实心三角代表风速50m/s。
而matplotlib的风羽只有短线、长线、三角三种,而这里的三角不分空心实心,但是可通过改变风羽颜色为白色使三角变为空心形状,虽然这三种可以自定义各自代表的风速,但是仍与我们的使用习惯不符,即使把三角设成20m/s,原本一个实心三角就能表示的50m/s的风在matplotlib中需要两个三角外加两条长线一条短线。
为了迎合预报员的需求,我在研究了matplotlib的风场函数barbs()的源代码quiver.py文件后,对quiver.py做了适当的调整,使得matplotlib也有了空心三角和实心三角之分。
一、函数barbs的使用
barb(X,Y,U,V,,**kw)
X:
风场数据X坐标
Y:
风场数据Y坐标
U:
风的水平方向分量
V:
风的垂直方向分量
'''
Demonstrationofwindbarbplots
'''
importmatplotlib.pyplotasplt
importnumpyasnp
x=np.linspace(-5,5,5)
X,Y=np.meshgrid(x,x)
U,V=12*X,12*Y
data=[(-1.5,.5,-6,-6),(1,-1,-46,46),(-3,-1,11,-11),(1,1.5,80,80),(0.5,0.25,25,15),(-1.5,-0.5,-5,40)]
data=np.array(data,dtype=[('x',np.float32),('y',np.float32),('u',np.float32),('v',np.float32)])
#Defaultparameters,uniformgrid
ax=plt.subplot(2,2,1)
ax.barbs(X,Y,U,V)
#Arbitrarysetofvectors,makethemlongerandchangethepivotpoint#(pointaroundwhichthey'rerotated)tobethemiddle
ax=plt.subplot(2,2,2)
ax.barbs(data['x'],data['y'],data['u'],data['v'],length=8,pivot='middle')#Showingcolormappingwithuniformgrid.Fillthecircleforanemptybarb,#don'troundthevalues,andchangesomeofthesizeparametersax=plt.subplot(2,2,3)
ax.barbs(X,Y,U,V,np.sqrt(U*U+V*V),fill_empty=True,rounding=False,sizes=dict(emptybarb=0.25,spacing=0.2,height=0.3))
#Changecolorsaswellastheincrementsforpartsofthebarbsax=plt.subplot(2,2,4)
ax.barbs(data['x'],data['y'],data['u'],data['v'],flagcolor='r',barbcolor=['b','g'],barb_increments=dict(half=10,full=20,flag=100),flip_barb=True)plt.show()
二、源代码解读
1.classBarbs()
classBarbs(mcollections.PolyCollection):
@docstring.interpd
def__init__(self,ax,*args,**kw):
'...'
def_find_tails(self,mag,rounding=True,half=5,full=10,flag=50):
'...'
def_make_barbs(self,u,v,nflags,nbarbs,half_barb,empty_flag,length,pivot,sizes,fill_empty,flip):
'...'
defset_UVC(self,U,V,C=None):
'...'
defset_offsets(self,xy):
'...'
通过读源代码可知类Barbs有五个方法分别为__init__、_find_tails、_make_barbs、set_UVC、set_offsets。
2.__init__
@docstring.interpd
def__init__(self,ax,*args,**kw):
"""
Theconstructortakesonerequiredargument,anAxes
instance,followedbytheargsandkwargsdescribed
bythefollowingpylabinterfacedocumentation:
%(barbs_doc)s
"""
self._pivot=kw.pop('pivot','tip')
self._length=kw.pop('length',7)
barbcolor=kw.pop('barbcolor',None)
flagcolor=kw.pop('flagcolor',None)
self.sizes=kw.pop('sizes',dict())
self.fill_empty=kw.pop('fill_empty',False)
self.barb_increments=kw.pop('barb_increments',dict())
self.rounding=kw.pop('rounding',True)
self.flip=kw.pop('flip_barb',False)
transform=kw.pop('transform',ax.transData)
#Flagcolorandandbarbcolorprovideconvenienceparametersfor
#settingthefacecolorandedgecolor,respectively,ofthebarb
#polygon.Wealsoworkheretomaketheflagthesamecolorasthe
#restofthebarbbydefault
ifNonein(barbcolor,flagcolor):
kw['edgecolors']='face'
ifflagcolor:
kw['facecolors']=flagcolor
elifbarbcolor:
kw['facecolors']=barbcolor
else:
#Settofacecolorpassedinordefaulttoblack
kw.setdefault('facecolors','k')
else:
kw['edgecolors']=barbcolor
kw['facecolors']=flagcolor
#Parseoutthedataarraysfromthevariousconfigurationssupported
x,y,u,v,c=_parse_args(*args)
self.x=x
self.y=y
xy=np.hstack((x[:
np.newaxis],y[:
np.newaxis]))
#Makeacollection
barb_size=self._length**2/4#Empiricallydetermined
mcollections.PolyCollection.__init__(self,[],(barb_size,),
offsets=xy,
transOffset=transform,**kw)
self.set_transform(transforms.IdentityTransform())
self.set_UVC(u,v,c)
__init__()方法为初始化方法,此方法中flagcolor、barbcolor为设置风羽颜色的关键字,中间的说明文字提示颜色设置是针对所有的风羽的,所以通过颜色设置达不到风羽中既有空心白色三角又有实心黑色三角。
初始化方法中在对一些参数进行了初始化赋值后执行了set_UVC()方法,所以我们顺着这个set_UVC()方法往下继续读。
3.set_UVC()
defset_UVC(self,U,V,C=None):
self.u=ma.masked_invalid(U,copy=False).ravel()
self.v=ma.masked_invalid(V,copy=False).ravel()
ifCisnotNone:
c=ma.masked_invalid(C,copy=False).ravel()
x,y,u,v,c=delete_masked_points(self.x.ravel(),
self.y.ravel(),
self.u,self.v,c)
else:
x,y,u,v=delete_masked_points(self.x.ravel(),self.y.ravel(),
self.u,self.v)
magnitude=np.hypot(u,v)
flags,emptyflags,barbs,halves,empty=self._find_tails(magnitude,
self.rounding,
**self.barb_increments)
#Gettheverticesforeachofthebarbs
plot_barbs=self._make_barbs(u,v,flags,emptyflags,barbs,halves,empty,
self._length,self._pivot,self.sizes,
self.fill_empty,self.flip)
self.set_verts(plot_barbs)
#Setthecolorarray
ifCisnotNone:
self.set_array(c)
#Updatetheoffsetsincasethemaskeddatachanged
xy=np.hstack((x[:
np.newaxis],y[:
np.newaxis]))
self._offsets=xy
self.stale=True
在此方法中,首先进行了变量的命名赋值,然后依次执行了方法_find_tails和_make_barbs。
_make_barbs的输入为_find_tails的输出,_find_tails的输入中有一个为magnitude=np.hypot(u,v),np.hypot()为勾股定理方法,因此可知magnitude为风速。
4._find_tails
def_find_tails(self,mag,rounding=True,half=5,full=10,flag=50):
'''
Findhowmanyofeachofthetailpiecesisnecessary.Flag
specifiestheincrementforaflag,barbforafullbarb,andhalffor
halfabarb.Magshouldbethemagnitudeofavector(i.e.,>=0).
Thisreturnsatupleof:
(*numberofflags*,*numberofbarbs*,*half_flag*,*empty_flag*)
*half_flag*isabooleanwhetherhalfofabarbisneeded,
sincethereshouldonlyeverbeonehalfonagiven
barb.*empty_flag*flagisanarrayofflagstoeasilytellif
abarbisempty(toolowtoplotanybarbs/flags.
'''
#Ifrounding,roundtothenearestmultipleofhalf,thesmallest
#increment
ifrounding:
mag=half*(mag/half+0.5).astype(np.int)
num_flags=np.floor(mag/flag).astype(np.int)
mag=np.mod(mag,flag)
num_barb=np.floor(mag/full).astype(np.int)
mag=np.mod(mag,full)
half_flag=mag>=half
empty_flag=~(half_flag|(num_flags>0)|(num_emptyflags>0)|(num_barb>0))
returnnum_flags,num_barb,half_flag,empty_flag通过读此方法的说明文档可知,此方法作用为根据输入的风速、设置的短线长线三角的数值计算并返回三角、长线、短线的个数以及有没有无风的情况。
5._make_barbs
def_make_barbs(self,u,v,nflags,nbarbs,half_barb,empty_flag,length,
pivot,sizes,fill_empty,flip):
'''
Thisfunctionactuallycreatesthewindbarbs.*u*and*v*
arecomponentsofthevectorinthe*x*and*y*directions,
respectively.
*nflags*,*nbarbs*,and*half_barb*,empty_flag*are,
*respectively,thenumberofflags,numberofbarbs,flagfor
*halfabarb,andflagforemptybarb,ostensiblyobtained
*from:
meth:
`_find_tails`.
*length*isthelengthofthebarbstaffinpoints.
*pivot*specifiesthepointonthebarbaroundwhichthe
entirebarbshouldberotated.Rightnow,validoptionsare
'head'and'middle'.
*sizes*isadictionaryofcoefficientsspecifyingtheratio
ofagivenfeaturetothelengthofthebarb.Thesefeatures
include:
-*spacing*:
spacebetweenfeatures(flags,full/half
barbs)
-*height*:
distancefromshaftoftopofaflagorfull
barb
-*width*-widthofaflag,twicethewidthofafullbarb
-*emptybarb*-radiusofthecircleusedforlow
magnitudes
*fill_empty*specifieswhetherthecirclerepresentingan
emptybarbshouldbefilledornot(thischangesthedrawing
ofthepolygon).
*flip*isaflagindicatingwhetherthefeaturesshouldbeflippedto
theothersideofthebarb(usefulforwindsinthesouthern
hemisphere.
Thisfunctionreturnslistofarraysofvertices,definingapolygon
foreachofthewindbarbs.Thesepolygonshavebeenrotatedto
properlyalignwiththevectordirection.
'''
#Thesecontrolthespacingandsizeofbarbelementsrelativetothe
#lengthoftheshaft
spacing=length*sizes.get('spacing',0.125)
full_height=length*sizes.get('height',0.4)
full_width=length*sizes.get('width',0.25)
empty_rad=length*sizes.get('emptybarb',0.15)
#Controlsypointwheretopivotthebarb.
pivot_points=dict(tip=0.0,middle=-length/2.)
#Checkforflip
ifflip:
full_height=-full_height
endx=0.0
endy=pivot_points[pivot.lower()]
#Gettheappropriateangleforthevectorcomponents.Theoffsetis
#duetothewaythebarbisinitiallydrawn,goingdownthey-axis.
#Thismakessenseinameteorologicalmodeofthinkingsincethere0
#degreescorrespondstonorth(they-axistraditionally)
angles=-(ma.arctan2(v,u)+np.pi/2)
#Usedforlowmagnitude.Wejustgetthevertices,soifwemakeit
#outhere,itcanbereused.Thecentersethereshouldputthe
#centerofthecircleatthelocation(offset),ratherthanatthe
#samepointasthebarbpivot;thisseemsmoresensible.
circ=CirclePolygon((0,0),radius=empty_rad).get_verts()
iffill_empty:
empty_barb=circ
else:
#Ifwedon'twanttheemptyonefilled,wemakeadegenerate
#polygonthatwrapsbackoveritself
empty_barb=np.concatenate((circ,circ[:
:
-1]))
barb_list=[]
forindex,angleinnp.ndenumerate(angles):
#Ifthevectormagnitudeistooweaktodrawanything,plotan
#emptycircleinstead
ifempty_flag[index]:
#Wecanskipthetransformsincethecirclehasnopreferred
#orientation
barb_list.append(empty_barb)
continue
poly_verts=[(endx,endy)]
offset=length
#Addverticesforeachflag
foriinrange(nflags[index]):
#Thespacingthatworksforthebarbsisalittletomuchfor
#theflags,butthisonlyoccurswhenwehavemorethan1
#flag.
ifoffset!
=length:
offset+=spacing/2.
poly
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Python 自学 笔记 Matplotlib 自定义
![提示](https://static.bingdoc.com/images/bang_tan.gif)