首页 > 解决方案 > Matplotlib - 沿基本方向往返点的箭头

问题描述

问题:terrain我有一个shape 数组(N+2,N+2,4)。在最后一个维度中,我们有 1 或 -1,如果该方向上的箭头指向所讨论的点,则为 -1,如果箭头指向该方向上的点,则为 1。顺序是北、南、东、西。因此,1,-1,1,1将对应于:

在此处输入图像描述

我正在尝试使用的代码如下。但这不起作用,因为它们都是从点开始绘制的。我找不到一种方法,可以根据与所讨论terrain[i,j]的方向相对应的位置值轻松地在所需方向上从点或到点进行绘图。

import numpy as np
import matplotlib.pyplot as plt
N=3
terrain = np.zeros((N+2,N+2,4))

for i in range(1, N+1):
    for j in range(1, N+1):
        terrain[i,j] = np.random.choice([-1,1],4)

for i in range(N+2):
    for j in range(N+2):
        iterr.append([i,j])

iterr = np.array(iterr)

fig = plt.figure()
ax = fig.add_subplot(111)
plt.quiver(iterr[:,0], iterr[:,1], terrain[:,:,0].reshape(((N+2)**2,1)), np.zeros(((N+2)**2,1)), color='k')
plt.quiver(iterr[:,0], iterr[:,1], terrain[:,:,1].reshape(((N+2)**2,1)), np.zeros(((N+2)**2,1)), color='yellow')
plt.quiver(iterr[:,0], iterr[:,1], np.zeros(((N+2)**2,1)), terrain[:,:,2].reshape(((N+2)**2,1)), color='blue')
plt.quiver(iterr[:,0], iterr[:,1], np.zeros(((N+2)**2,1)), terrain[:,:,3].reshape(((N+2)**2,1)), color='red')

标签: pythonnumpymatplotlib

解决方案


在您的情况下,可能plt.quiver(X, Y, U, V, C, **kw)不是最简单的方法。quiver 方法将始终(x,y)绘制箭头向量 (u,v )。

迭代数据并用于plt.arrow(x, y, dx, dy, **kwargs)绘制箭头可能更容易。

使用你的数据结构,plt.arrow我写了这个,我跳过了所有的 0 值terrain

import numpy as np
import matplotlib.pyplot as plt
N=3
terrain = np.zeros((N+2,N+2,4))

for i in range(1, N+1):
    for j in range(1, N+1):
        terrain[i,j] = np.random.choice([-1,1],4)

iterr = []
for i in range(N+2):
    for j in range(N+2):
        iterr.append([i,j])

iterr = np.array(iterr)

#-------------------------------------------------

fig = plt.figure()
ax = fig.add_subplot(111, aspect='equal')

X = iterr[:,0]
Y = iterr[:,1]
cardinal_vectors = [(0,1), (0,-1), (1,0), (-1,0)]   # north, south, east, west
cardinal_colors  = ['black', 'green', 'blue', 'red'] 

# plot all points        
plt.plot(X,Y,'k.')

for x, y, arrow_directions in zip(X, Y, terrain.reshape(((N+2)**2,4))):

    for direction, vector, color in zip(arrow_directions, 
                                        cardinal_vectors, 
                                        cardinal_colors):

        arrow_size = 0.5
        head_size  = 0.2
        arrow_args = {'length_includes_head' : True,
                      'head_width'           : head_size, 
                      'head_length'          : head_size, 
                      'width'                : 0.02,
                      'fc'                   : color, 
                      'ec'                   : color}

        dx = vector[0] * arrow_size
        dy = vector[1] * arrow_size 

        if direction == 1:
            # arrow FROM (x,y)
            plt.arrow(x, y, dx, dy, **arrow_args)
        if direction == -1:
            # arrow TO (x,y)
            plt.arrow(x + dx, y + dy, -dx, -dy, **arrow_args)

plt.show()

推荐阅读