包装文本在matplotlib中不起作用

时间:2018-01-03 14:29:45

标签: python matplotlib text

我正在尝试使用wrap = True来包装文本,但它似乎对我不起作用。从下面的matplotlib运行示例:

import matplotlib.pyplot as plt

fig = plt.figure()
plt.axis([0, 10, 0, 10])
t = "This is a really long string that I'd rather have wrapped so that it"\
    " doesn't go outside of the figure, but if it's long enough it will go"\
    " off the top or bottom!"
plt.text(4, 1, t, ha='left', rotation=15, wrap=True)
plt.text(6, 5, t, ha='left', rotation=15, wrap=True)
plt.text(5, 5, t, ha='right', rotation=-15, wrap=True)
plt.text(5, 10, t, fontsize=18, style='oblique', ha='center',
         va='top', wrap=True)
plt.text(3, 4, t, family='serif', style='italic', ha='right', wrap=True)
plt.text(-1, 0, t, ha='left', rotation=-15, wrap=True)

plt.show()

告诉我这个:

文字换行错误

enter image description here

关于问题的任何想法?

1 个答案:

答案 0 :(得分:1)

Matplotlib硬连线使用图形框作为包装宽度。要解决此问题,您必须重写_get_wrap_line_width方法,该方法返回以像素为单位的行的长度。例如:

text = ('Lorem ipsum dolor sit amet, consectetur adipiscing elit, '
        'sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ')
txt = ax.text(.2, .8, text, ha='left', va='top', wrap=True,
              bbox=dict(boxstyle='square', fc='w', ec='r'))
txt._get_wrap_line_width = lambda : 600.  #  wrap to 600 screen pixels

lambda函数只是创建函数/方法的简便方法,而无需使用def编写命名函数。

显然,使用私有方法会带来风险,例如在将来的版本中将其删除。而且我还没有测试过旋转的效果。如果您想做一些更复杂的事情,例如使用数据坐标,则必须继承Text类,并显式重写_get_wrap_line_width方法。

import matplotlib.pyplot as plt
import matplotlib.text as mtext

class WrapText(mtext.Text):
    def __init__(self,
                 x=0, y=0, text='',
                 width=0,
                 **kwargs):
        mtext.Text.__init__(self,
                 x=x, y=y, text=text,
                 wrap=True,
                 **kwargs)
        self.width = width  # in screen pixels. You could do scaling first

    def _get_wrap_line_width(self):
        return self.width

fig = plt.figure(1, clear=True)
ax = fig.add_subplot(111)

text = ('Lorem ipsum dolor sit amet, consectetur adipiscing elit, '
        'sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ')

# Create artist object. Note clip_on is True by default
# The axes doesn't have this method, so the object is created separately
# and added afterwards.
wtxt = WrapText(.8, .4, text, width=500, va='top', clip_on=False,
                bbox=dict(boxstyle='square', fc='w', ec='b'))
# Add artist to the axes
ax.add_artist(wtxt)

plt.show()