如果色相中缺少类别,条形图中的中心条

Centre bars in barplots if category is missing in hue

如果在 seaborn 的条形图中使用 hue 并且其中一个类别丢失,则会导致“空列”的这种奇怪效果,其中 seaborn 在它期望色调的地方不绘制任何东西(见下面第二个位置,星期五;或在第二张图片中)。怎样才能使这些案例居中,使其位于刻度线的位置?在第一种情况下,它将位于橙色条的中间,在第二种情况下,它将删除蓝色和绿色之间的空白 space 并将刻度放置在绿色条的中间。 谢谢。

import seaborn

tips = sns.load_dataset("tips")
tips.loc[(tips["sex"]=="Male")&(tips["day"]=="Fri"), "total_bill"]=np.nan

sns.barplot(x="day", y="total_bill", hue="sex", data=tips)

sns.barplot(x="sex", y="total_bill", hue="day", data=tips)

旁注,与此无关

如@TrentonMcKinney 的评论中所述,following post 有一些手动解决方法(已更改和调整,另请注意颜色会保留,因为它不接触图形,只接触位置):

import seaborn
tips = sns.load_dataset("tips")
tips.loc[(tips["sex"]=="Male")&(tips["day"]=="Fri"), "total_bill"]=np.nan

plot1 = sns.barplot(x="day", y="total_bill", hue="sex", data=tips)

for i, bar in enumerate(plot1.axes.patches): 

    # move the missing to the centre
    current_width = bar.get_width()
    current_pos = bar.get_x()
    if i == 5:
        bar.set_x(current_pos-(current_width/2))
        # move also the std mark
        plot1.axes.lines[i].set_xdata(current_pos)


plot2 = sns.barplot(x="sex", y="total_bill", hue="day", data=tips)

for i, bar in enumerate(plot2.axes.patches): 

    # move the missing to the centre
    current_width = bar.get_width()
    current_pos = bar.get_x()
    if i == 0:
        bar.set_x(current_pos+(current_width/2))
        # get also the std mark
        plot2.axes.lines[i].set_xdata(current_pos+(current_width))
    
    if i == 4:
        bar.set_x(current_pos-(current_width/2))
        # get also the std mark
        plot2.axes.lines[i].set_xdata(current_pos)
    
    if i == 6:
        bar.set_x(current_pos-(current_width/2))
        # get also the std mark
        plot2.axes.lines[i].set_xdata(current_pos)    

还有更多工作要做(例如,还要处理 std 或找到正确的索引)但问题仍然存在——它填充了 space 以使其看起来更好但不会删除 space。但是,我相信这已经足够了。非常感谢@JohanC 和@TrentonMcKinney。