在Matplotlib中使用带有注释箭头的Colormap

时间:2017-11-07 17:18:12

标签: python matplotlib

我见过很多在Matplotlib中使用注释箭头的例子,它们指定了一种颜色。我想知道是否可以根据色图设置颜色,以便指定色图的整个颜色范围显示在单个箭头上。我知道可以从颜色图中将箭头的颜色设置为单一颜色,但我希望有一个箭头显示给定颜色图的所有颜色。

使用注释箭头的简单示例如下所示。在文档中,我没有找到任何指定色彩映射的方法。如果我天真地指定色彩映射,我会从无效的RGBA参数中得到错误。

import matplotlib.pyplot as plt

RdPu = plt.get_cmap('RdPu')

ax = plt.subplot(111)
ax.annotate("Test", xy=(0.2, 0.2), xycoords='data',
    xytext=(0.8, 0.8), textcoords='data',
    size=20, arrowprops=dict(color=RdPu),
)

plt.show()

1 个答案:

答案 0 :(得分:0)

好的,让我们制作 The Rainbow Arrow 。 ;-)
当然没有内置的方法来使用颜色渐变着色箭头。相反,需要手动构建箭头。我可以想到两个选择。 (1)创建颜色渐变并使用箭头的圆周路径剪切它。 (2)使用colorgradient生成LineCollection,然后向其添加箭头。

以下是第二个选项:

import matplotlib.pyplot as plt
import matplotlib.transforms
import matplotlib.path
import numpy as np
from matplotlib.collections import LineCollection

def rainbowarrow(ax, start, end, cmap="viridis", n=50,lw=3):
    cmap = plt.get_cmap(cmap,n)
    # Arrow shaft: LineCollection
    x = np.linspace(start[0],end[0],n)
    y = np.linspace(start[1],end[1],n)
    points = np.array([x,y]).T.reshape(-1,1,2)
    segments = np.concatenate([points[:-1],points[1:]], axis=1)
    lc = LineCollection(segments, cmap=cmap, linewidth=lw)
    lc.set_array(np.linspace(0,1,n))
    ax.add_collection(lc)
    # Arrow head: Triangle
    tricoords = [(0,-0.4),(0.5,0),(0,0.4),(0,-0.4)]
    angle = np.arctan2(end[1]-start[1],end[0]-start[0])
    rot = matplotlib.transforms.Affine2D().rotate(angle)
    tricoords2 = rot.transform(tricoords)
    tri = matplotlib.path.Path(tricoords2, closed=True)
    ax.scatter(end[0],end[1], c=1, s=(2*lw)**2, marker=tri, cmap=cmap,vmin=0)
    ax.autoscale_view()

fig,ax = plt.subplots()
ax.axis([0,5,0,4])
ax.set_aspect("equal")

rainbowarrow(ax, (3,3), (2,2.5), cmap="viridis", n=100,lw=3)
rainbowarrow(ax, (1,1), (1.5,1.5), cmap="jet", n=50,lw=7)
rainbowarrow(ax, (4,1.3), (2.7,1.0), cmap="RdYlBu", n=23,lw=5)

plt.show()

Matplotlib rainbow arrow

<小时/> 以下是由于误解造成的旧解决方案

注释箭头是单箭头。因此,您需要单独绘制任意数量的箭头。为了使每个箭头获得颜色,您可以使用arrowprops=dict(color="<some color>")参数。

要从色彩映射中获取颜色,可以使用值调用色彩映射。这里箭头的长度可以作为编码为颜色的数量。

import matplotlib.pyplot as plt
import numpy as np

RdPu = plt.get_cmap('RdPu')

ax = plt.subplot(111)
ax.axis([-6,2,-4.5,3.2])
ax.set_aspect("equal")

X = np.linspace(0,1,17, endpoint=False)
Xt =np.sin(2.5*X+3)
Yt = 3*np.cos(2.6*X+3.4)

Xh = np.linspace(-0.5,-5,17)
Yh = -1.3*Xh-5

#Distance
D = np.sqrt((Xh-Xt)**2+(Yh-Yt)**2)
norm = plt.Normalize(D.min(), D.max())

for xt, yt, xh, yh, d in zip(Xt,Yt,Xh,Yh,D):
    ax.annotate("Test", xy=(xh,yh), xycoords='data',
                xytext=(xt,yt), textcoords='data',
                size=10, arrowprops=dict(color=RdPu(norm(d))))

plt.show()

enter image description here