根据幅度和方向颜色matplotlib箭袋场

时间:2013-10-24 20:56:58

标签: python matlab vector matplotlib

我试图获得与this function in Matlab相同的行为,其中每个箭头的颜色对应于它的大小和方向,基本上从轮子中绘制颜色。我看到了this question,但它似乎只适用于barbs。我也看到了这个答案,但是quiver抱怨颜色数组必须是二维的。

考虑到幅度和方向,计算matplotlib.pyplot.quiverC的最佳方法是什么?

2 个答案:

答案 0 :(得分:1)

我不知道你是否发现使用matplotlib 1.4.x的箭袋具有3d功能。但是,在尝试为箭头着色时,此功能会受到限制。

我的朋友和我编写了以下脚本(半小时左右),使用电子表格中的十六进制值来绘制我的实验数据。我们在完成学期后会更加自动化,但将色彩图传递给箭袋的问题在于,由于某种原因,它无法接受矢量形式。

This link是我的git存储库,其中托管了我使用的代码,稍微由另一位朋友整理。

我希望我可以节省一些时间。

答案 1 :(得分:1)

尽管现在已经很老了,但我遇到了同样的问题。基于 matplotlibs quiver demomy own answer to this post,我创建了以下示例。这个想法是使用 HSV colors 色调值将矢量的角度转换为颜色。向量的绝对值用作饱和度和值。

MyModel.query

Result plot

色轮如下。编辑中提到了生成它的代码。


编辑

我刚刚注意到,链接的 matlab 函数“将矢量场呈现为单位长度箭头的网格。箭头方向表示矢量场方向,颜色表示幅度”。所以我上面的例子并不是真正的问题。这里有一些修改。

左图与上图相同。正确的是,引用的 matlab 函数的作用是:单位长度的箭头图,颜色表示幅度。中心不使用大小,而只使用颜色中的方向,这也可能有用。我希望从这个例子中可以清楚地看出其他组合。

Result plot

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()

要绘制色轮,请使用以下代码。请注意,这使用了上面的 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()