【问题标题】:Order of categoricals in seaborn PairGridseaborn PairGrid中的分类顺序
【发布时间】:2017-09-28 09:14:43
【问题描述】:

我正在使用以下代码将 seaborn stripplot 映射到 seaborn PairGrid:

import pandas as pd
import seaborn as sns

df = (pd.read_csv(filepath_or_buffer='http://vincentarelbundock.github.io/' +
              'Rdatasets/csv/ggplot2/diamonds.csv')
    .drop(labels='Unnamed: 0', axis=1)
    .astype(dtype={'cut': 'category', 'color': 'category',
                   'clarity': 'category'}))
agged = df.groupby(by=['cut', 'color']).mean().sort_index().reset_index()
g = sns.PairGrid(data=agged, x_vars=agged.columns[2:], y_vars=['cut', 'color'],
             size=5, aspect=.65)
g.map(func=sns.stripplot, orient='h', size=10, palette='Blues_d')

默认情况下,“剪切”构面中的类别按字母顺序显示。但是,我想指定顺序:

['Fair', 'Good', 'Very Good', 'Premium', 'Ideal']

我已尝试为 stripplot 传递 'order' 参数,如下所示:

g.map(func=sns.stripplot, orient='h', size=10, palette='Blues_d',
  order=['Fair', 'Good', 'Very Good', 'Premium', 'Ideal'])

虽然这会正确地对“cut”中的类别进行排序,但它根本不会在“color”方面绘制任何内容。我还尝试在相同的参数中指定“颜色”方面的顺序,如下所示:

g.map(func=sns.stripplot, orient='h', size=10, palette='Blues_d',
  order=['Fair', 'Good', 'Very Good', 'Premium', 'Ideal', 'D', 'E', 'F',
         'G', 'H', I'])

但是,这里的问题是 order 参数中的所有值都出现在“color”和“cut”方面。

是否可以在映射函数中指定一个顺序,从而在两组方面都进行正确的排序,并且没有重复?

['Fair', 'Good', 'Very Good', 'Premium', 'Ideal']
['D', 'E', 'F', 'G', 'H', I']

【问题讨论】:

  • 我试图通过包含读取我的原始 df 的代码(这是来自 ggplot2 的示例钻石数据集)来修改我的原始帖子,以使其最小化、完整和可验证。希望这会有所帮助。抱歉 - 我刚开始在这里提问,所以请耐心等待,因为我一直在努力澄清!

标签: python seaborn categorical-data


【解决方案1】:

问题是网格中的每一行都有不同的类别。因此,您需要为每一行的子图使用不同的 order

我认为没有自动提供不同订单的方法,但您可以根据行变量定义自己的订单字典

order = {'cut'  :['Fair', 'Good', 'Very Good', 'Premium', 'Ideal'],
         'color':['D', 'E', 'F', 'G', 'H', 'I']}

然后您可以将自定义函数映射到网格,它会根据行变量选择正确的顺序。

def ordered_stripplot(*args, **kwargs):
    order = kwargs.pop("order")
    sns.stripplot(args[0],args[1], order=order[args[1].name], **kwargs)

g.map(ordered_stripplot, order=order, orient='h', size=10, palette='Blues_d')

不是直接映射到sns.stripplot,而是映射到一个自定义函数,该函数将顺序字典作为输入并根据参数选择正确的顺序。这被提供给sns.stripplot,在这个函数中被调用。

完整代码:

import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns

df = (pd.read_csv(filepath_or_buffer='http://vincentarelbundock.github.io/' +
              'Rdatasets/csv/ggplot2/diamonds.csv')
    .drop(labels='Unnamed: 0', axis=1)
    .astype(dtype={'cut': 'category', 'color': 'category',
                   'clarity': 'category'}))
agged = df.groupby(by=['cut', 'color']).mean().sort_index().reset_index()

order = {'cut'  :['Fair', 'Good', 'Very Good', 'Premium', 'Ideal'],
         'color':['D', 'E', 'F', 'G', 'H', 'I']}

g = sns.PairGrid(data=agged, x_vars=agged.columns[2:], y_vars=['cut', 'color'],
             size=3, aspect=.65)

def ordered_stripplot(*args, **kwargs):
    order = kwargs.pop("order")
    sns.stripplot(args[0],args[1], order=order[args[1].name], **kwargs)

g.map(ordered_stripplot, order=order, orient='h', size=10, palette='Blues_d')

plt.tight_layout()
plt.show()

【讨论】:

  • 这是一种非常有用的技术,我可以看到它如何形成类似需求的设计模式。我得出了与您相同的结论,即不太可能提供不同的订单,但我一直在努力寻找使用自定义函数包装 stripplot 并使用订单字典的解决方案。非常优雅。我对你的答案投了赞成票,但由于我还没有足够的声誉,它仍然显示为 0。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-05
  • 1970-01-01
  • 1970-01-01
  • 2019-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多