在轴外绘制带文本的箭头

时间:2017-03-29 23:58:36

标签: python matplotlib annotations

我想绘制一个带有跨越多个轴的文本的箭头。阅读http://matplotlib.org/users/annotations_guide.html

我走得那么远:

fig,ax = plt.subplots(2,3)
bbox_props = dict(boxstyle="rarrow,pad=0.2", fc="cyan", ec="b", lw=1)
t = ax[0,1].text(-0.8, 1.2, "Mag", ha="center", va="center", rotation=0, size=15, bbox=bbox_props)

使

arrow

我从text docs发现bbox是Rectangle的字典,它有宽度和高度,但是当我设置

bbox_props = dict(boxstyle="rarrow,pad=0.2", fc="cyan", ec="b", lw=1, width=3)
t = ax[0,1].text(-0.8, 1.2, "Mag", ha="center", va="center", rotation=0, size=15, bbox=bbox_props)

我发生了冲突:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-255-006733283545> in <module>()
     13 # properties of a rectangle : http://matplotlib.org/api/patches_api.html#matplotlib.patches.Rectangle
     14 
---> 15 t = ax[0,1].text(-0.8, 1.2, "Mag", ha="center", va="center", rotation=0, size=15, bbox=bbox_props)
     16 plt.savefig('example.png', bbox_inches='tight')

/Users/chris/anaconda3/lib/python3.5/site-packages/matplotlib/axes/_axes.py in text(self, x, y, s, fontdict, withdash, **kwargs)
    626         if fontdict is not None:
    627             t.update(fontdict)
--> 628         t.update(kwargs)
    629 
    630         t.set_clip_path(self.patch)

/Users/chris/anaconda3/lib/python3.5/site-packages/matplotlib/text.py in update(self, kwargs)
    242         super(Text, self).update(kwargs)
    243         if bbox:
--> 244             self.set_bbox(bbox)  # depends on font properties
    245 
    246     def __getstate__(self):

/Users/chris/anaconda3/lib/python3.5/site-packages/matplotlib/text.py in set_bbox(self, rectprops)
    514                                     bbox_transmuter=bbox_transmuter,
    515                                     transform=mtransforms.IdentityTransform(),
--> 516                                     **props)
    517         else:
    518             self._bbox_patch = None

TypeError: __init__() got multiple values for argument 'width'

如何使用bbox控制箭头的大小?有没有办法将它一直延伸到右边?

谢谢! 克里斯

2 个答案:

答案 0 :(得分:1)

如果你向两边添加一堆空格,它会起作用:

fig,axes = plt.subplots(2,3)
ax = axes[0,0]
bbox_props = dict(boxstyle="rarrow, pad=0.2", fc="cyan", ec="b", lw=1)
t = ax.text(0.15,1.15,45*' '+'Mag'+45*' ', ha="left", va="center",
            size=15,bbox=bbox_props)
plt.show()

结果图片:

enter image description here

答案 1 :(得分:1)

一个选项是为自定义箭头样式构建我们自己的width参数 为此,我们可以继承BoxStyle.RArrow并在新创建的类width中引入MyRArrow参数。
然后箭头的点将被该宽度偏移。在这个简单的示例中,width以像素为单位。 最后,我们可以将这个新课程注册为boxstyle "myrarrow"

from matplotlib.patches import BoxStyle


class MyRArrow(BoxStyle.RArrow):
        def __init__(self, pad=0.3, width=220):
            self.width_ = width
            super(MyRArrow, self).__init__(pad)

        def transmute(self, x0, y0, width, height, mutation_size):
            p = BoxStyle.RArrow.transmute(self, x0, y0,
                                          width, height, mutation_size)
            x = p.vertices[:, 0]
            p.vertices[1:3, 0] = x[1:3] - self.width_
            p.vertices[0, 0]   = x[0]   + self.width_
            p.vertices[3:, 0]  = x[3:]  + self.width_
            return p

BoxStyle._style_list["myrarrow"] = MyRArrow

我们现在可以使用这种新样式并指定boxstyle="myrarrow,pad=0.2, width=150"作为bbox关键字参数 然后在图坐标中指定箭头位置而不是轴坐标也是有意义的。

import matplotlib.pyplot as plt

fig,ax = plt.subplots(2,3)
bbox_props = dict(boxstyle="myrarrow,pad=0.2, width=150", fc="cyan", ec="b", lw=1)
t = ax[0,1].text(0.5, 0.95, "Mag", ha="center", va="center", 
                rotation=0, size=15, bbox=bbox_props, transform=fig.transFigure)

plt.show()

enter image description here