【问题标题】:Using Colormap with Annotate Arrow in Matplotlib在 Matplotlib 中使用带有注释箭头的颜色图
【发布时间】:2017-11-07 17:18:12
【问题描述】:

我见过很多在 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()

【问题讨论】:

  • 我认为您应该更详细地了解您想要实现的目标。如果您知道如何使用 annotate 绘制不同的箭头,请显示 minimal reproducible example 并明确说明阻碍您使用颜色图作为其颜色的原因。
  • 作为这里的新用户,您可能还想阅读How to Ask 或一般the guide about questions。
  • 我已经更新了一个简单的例子。如果我的帖子还不够清楚,请告诉我。
  • 颜色图将一些数量映射到颜色。这种情况下的数量是多少?
  • 我想这个数量是从箭头尾部经过的距离。

标签: python matplotlib


【解决方案1】:

好的,我们来制作彩虹箭。 ;-)
当然,没有内置的方法可以用颜色渐变为箭头着色。相反,需要手动构建箭头。我可以想到两个选择。 (1) 创建一个颜色渐变,并用箭头的圆周路径对其进行裁剪。 (2) 生成一个带有颜色渐变的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()


以下是老的解决方案,由于误会造成的

注释箭头是单箭头。因此,您需要单独绘制任意数量的箭头。为了让每个箭头获得颜色,您可以使用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()

【讨论】:

  • 感谢您的回复,但这并不是我想要的。我最初的问题是询问是否可以绘制具有指定颜色图的整个颜色范围的单个注释箭头。我知道可以从颜色图中指定一种颜色,但我不明白如何(如果有的话)用颜色图中的所有颜色绘制一个箭头。
  • 好吧,我迷路了。你想让一个箭头有几种颜色吗?所以会同时是红绿黄?
  • 是的。抱歉,如果我没有清楚地解释这一点。我想要一个箭头,它将给定颜色图的所有颜色分布在箭头的长度上。
  • 非常感谢您的帮助!这正是我想要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多