【问题标题】:Color matplotlib quiver field according to magnitude and direction根据大小和方向为 matplotlib 颤动场着色
【发布时间】:2013-11-03 18:48:52
【问题描述】:

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

同时考虑幅度和方向,计算 Cmatplotlib.pyplot.quiver 的最佳方法是什么?

【问题讨论】:

  • 我发现这个帖子回答了一个类似的问题。 stackoverflow.com/questions/11970186/…
  • 计算 C 的方式完全取决于您的需要。您问题中指示的 Matlab 文件仅使用方向来计算颜色。你能准确地说出你在寻找什么效果。可能这个问题本身不再重要,因为它已经这么久了。但它可能会帮助其他可能面临类似问题的人。

标签: python matlab vector matplotlib


【解决方案1】:

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

我和一个朋友为我的论文编写了以下脚本(半小时左右),使用电子表格中的十六进制值绘制我的实验数据。一旦我们完成了这个学期,我们将使它更加自动化,但是将颜色图传递给 quiver 的问题是它由于某种原因不能接受矢量形式。

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2020-12-15
      • 2014-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-30
      • 1970-01-01
      • 2019-11-23
      • 1970-01-01
      相关资源
      最近更新 更多