在Matplotlib中将图表标题拆分成多行

65

我使用matplotlib创建一个带有4个子图的图形。

我想要分割其中一个子图的标题,以使每行都相对于子图居中对齐。

我尝试过:

import matplotlib.pylab as plt

fig = plt.figure(num=0,figsize=(8.27, 11.69), dpi=300)
ax  = fig.add_subplot(2, 2, 1)
ax.set_title(r'Normalized occupied \\ Neighbors')

我得到的是 Neighbors 靠左缩进。

我该如何更正呢?

5个回答

115

当我以这种方式格式化字符串时,我得到了正确的对齐方式:

import matplotlib.pylab as plt

fig = plt.figure()#num=0,figsize=(8.27, 11.69), dpi=300)
ax  = fig.add_subplot(2, 2, 1)
ax.set_title('Normalized occupied \n Neighbors')

plt.show()

在此输入图片描述


26
在Matplotlib 3.1.1中,plt.title()ax.set_title()都允许将文本属性作为kwargs传递,因此您可以传递wrap=True:
plt.title('My long title that I want to wrap and stay center-aligned', wrap=True)

或者

fig, [ax1, ax2] = plt.subplots(2, 1)
ax1.set_title('My long title that I want to wrap and stay center-aligned', wrap=True)

2
这应该是正确的答案,因为它会根据您的图像大小动态调整标题长度。 - Kel Solaar

25

一个更好的解决方案,可以与 r 前缀兼容(特别是当需要使用 LaTeX 标记时),是将标题文本分成两个(或多个)部分,例如:

import matplotlib.pylab as plt

fig = plt.figure()
plt.title('My Title\n' + r'$\alpha - \omega$ are LaTeX Markup')
plt.plot([1,2,3,4])
plt.show()

3
谢谢您的评论 - 我可以在标题中使用两行并为它们分别设置属性吗?比如对于上一行使用更大的字体和粗体,对于下一行使用普通字体? - spiff

1

除了之前的回答,如果有人想要自动化操作,我编写了一个函数来简化这个过程。 这是它:

def split_title_line(title_text, split_on='(', max_words=5):  # , max_words=None):
    """
    A function that splits any string based on specific character
    (returning it with the string), with maximum number of words on it
    """
    split_at = title_text.find (split_on)
    ti = title_text
    if split_at > 1:
        ti = ti.split (split_on)
        for i, tx in enumerate (ti[1:]):
            ti[i + 1] = split_on + tx
    if type (ti) == type ('text'):
        ti = [ti]
    for j, td in enumerate (ti):
        if td.find (split_on) > 0:
            pass
        else:
            tw = td.split ()
            t2 = []
            for i in range (0, len (tw), max_words):
                t2.append (' '.join (tw[i:max_words + i]))
            ti[j] = t2
    ti = [item for sublist in ti for item in sublist]
    ret_tex = []
    for j in range (len (ti)):
        for i in range(0, len(ti)-1, 2):
            if len (ti[i].split()) + len (ti[i+1].split ()) <= max_words:
                mrg = " ".join ([ti[i], ti[i+1]])
                ti = [mrg] + ti[2:]
                break

    if len (ti[-2].split ()) + len (ti[-1].split ()) <= max_words:
        mrg = " ".join ([ti[-2], ti[-1]])
        ti = ti[:-2] + [mrg]
    return '\n'.join (ti)

示例:

输入:split_title_line('小学毕业率(女孩占比)')

输出:

Primary school completion 
(% of girls)

输入: split_title_line ('全国小学女生完成率') 输出:

Primary school completion in the
country as % of girls

针对您关于在matplotlib中分割标题的问题,您可以添加以下代码:ax.set_title(split_title_line(r'Normalized occupied Neighbors', max_words=2))

希望每个人都从中受益。


看起来很有用,谢谢!如果有一种根据最大字符数拆分的方法,那就太好了 :) - information_interchange

0

我想要补充一下我的看法:这里的问题更普遍,涉及到正确插入换行符,将单个长行文本分割成一个视觉上令人愉悦、美观的块。因此,这是我的贡献,它与Mohammed的方法非常相似,只是将字符串分成了每5个单词一组。很容易根据您的需要进行自定义(分隔符、长度等)。

def pretty_name(text):
  words = text.split("_")
  total_string = ""
  for counter, word in enumerate(words):
    if counter>0 and counter % 5 == 0:
      total_string +="\n{}".format(word)
    else:
      total_string +=" {}".format(word)
  return total_string.lstrip()



网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接