1. 程式人生 > >python matplotlib quiver——畫箭頭、風場

python matplotlib quiver——畫箭頭、風場

https://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.quiver

上面是官方文件的連結

箭頭關鍵的一個引數是長度,長度可以通過引數scale來設定,如果你多次使用quiver(),只要保證引數scale一致,那麼箭頭長度就會與風速的值成正比,可按照下面我貼出的程式碼那樣設定引數。建議scale設定成30-50,100之內也都還可以。箭頭寬度可以通過width=0.005開始設定。箭頭顏色可以通過傳入顏色列表來控制。

Axes.quiver(*argsdata=None**kw)

        用於畫二維的箭頭

        呼叫quivers有以下幾種形式(signatures):

quiver(U, V, **kw)
quiver(U, V, C, **kw)
quiver(X, Y, U, V, **kw)
quiver(X, Y, U, V, C, **kw)

 U、V是箭頭資料(data),X、Y是箭頭的位置,C是箭頭的顏色。這些引數可以是一維或二維的陣列或序列。

如果X、Y不存在(absent),他們將作為均勻網格被生成。如果U和V是2維的陣列,X和Y是1維陣列,並且len(X)和len(Y)與U的列(column)和行(row)緯度相匹配(match),那麼X和Y將使用

numpy.meshgrid()——用於產生一個矩陣,具體可參考:meshgrid使用方法——進行擴充套件。

預設設定會自動將箭頭的長度縮放到合理的大小。要改變箭頭的長度請參看 scale 和scale_units兩個關鍵字引數(kwargs:關鍵字引數,參看文章最後有關鍵字引數與可變引數的區別)

預設值給出一個稍微後掠(swept-back)的箭頭;若要使箭頭頭部呈三角狀,則要確保headaxislength與headlength相同。若要使箭頭更尖銳(more pointed),則應減小headwidth或者增大headlength和headaxislength。若要使箭頭頭部相對於箭桿(shaft)更小一些,則應將所有頭部引數都減小(scale down)。你最好不要單獨留下minshaft(You will probably do best to leave minshaft alone.)

線寬和邊緣顏色可以用於自定義箭頭輪廓(outlines)。

引數

X: 1D or 2D array, sequence, optional

   1維或2維陣列,序列(sequence),可自選(optional)

   箭頭位置的x座標

Y:1D or 2D array, sequence, optional

   1維或2維陣列,序列,可自選

   箭頭位置的y座標

