Seaborn:有没有更好的方法将文本包装在我的条形图中?

mes*_*748 5 python data-visualization matplotlib word-wrap seaborn

我正在编写一个条形图函数,并遇到了另一个小问题。我有一些 ytick 标签太长,导致我的 y 轴标签看不到。只有当我大幅减小 ytick 标签的大小时,我才能看到 y 标签。

def bar_plot(data, x, y, title):
    sns.set_style('darkgrid')
    data = data.sort_values(ascending=False, by=x)
    data = data.head(n=10)
    if (data[x]>1000000).any():
        data[x] = data[x] / 1000000
        ax = sns.barplot(data=data, x=x, y=y)
        ax.set_title(title, size=35)
        ax.set_xlabel(x + ' ($ Millions)', size=15)
        ax.set_ylabel(y, size=15)
        ax.set_yticklabels(data[y].head(n=10), wrap=True)

    else:
       ax = sns.barplot(data=data, x=x, y=y)
       ax.set_xlabel(x, size=15)
       ax.set_ylabel(y, size=15)
       ax.set_title(title, size=35)
       ax.set_yticklabels(data[y].head(n=10), wrap=True)
Run Code Online (Sandbox Code Playgroud)

我尝试过ax.set_yticklabels(data[y].head(n=10), wrap=True)将文本换行。虽然它有效,但它对文本的换行还不够。有没有办法告诉wrap=Truex 个字符后换行?我试过用谷歌搜索这个,但找不到任何有效的东西。

编辑

我正在使用的数据框的格式类似于

def bar_plot(data, x, y, title):
    sns.set_style('darkgrid')
    data = data.sort_values(ascending=False, by=x)
    data = data.head(n=10)
    if (data[x]>1000000).any():
        data[x] = data[x] / 1000000
        ax = sns.barplot(data=data, x=x, y=y)
        ax.set_title(title, size=35)
        ax.set_xlabel(x + ' ($ Millions)', size=15)
        ax.set_ylabel(y, size=15)
        ax.set_yticklabels(data[y].head(n=10), wrap=True)

    else:
       ax = sns.barplot(data=data, x=x, y=y)
       ax.set_xlabel(x, size=15)
       ax.set_ylabel(y, size=15)
       ax.set_title(title, size=35)
       ax.set_yticklabels(data[y].head(n=10), wrap=True)
Run Code Online (Sandbox Code Playgroud)

Wil*_*ler 5

正如@ImportanceOfBeingErnest指出的,您可以使用该textwrap模块来执行此操作,特别有用的是textwrap.fill()

textwrap.fill(text[, width[, ...]])

将文本中的单个段落换行,以便每行最多为width字符长,并返回包含换行段落的单个字符串。fill()是简写

"\n".join(wrap(text, ...))

尽管您需要在每个标签上分别调用类似的内容

ax.set_yticklabels([textwrap.fill(e, width) for e in data[y].head()])
Run Code Online (Sandbox Code Playgroud)

编辑

这是一个更完整的示例来展示用法:

import textwrap
import matplotlib.pyplot as plt
import pandas as pd

df = {'Client Name': ['Some Name', 'Some long company name', 'Name',
            'Company', 'Long Comany Name'],
      'Col 1': [51235, 152, 12554, 12464, 12434]}
data = pd.DataFrame(df)

fig, ax = plt.subplots(1)


ax.set_yticklabels(data['Client Name'].head())
plt.show()
Run Code Online (Sandbox Code Playgroud)

这将显示以下内容

在此输入图像描述

然而

ax.set_yticklabels([textwrap.fill(e, 7) for e in data['Client Name'].head()])
plt.show()
Run Code Online (Sandbox Code Playgroud)

会显示更多类似的东西

在此输入图像描述