私はMatlabでこの関数と同じ動作を実現しようとしています。これにより、各矢印の色はその大きさと方向の両方に対応し、基本的にホイールからその色を描画します。この質問を見ましたが、 でしか機能しないようですbarbs
。this answer も見ましたがquiver
、カラー配列は 2 次元でなければならないと文句を言います。
大きさと方向の両方を考慮して、 をC
計算する最良の方法は何ですか?matplotlib.pyplot.quiver
私はMatlabでこの関数と同じ動作を実現しようとしています。これにより、各矢印の色はその大きさと方向の両方に対応し、基本的にホイールからその色を描画します。この質問を見ましたが、 でしか機能しないようですbarbs
。this answer も見ましたがquiver
、カラー配列は 2 次元でなければならないと文句を言います。
大きさと方向の両方を考慮して、 をC
計算する最良の方法は何ですか?matplotlib.pyplot.quiver
これはかなり古いものですが、同じ問題に遭遇しました。matplotlibs quiver demoとこの投稿に対する私自身の回答に基づいて、次の例を作成しました。アイデアは、 HSV 色の色相値を使用して、ベクトルの角度を色に変換することです。ベクトルの絶対値が彩度と値として使用されます。
import numpy as np
import matplotlib.colors
import matplotlib.pyplot as plt
def vector_to_rgb(angle, absolute):
"""Get the rgb value for the given `angle` and the `absolute` value
Parameters
----------
angle : float
The angle in radians
absolute : float
The absolute value of the gradient
Returns
-------
array_like
The rgb value as a tuple with values [0..1]
"""
global max_abs
# normalize angle
angle = angle % (2 * np.pi)
if angle < 0:
angle += 2 * np.pi
return matplotlib.colors.hsv_to_rgb((angle / 2 / np.pi,
absolute / max_abs,
absolute / max_abs))
X = np.arange(-10, 10, 1)
Y = np.arange(-10, 10, 1)
U, V = np.meshgrid(X, Y)
angles = np.arctan2(V, U)
lengths = np.sqrt(np.square(U) + np.square(V))
max_abs = np.max(lengths)
c = np.array(list(map(vector_to_rgb, angles.flatten(), lengths.flatten())))
fig, ax = plt.subplots()
q = ax.quiver(X, Y, U, V, color=c)
plt.show()
カラーホイールは以下。それを生成するためのコードは編集に記載されています。
編集
リンクされたmatlab関数が「ベクトルフィールドを単位長の矢印のグリッドとしてレンダリングします。矢印の方向はベクトルフィールドの方向を示し、色は大きさを示します」ことに気付きました。したがって、上記の例は実際には問題の内容ではありません。ここにいくつかの変更があります。
左のグラフは上と同じです。右のものは、引用された matlab 関数が行うことです。色が大きさを示す単位長の矢印プロット。中央のものは大きさを使用せず、色の方向のみを使用します。これも役立つ場合があります。この例から他の組み合わせが明らかであることを願っています。
import numpy as np
import matplotlib.colors
import matplotlib.pyplot as plt
def vector_to_rgb(angle, absolute):
"""Get the rgb value for the given `angle` and the `absolute` value
Parameters
----------
angle : float
The angle in radians
absolute : float
The absolute value of the gradient
Returns
-------
array_like
The rgb value as a tuple with values [0..1]
"""
global max_abs
# normalize angle
angle = angle % (2 * np.pi)
if angle < 0:
angle += 2 * np.pi
return matplotlib.colors.hsv_to_rgb((angle / 2 / np.pi,
absolute / max_abs,
absolute / max_abs))
X = np.arange(-10, 10, 1)
Y = np.arange(-10, 10, 1)
U, V = np.meshgrid(X, Y)
angles = np.arctan2(V, U)
lengths = np.sqrt(np.square(U) + np.square(V))
max_abs = np.max(lengths)
# color is direction, hue and value are magnitude
c1 = np.array(list(map(vector_to_rgb, angles.flatten(), lengths.flatten())))
ax = plt.subplot(131)
ax.set_title("Color is lenth,\nhue and value are magnitude")
q = ax.quiver(X, Y, U, V, color=c1)
# color is length only
c2 = np.array(list(map(vector_to_rgb, angles.flatten(),
np.ones_like(lengths.flatten()) * max_abs)))
ax = plt.subplot(132)
ax.set_title("Color is direction only")
q = ax.quiver(X, Y, U, V, color=c2)
# color is direction only
c3 = np.array(list(map(vector_to_rgb, 2 * np.pi * lengths.flatten() / max_abs,
max_abs * np.ones_like(lengths.flatten()))))
# create one-length vectors
U_ddash = np.ones_like(U)
V_ddash = np.zeros_like(V)
# now rotate them
U_dash = U_ddash * np.cos(angles) - V_ddash * np.sin(angles)
V_dash = U_ddash * np.sin(angles) + V_ddash * np.cos(angles)
ax = plt.subplot(133)
ax.set_title("Uniform length,\nColor is magnitude only")
q = ax.quiver(X, Y, U_dash, V_dash, color=c3)
plt.show()
カラー ホイールをプロットするには、次のコードを使用します。max_abs
これは、色相と値が到達できる最大値である上記の値を使用することに注意してください。ここvector_to_rgb()
でも関数が再利用されます。
ax = plt.subplot(236, projection='polar')
n = 200
t = np.linspace(0, 2 * np.pi, n)
r = np.linspace(0, max_abs, n)
rg, tg = np.meshgrid(r, t)
c = np.array(list(map(vector_to_rgb, tg.T.flatten(), rg.T.flatten())))
cv = c.reshape((n, n, 3))
m = ax.pcolormesh(t, r, cv[:,:,1], color=c, shading='auto')
m.set_array(None)
ax.set_yticklabels([])