2017-03-29 24 views
2

我想绘制一个箭头,文字可以横跨多个轴线。阅读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控制我的箭头大小?有没有办法将它扩展到正确的位置?

谢谢! 克里斯

回答

1

的选择是建立了自己的width参数传递给自定义箭头风格。
为此,我们可以子类BoxStyle.RArrow并在新创建的类MyRArrow中引入width参数。
箭头的点将被这个宽度所抵消。在这个简单的例子中,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

+1

非常感谢你,这是一个非常整洁的解决方案,因为文本保持以箭头为中心,我可以轻松控制其宽度。这比我想象的要复杂,但我学到了一些关于箭头的新东西。那很棒! – scichris

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

+0

谢谢!这是非常简单的解决方案,它也可以工作。我真的很喜欢它的简单性 - 这是一个黑客工作。 @Importance的答案非常详细,但涉及更多。我现在将使用你的答案,因为它更短,并保留另一个在我非常有用的代码库。 – scichris

+0

欢呼声,伴侣:-)请接受我们带有复选标记的答案,以便人们知道这是回答。 – bernie