如何为seaborn catplot的每个子图自定义文本刻度标签

4

让我们考虑以下示例(来源于 Seaborn 文档):

titanic = sns.load_dataset("titanic")

fg = sns.catplot(x="age", y="embark_town",
                hue="sex", row="class",
                data=titanic[titanic.embark_town.notnull()],
                orient="h", height=2, aspect=3, palette="Set3",
                kind="violin", dodge=True, cut=0, bw=.2)

输出:

输入图像描述

我想要更改y轴的刻度标签,例如在数字前加括号:(1)南安普敦,(2)瑟堡,(3)昆士敦。我看到了这个答案,并且尝试使用FuncFormatter,但是结果很奇怪。以下是我的代码:

titanic = sns.load_dataset("titanic")

fg = sns.catplot(x="age", y="embark_town",
                hue="sex", row="class",
                data=titanic[titanic.embark_town.notnull()],
                orient="h", height=2, aspect=3, palette="Set3",
                kind="violin", dodge=True, cut=0, bw=.2)

from matplotlib.ticker import FuncFormatter
for ax in fg.axes.flat:
    ax.yaxis.set_major_formatter(ticker.FuncFormatter(lambda x, pos: f'({1 + pos}) {x}'))

这是输出内容:

enter image description here

看起来xlambda中的pos相同。我预期x应该是刻度标签的值(即Southampton,Cherbourg,Queenstown)。我做错了什么?


软件版本:

matplotlib                         3.4.3
seaborn                            0.11.2
1个回答

3
如何在seaborn catplot中旋转xticklabels 的答案类似,但需要为每个子图的每个刻度自定义文本。文本标签与其他示例中的数值标签工作方式不同。数字标签匹配刻度位置,但文本标签则不是如此。对于每个子图,.get_yticklabels() 返回 [Text(0, 0, 'Southampton'), Text(0, 1, 'Cherbourg'), Text(0, 2, 'Queenstown')]。如下所示,提取文本和位置,然后使用 .set_yticklabels 设置新的文本标签。测试环境为 python 3.8.12matplotlib 3.4.3seaborn 0.11.2
import seaborn as sns

titanic = sns.load_dataset("titanic")

fg = sns.catplot(x="age", y="embark_town",
                hue="sex", row="class",
                data=titanic[titanic.embark_town.notnull()],
                orient="h", height=2, aspect=3, palette="Set3",
                kind="violin", dodge=True, cut=0, bw=.2)

for ax in fg.axes.flat:  # iterate through each subplot
    labels = ax.get_yticklabels()  # get the position and text for each subplot
    for label in labels:
        _, y = label.get_position()  # extract the y tick position
        txt = label.get_text()  # extract the text
        txt = f'({y + 1}) {txt}'  # update the text string
        label.set_text(txt)  # set the text
    ax.set_yticklabels(labels)  # update the yticklabels

enter image description here


1
谢谢您的回复和解释。非常有用! - MarcoS

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