Matplotlib 箭袋图:参数顺序
Matploltib quiver plot: argument order
给定纵横比值的二维数组(罗盘方位,例如由高程模型的纵横比导数表示),我正在创建一个 quiver plot using matplotlib。这被放置在方面值的彩色矩阵上以充当检查。
代码之所以有效,是因为它创建了我想要的内容,但仅在参数与我的预期相反的地方创建。我犯了一个简单的错误,但无法发现它。
问题: 虽然 matplotlib.pyplot.quiver()
期望 quiver([X, Y], U, V, [C], **kw)
,但为什么我的代码只给出 quiver([X, Y], V, U)
的预期答案(即 U 和 V是否反过来)被使用?
顺便说一句,在绘图时,我将 plt.imshow
的原点移到了 lower
(如 here 所讨论的)。我认为问题出在与我的索引等相关的地方
下面的代码(使用 python 3.5 和 matplotlib v3.x):
import numpy as np
import matplotlib.pyplot as plt
def compassBearing_to_standardPosition__degrees_counterClockwise(bearing_deg):
"""Vector magnitude and direction calculations assume angle is relative to the x axis
i.e. 0 degrees north is at 3 o'clock
Adjust compass bearings to be relative to standard position
"""
std_pos=(450 - bearing_deg) % 360
return(std_pos)
def calculate_U_and_V__vector_magnitude_and_direction(angle_degrees, magnitude=1):
"""Calculates the components of a vector given in magnitude (U) and direction (V) form
angle: Expected that angles are in standard position
i.e. relative to the x axis or where 3 o'clock is zero and not the compass bearing
where 12 o'clock is 0
magnitude: defaults to 1
"""
angle_rad=np.deg2rad(angle_degrees)
x = magnitude * np.cos(angle_rad) # change in x == U
y = magnitude * np.sin(angle_rad) # change in y == V
return(x,y)
def array_indices(arr, indexing='xy'):
"""Calculates index positions of each cell in array
These can be used to map to e.g. when creating a quiver plot
indexing: Giving the string 'ij' returns a meshgrid with
matrix indexing, while 'xy' returns a meshgrid with Cartesian indexing.
In the 2-D case with inputs of length M and N, the outputs are of shape
(N, M) for 'xy' indexing and (M, N) for 'ij' indexing.
"""
nrows, ncols = arr.shape
nx = 1
ny = 1
x = np.linspace(0, ncols-1, ncols)
y = np.linspace(0, nrows-1, nrows)
#y = np.linspace(nrows-1, 0, nrows) # note that the largest vlue is first
xi, yi = np.meshgrid(x, y, indexing=indexing)
return(xi, yi)
#Create a toy aspect grid (degrees North)
aspect_grid=np.array([[ 216, 226, 151],
[ 74, 323, 268],
[ 177, 204, 84]])
#Get the array indices
x,y=array_indices(aspect_grid, indexing='xy')
#Get U and V
x_change,y_change=calculate_U_and_V__vector_magnitude_and_direction(aspect_grid.flatten())
#Plot quiver over imshow
cmap = 'twilight_shifted' # this will expect matplotlib v3.x
plt.imshow(np.floor(aspect_grid), cmap=cmap, origin='lower')
plt.colorbar(label="Aspect (degrees N)")
plt.quiver(x, y, y_change, x_change, pivot='middle') # <<< why not x,y,x_change,y_change?
plt.title("Surface aspect values")
plt.show()
当您将 aspect_grid
数组传递给 calculate_U_and_V__vector_magnitude_and_direction
时,您并没有将它们从绝对方位角转换为逆时针度数,因为 compassBearing_to_standardPosition__degrees_counterClockwise
没有在 calculate_U_and_V__vector_magnitude_and_direction
中被调用。由于两个约定的 90 度错位,这导致 cos(angle)
对应于 y
组件,而 sin(angle)
对应于 x
组件(由于 属性 cos(x - pi/2) == sin(x)
)。为了纠正这个问题,你只需要使用你设置的转换(它正确地从方位转换为标准位置)通过做类似
的事情
#...
angle_degrees = compassBearing_to_standardPosition__degrees_counterClockwise(angle_degrees)
angle_rad=np.deg2rad(angle_degrees)
#...
在 calculate_U_and_V__vector_magnitude_and_direction
中。这将允许您使用
plt.quiver(x, y, x_change, y_change, pivot='middle')
并得到正确的结果:
给定纵横比值的二维数组(罗盘方位,例如由高程模型的纵横比导数表示),我正在创建一个 quiver plot using matplotlib。这被放置在方面值的彩色矩阵上以充当检查。
代码之所以有效,是因为它创建了我想要的内容,但仅在参数与我的预期相反的地方创建。我犯了一个简单的错误,但无法发现它。
问题: 虽然 matplotlib.pyplot.quiver()
期望 quiver([X, Y], U, V, [C], **kw)
,但为什么我的代码只给出 quiver([X, Y], V, U)
的预期答案(即 U 和 V是否反过来)被使用?
顺便说一句,在绘图时,我将 plt.imshow
的原点移到了 lower
(如 here 所讨论的)。我认为问题出在与我的索引等相关的地方
下面的代码(使用 python 3.5 和 matplotlib v3.x):
import numpy as np
import matplotlib.pyplot as plt
def compassBearing_to_standardPosition__degrees_counterClockwise(bearing_deg):
"""Vector magnitude and direction calculations assume angle is relative to the x axis
i.e. 0 degrees north is at 3 o'clock
Adjust compass bearings to be relative to standard position
"""
std_pos=(450 - bearing_deg) % 360
return(std_pos)
def calculate_U_and_V__vector_magnitude_and_direction(angle_degrees, magnitude=1):
"""Calculates the components of a vector given in magnitude (U) and direction (V) form
angle: Expected that angles are in standard position
i.e. relative to the x axis or where 3 o'clock is zero and not the compass bearing
where 12 o'clock is 0
magnitude: defaults to 1
"""
angle_rad=np.deg2rad(angle_degrees)
x = magnitude * np.cos(angle_rad) # change in x == U
y = magnitude * np.sin(angle_rad) # change in y == V
return(x,y)
def array_indices(arr, indexing='xy'):
"""Calculates index positions of each cell in array
These can be used to map to e.g. when creating a quiver plot
indexing: Giving the string 'ij' returns a meshgrid with
matrix indexing, while 'xy' returns a meshgrid with Cartesian indexing.
In the 2-D case with inputs of length M and N, the outputs are of shape
(N, M) for 'xy' indexing and (M, N) for 'ij' indexing.
"""
nrows, ncols = arr.shape
nx = 1
ny = 1
x = np.linspace(0, ncols-1, ncols)
y = np.linspace(0, nrows-1, nrows)
#y = np.linspace(nrows-1, 0, nrows) # note that the largest vlue is first
xi, yi = np.meshgrid(x, y, indexing=indexing)
return(xi, yi)
#Create a toy aspect grid (degrees North)
aspect_grid=np.array([[ 216, 226, 151],
[ 74, 323, 268],
[ 177, 204, 84]])
#Get the array indices
x,y=array_indices(aspect_grid, indexing='xy')
#Get U and V
x_change,y_change=calculate_U_and_V__vector_magnitude_and_direction(aspect_grid.flatten())
#Plot quiver over imshow
cmap = 'twilight_shifted' # this will expect matplotlib v3.x
plt.imshow(np.floor(aspect_grid), cmap=cmap, origin='lower')
plt.colorbar(label="Aspect (degrees N)")
plt.quiver(x, y, y_change, x_change, pivot='middle') # <<< why not x,y,x_change,y_change?
plt.title("Surface aspect values")
plt.show()
当您将 aspect_grid
数组传递给 calculate_U_and_V__vector_magnitude_and_direction
时,您并没有将它们从绝对方位角转换为逆时针度数,因为 compassBearing_to_standardPosition__degrees_counterClockwise
没有在 calculate_U_and_V__vector_magnitude_and_direction
中被调用。由于两个约定的 90 度错位,这导致 cos(angle)
对应于 y
组件,而 sin(angle)
对应于 x
组件(由于 属性 cos(x - pi/2) == sin(x)
)。为了纠正这个问题,你只需要使用你设置的转换(它正确地从方位转换为标准位置)通过做类似
#...
angle_degrees = compassBearing_to_standardPosition__degrees_counterClockwise(angle_degrees)
angle_rad=np.deg2rad(angle_degrees)
#...
在 calculate_U_and_V__vector_magnitude_and_direction
中。这将允许您使用
plt.quiver(x, y, x_change, y_change, pivot='middle')
并得到正确的结果: