gpt4 book ai didi

python - 如何按递增顺序(按中值)对箱线图值进行排序?

转载 作者:太空宇宙 更新时间:2023-11-04 09:36:47 25 4
gpt4 key购买 nike

这是我的 Pandas 数据框:

Area            Gender  Quantity
XXX Men 115
XXX Men 105
XXX Men 114
YYY Men 100
YYY Men 90
YYY Men 95
YYY Men 101
XXX Women 120
XXX Women 122
XXX Women 115
XXX Women 117
YYY Women 91
YYY Women 90
YYY Women 90

这就是我创建箱形图的方式。

import seaboard as sns
import matplotlib.pyplot as pat

fig, ax = plt.subplots(figsize=(15,11))
ax = sns.boxplot(x="Area", y="Quantity", hue="Gender", data=df, palette="Set3")

我想按中位数 Quantity 以升序对 Area 组进行排序。我该怎么做?

最佳答案

这对于当前版本的 seaborn (<=0.9.0) 是不可能的。您目前可以做的最好的事情是设置 hue_order(例如:['Woman', 'Men']),但它适用于所有组同样,这不是您想要的。

此外,扩展 boxplot() 并不是那么简单,因为 seaborn 没有在官方 API 中公开负责绘图的类。参见 here the entry point to boxplot() (截至 2018 年 10 月 20 日的 seaborn master 版本的永久链接,git hash:84ca6c6)。

如果您不惧怕使用内部 seaborn 对象,您可以创建自己的 sorted_boxplot() 版本。实现排序的最简单方法可能是修改 the following line_BoxPlotter.draw_boxplot()(固定链接,git:84ca6c6)中:

# Original
center = i + offsets[j]

# Fix:
ordered_offsets = ...
center = i + ordered_offsets[j]

center指的是箱线图的位置,i是组的索引,j是当前色调。我通过从 _BoxPlotter 派生并覆盖 draw_boxplot() 来测试它,请参阅下面的一些代码。

PS:如果有人对此进行详细说明以建议对 seaborn 提出拉取请求,那就太好了。该功能当然很有用。


以下对我有用(python 3.6,seaborn 0.9.0):

import numpy as np
import seaborn as sns
from seaborn.categorical import _BoxPlotter
from seaborn.utils import remove_na

class SortedBoxPlotter(_BoxPlotter):
def __init__(self, *args, **kwargs):
super(SortedBoxPlotter, self).__init__(*args, **kwargs)

def draw_boxplot(self, ax, kws):
'''
Below code has been copied partly from seaborn.categorical.py
and is reproduced only for educational purposes.
'''
if self.plot_hues is None:
# Sorting by hue doesn't apply here. Just
return super(SortedBoxPlotter, self).draw_boxplot(ax, kws)

vert = self.orient == "v"
props = {}
for obj in ["box", "whisker", "cap", "median", "flier"]:
props[obj] = kws.pop(obj + "props", {})

for i, group_data in enumerate(self.plot_data):

# ==> Sort offsets by median
offsets = self.hue_offsets
medians = [ np.median(group_data[self.plot_hues[i] == h])
for h in self.hue_names ]
offsets_sorted = offsets[np.argsort(medians)]

# Draw nested groups of boxes
for j, hue_level in enumerate(self.hue_names):

# Add a legend for this hue level
if not i:
self.add_legend_data(ax, self.colors[j], hue_level)

# Handle case where there is data at this level
if group_data.size == 0:
continue

hue_mask = self.plot_hues[i] == hue_level
box_data = remove_na(group_data[hue_mask])

# Handle case where there is no non-null data
if box_data.size == 0:
continue

# ==> Fix ordering
center = i + offsets_sorted[j]

artist_dict = ax.boxplot(box_data,
vert=vert,
patch_artist=True,
positions=[center],
widths=self.nested_width,
**kws)
self.restyle_boxplot(artist_dict, self.colors[j], props)

def sorted_boxplot(x=None, y=None, hue=None, data=None, order=None, hue_order=None,
orient=None, color=None, palette=None, saturation=.75,
width=.8, dodge=True, fliersize=5, linewidth=None,
whis=1.5, notch=False, ax=None, **kwargs):

'''
Same as sns.boxplot(), except that nested groups of boxes are plotted by
increasing median.
'''

plotter = SortedBoxPlotter(x, y, hue, data, order, hue_order,
orient, color, palette, saturation,
width, dodge, fliersize, linewidth)
if ax is None:
ax = plt.gca()
kwargs.update(dict(whis=whis, notch=notch))
plotter.plot(ax, kwargs)
return ax

使用您的示例数据运行:

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame([ ["XXX", "Men" , 115],
["XXX", "Men" , 105 ],
["XXX", "Men" , 114],
["YYY", "Men" , 100],
["YYY", "Men" , 90 ],
["YYY", "Men" , 95],
["YYY", "Men" , 101],
["XXX", "Women", 120 ],
["XXX", "Women", 122],
["XXX", "Women", 115],
["XXX", "Women", 117 ],
["YYY", "Women", 91],
["YYY", "Women", 90],
["YYY", "Women", 90]],
columns = ["Area", "Gender", "Quantity"])
sorted_boxplot(x="Area", y="Quantity", hue="Gender", data=df, palette="Set3")
plt.show()

结果:

enter image description here

关于python - 如何按递增顺序(按中值)对箱线图值进行排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53390367/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com