U: 1D or 2D array or masked array, sequence

   1維或2維陣列或掩碼陣列(參看masked array https://blog.csdn.net/liukai2918/article/details/78419302),序列

   箭頭向量的x分量

V:1D or 2D array or masked array, sequence

   1維或2維陣列或掩碼陣列,序列

   箭頭向量的y分量

C: 1D or 2D array, sequence, optional

   1維或2維陣列,序列(sequence),可自選

   箭頭顏色

units(單位): [ 'width' | 'height' | 'dots' | 'inches' | 'x' | 'y' | 'xy' ]

   箭頭尺寸(除長度外)以此單位的倍數計算——即是說選定單位後,箭頭尺寸即是此單位的倍數

   ‘width’或’height’:軸(axis)的寬度或高度

   ‘dots’或’inches’:畫素或英寸,基於圖的dpi

   ‘x’, ‘y’或‘xy’:分別是X、Y或X2+Y2的資料單位(data units)

   箭頭依單位不同而不同。對於’x’或’y’,箭頭會隨著其一的增大(zoom in)而增大;對於其他單位,箭頭的大小與縮放狀態(zoom state)無關。對於’width’或’height’,當視窗重置時,箭頭的大小會隨著軸(axes)的寬度和高度的增大而增大;低於同意’dots’或’inches’。重置不會改變箭頭。

angles: [‘uv’ | ‘xy’], array, 可自選

   用於決定箭頭角度的方法,預設是’uv’

‘uv’:箭頭的縱橫比(axis aspect ratio)為1,所以若U*==*V,則繪圖上箭頭的方向與水平軸逆時針呈45度(正向右)。

‘xy’: 箭頭從(x,y)指向(x + u,y + v)。例如,使用它來繪製漸變場(gradient field)。

或者,可以將任意角度指定為以水平軸逆時針方向的度數值的陣列。

注意:反轉資料軸將相應地僅使用angles='xy'反轉箭頭。

scale : None, float, optional

   每個箭頭長度單位的資料單位數量,例如,每個繪圖寬度m / s;引數scale越小箭頭越長。預設是None

   若是None,一個簡單的自動縮放演算法將被採用,基於平均向量長度和適量的數量。箭頭長度單位由scale_units引數給出。

scale_units : [ 'width' | 'height' | 'dots' | 'inches' | 'x' | 'y' | 'xy' ], None, optional

   如果關鍵字引數scale是None,那麼箭頭長度單位預設是None

   例如:scale_units是’inches’,scale是2.0,(u,v)=(1,0),那麼向量將會是0.5英寸長。

   如果scale_units是’width/height’,那麼向量長度是軸’width/height’的半長

   如果scale_units是’x’那麼向量是x軸單位的0.5倍。要在x-y平面上畫向量,使得u和v與x和y有相同的單位,則應另angles=’xy’, scale_units’xy’, scale=1.

width : scalar(標量), optional

   箭桿(shaft)的寬度,以箭頭單位衡量。預設是由以上單位的選擇和向量數量來決定。常用的初始值是0.005倍的畫的寬度(width of the plot)

headwidth : scalar, optional

   頭部寬度相對於箭桿寬度的倍數,預設是3倍

headlength : scalar, optional

   軸交叉處的頭部長度,預設是4.5

minshaft : scalar, optional

   箭頭比例的長度,以頭部長度為單位。不要將其設定為小於1,否則小箭頭看起來會很糟糕

minlength : scalar, optional

   最小長度為軸寬的倍數;如果箭頭長度小於此值,則繪製該直徑的點(六邊形)。預設值為1

pivot : [ 'tail' | 'mid' | 'middle' | 'tip' ], optional

   箭頭在網格點上的部分;箭頭圍繞這一點旋轉,因此稱為樞軸。

color : [ color | color sequence ], optional

   這是PolyCollection facecolor kwarg的同義詞。如果設定了C,顏色就沒有效果。

 

quiver(*args, **kw)

 

 

import matplotlib.pyplot as plt
import math
from mpl_toolkits.basemap import Basemap
from pylab import *
import numpy as np


mpl.rcParams['font.sans-serif'] = ['SimHei']

for i in range(1,3):
	plt.subplot(2, 1, i)
	ax = plt.gca()
	wind = [x for x in range(1,9)]
	# angle = [45*x for x in range(0,8)]
	# lon = list(np.linspace(113.8, 114.6, 8))
	lat = list(np.linspace(22.4, 22.85, 8))

	# wind = [2]*8
	angle = [90]*8 # 為方便比較長度,箭頭方向設定成一樣
	lon = [114.27] * 8 # 為方便比較長度,箭頭經度設定成一樣

	# 指定地圖範圍、投影方式(projection)等  area_thresh是與湖泊等在地圖上顯示相關的引數
	m = Basemap(llcrnrlon=113.7, llcrnrlat=22.35, urcrnrlon=114.7, urcrnrlat=22.9,\
            rsphere=(6378137.00,6356752.3142),\
            resolution='l', area_thresh=1000., projection='lcc', lat_1=22.5, lat_0=22.5, lon_0=114,ax=ax)
	lon, lat = m(*(lon, lat))

	# 一系列的U、V
	ver = [-spd*math.sin(math.radians(agl)) for spd,agl in zip(wind, angle)] # U分量
	hriz = [-spd*math.cos(math.radians(agl)) for spd,agl in zip(wind, angle)] # V分量
	print(ver, '\n', hriz)

	ax=plt.gca()
	#下面兩行是讀取地圖中的shape檔案,即輪廓圖
	# m.readshapefile(r'G:\深圳季風研究\gadm36_HKG_shp\gadm36_HKG_0', 'states',color='grey') #HongKong
	# # m.readshapefile(r'G:\深圳季風研究\gadm36_CHN_shp\gadm36_CHN_3', 'states',color='grey') #Mainland in given lon and lat
	# m.readshapefile(r'G:\深圳季風研究\gadm36_sz_shp\Bon_data\xzq_sz_pop', 'states', color='grey')

	m.scatter(lon, lat, s=2, color='goldenrod', marker="o") #根據經緯度,畫出對應站點位置
	ax.set_title('風場')
	# ax.quiver(lon, lat, ver, hriz, units='width', scale=2, width=0.01, color='deepskyblue')
	ax.quiver(lon, lat, ver, hriz, color='deepskyblue', width=0.005, scale=30)

	for i, wspd in enumerate(wind):
		ax.annotate(str(wspd), (lon[i], lat[i]))

	# 在圖上新增一些文字資訊
	plt.text(0.6,0.9, r'$mean: $'+str(18) + '°', color='forestgreen',transform=ax.transAxes, fontweight='extra bold')
	plt.text(1.02,0.6, r'$S: $' + str(18) + '%', color='forestgreen',transform=ax.transAxes, fontweight='heavy')
	plt.text(1.02,0.4, r'$N: $', color='forestgreen',transform=ax.transAxes, fontweight=100)

	# 畫經緯度網格
	m.drawmeridians([114.0,114.4], labels=[1,0,0,1]) # meridian:子午線,經線 arange指明範圍和間隔
	m.drawparallels(np.arange(15, 30, 0.3), labels=[1,0,0,0])  # 畫緯度平行線

	# 比例尺長度的U、V值和位置
	q_lon, q_lat = m(*(114.27, 22.75))
	spd = 2
	angle_all = 90
	ver_all = -spd*math.sin(math.radians(angle_all))
	hriz_all = -spd*math.cos(math.radians(angle_all))
	# ax.quiver(q_lon, q_lat, ver_all, hriz_all, color='g', pivot='mid') # mid是旋轉樞紐在中間,預設在尾部
	ax.quiver(q_lon, q_lat, ver_all, hriz_all, color='g', scale=30)

	# 畫比例尺
	plt.text(0.82,0.1, r'$scale:$', color='r',transform=ax.transAxes, fontweight=100, fontsize=8)
	plt.text(0.82,0.03, r'$2m/s$', color='r',transform=ax.transAxes, fontweight=100, fontsize=8)
	plt.quiver(95000, 3000, 3, hriz_all, color='r', width=0.005, scale=50)
	print(-ver_all, hriz_all)

	# 這一段與畫箭頭不相干,可忽略註釋掉  畫散點,為不同散點設定不同顏色
	# Colors=('#DDDDFF','#7D7DFF','#0000C6','#000079','#CEFFCE','#28FF28','#007500','#FFFF93')
	# sc = plt.scatter(lon, lat, s=100, color=Colors, marker="o") #根據經緯度,畫出對應站點位置
	# for i,txt in enumerate(Colors):
	# 	ax.annotate(txt,(lon[i],lat[i]), fontsize=5)

plt.show()

下面是程式碼執行結果:

未讀入shape檔案的結果:

讀入了shape檔案的結果 

quiver(*args, **kw)

*args, **kw分別是可變引數和關鍵字引數,參考此文總結如下: