【问题标题】:Wrapping text not working in matplotlib环绕文本在 matplotlib 中不起作用
【发布时间】:2018-01-03 14:29:45
【问题描述】:

我正在尝试使用 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()

给我这个:

文本换行出错

有什么想法吗?

【问题讨论】:

  • 在 Python 3.4 和 matplotlib 2.1.1 上为我工作。你用的是什么版本的 Python 和 matplotlib?
  • 您好,这是 Anaconda #705 自 2016 年 3 月 15 日以来的问题。问题仍然存在。我刚刚在那里发表了评论,问题仍然存在。
  • 使用 matplotlib 2.1.0 运行 Anaconda/python 3.6.3

标签: python matplotlib text


【解决方案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()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-07
    相关资源
    最近更新 更多