pandas 更改使用 seaborn.factorplot 创建的条形图中条的宽度

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34888058/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 00:32:12  来源:igfitidea点击:

Changing width of bars in bar chart created using seaborn.factorplot

pythonpandasmatplotlib

提问by kaleshanagineni

I'm trying to create bar chart using seaborn.factorplot. My code looks like this:

我正在尝试使用 seaborn.factorplot 创建条形图。我的代码如下所示:

 import seaborn
 import matplotlib.pyplot as plt 

df=pd.read_csv('data.csv')

 fg = seaborn.factorplot(x='vesselID', y='dur_min', hue='route', size=6,aspect=2    ,kind='bar', data=df)

my data.csvlooks like this

我的data.csv看起来像这样

 ,route,vesselID,dur_min
 0,ANA-SJ,13,39.357894736842105
 1,ANA-SJ,20,24.747663551401867
 2,ANA-SJ,38,33.72142857142857
 3,ANA-SJ,69,37.064516129032256
 4,ED-KING,30,22.10062893081761
 5,ED-KING,36,21.821428571428573
 6,ED-KING,68,23.396551724137932
 7,F-V-S,1,13.623239436619718
 8,F-V-S,28,14.31294964028777
 9,F-V-S,33,16.161616161616163
 10,MUK-CL,18,13.953191489361702
 11,MUK-CL,19,14.306513409961687
 12,PD-TAL,65,12.477272727272727
 13,PT-COU,52,27.48148148148148
 14,PT-COU,66,28.24778761061947
 15,SEA-BI,25,30.94267515923567
 16,SEA-BI,32,31.0
 17,SEA-BI,37,31.513513513513512
 18,SEA-BR,2,55.8
 19,SEA-BR,13,57.0
 20,SEA-BR,15,54.05434782608695
 21,SEA-BR,17,50.43859649122807

please click here to see the output

请点击这里查看输出

Now my question is how to change the width of the bar and I'm not able to achieve this by changing size and aspect.

现在我的问题是如何改变条的宽度,我无法通过改变大小和方面来实现这一点。

回答by jsgounot

In fact, you can do it using directly the patches attributes with the function set_width. However if you only do that, you will just modify your patches width but not the position on the axe, so you have to change the x coordinates too.

事实上,您可以直接使用带有功能的补丁属性来完成set_width。但是,如果您只这样做,您将只修改补丁宽度而不是轴上的位置,因此您也必须更改 x 坐标。

import pylab as plt
import seaborn as sns

tips = sns.load_dataset("tips")
fig, ax = plt.subplots()

sns.barplot(data=tips, ax=ax, x="time", y="tip", hue="sex")

def change_width(ax, new_value) :
    for patch in ax.patches :
        current_width = patch.get_width()
        diff = current_width - new_value

        # we change the bar width
        patch.set_width(new_value)

        # we recenter the bar
        patch.set_x(patch.get_x() + diff * .5)

change_width(ax, .35)
plt.show()

And here is the result : barplot result

这是结果: 条形图结果

回答by tsando

In my case, I didn't have to define a custom function to change the width as suggested above (which btw didn't work for me as all the bars were unaligned). I simply added the attribute dodge=Falseto the argument of the seaborn plotting function and this made the trick! e.g.

就我而言,我不必定义自定义函数来更改上述建议的宽度(顺便说一句,这对我不起作用,因为所有条形都未对齐)。我只是将属性添加dodge=False到 seaborn 绘图函数的参数中,这就成功了!例如

sns.countplot(x='x', hue='y', data=data, dodge=False);

See additional reference here: https://github.com/mwaskom/seaborn/issues/871

在此处查看其他参考:https: //github.com/mwaskom/seaborn/issues/871

My bar plot looks now like this:

我的条形图现在看起来像这样:

enter image description here

在此处输入图片说明

回答by cphlewis

I don't think seaborn will do this, but it's possible mwaskom will come verify.

我不认为 seaborn 会这样做,但 mwaskom 可能会来验证。

First, the general way to tweak matplotlib calls in seaborn is to pass through more kwargs (or in some cases a dict thereof), which would change your code like this:

首先,在 seaborn 中调整 matplotlib 调用的一般方法是通过更多的 kwargs(或在某些情况下是其中的 dict),这会像这样改变你的代码:

fg = seaborn.factorplot(x='vesselID', y='dur_min', hue='route',
                        size=6,  aspect=2,
                        kind='bar', 
                        width=10, # Factorplot passes arguments through
                        data=df)

but when I run that the error is:

但是当我运行时,错误是:

TypeError: bar() got multiple values for keyword argument 'width'

类型错误:bar() 为关键字参数“width”获得了多个值

and, yes, it turns out all the seaborn categorical comparisons define widthand build a lot of the aesthetics around it. You can check the draw_barsfunction in categorical.pydirectly, and of course you couldedit your own copy of categorical.py, but that part of seaborn's style is currently baked in.

而且,是的,事实证明,所有的 seaborn 分类比较都width围绕它定义和构建了许多美学。您可以直接draw_barscategorical.py 中查看该函数,当然您也可以编辑自己的 categorical.py 副本,但是目前seaborn 风格的那部分已被烘焙。

回答by Yuchao Jiang

seaborn is a higher level library above matplotlib. While seaborn doesn't have the flexibility to control bar width, matplotlib can do it with one line of code:

seaborn 是高于 matplotlib 的更高级别的库。虽然 seaborn 没有控制条宽的灵活性,但 matplotlib 可以用一行代码来完成:

plt.bar(data.xcol,data.ycol,4)

plt.bar(data.xcol,data.ycol,4)

回答by Jed

This is a slight modification of @jsgounot's answer, which I found very instructive. The modification helps to center the bars on the appropriate xtick.

这是对@jsgounot 的回答的轻微修改,我觉得这很有启发性。修改有助于在适当的 xtick 上将条形居中。

def change_width(ax, new_value) :
    locs = ax.get_xticks()
    for i,patch in enumerate(ax.patches):
        current_width = patch.get_width()
        diff = current_width - new_value

        # we change the bar width
        patch.set_width(new_value)

        # we recenter the bar
        patch.set_x(locs[i//4] - (new_value * .5))