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

时间:2016-01-19 22:20:12

标签: python pandas matplotlib

我正在尝试使用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)

我的 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

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

6 个答案:

答案 0 :(得分:15)

就我而言,我不必定义自定义函数来更改宽度(如前所述)(由于所有条形都未对齐,因此btw对我不起作用)。我只是将属性dodge=False添加到了seaborn绘图函数的参数中,就成功了!例如

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

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

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

enter image description here

答案 1 :(得分:8)

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.

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

答案 2 :(得分:0)

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

首先,在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)

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

  

TypeError:bar()获得了关键字参数' width'

的多个值

并且,是的,事实证明所有的seaborn分类比较定义width并围绕它构建了许多美学。您可以直接查看categorical.py中的draw_bars功能,当然您可以编辑您自己的categorical.py副本,但是seaborn风格的那部分是目前正在烘焙。

答案 3 :(得分:0)

seaborn是matplotlib之上的更高级别的库。虽然seaborn不具备控制条宽度的灵活性,但matplotlib可以通过一行代码来实现:

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

答案 4 :(得分:0)

这是@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))

答案 5 :(得分:0)

另一种解决方案是修改box_aspect:

import pylab as plt
import seaborn as sns

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

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

ax.set_box_aspect(10/len(ax.patches)) #change 10 to modify the y/x axis ratio
plt.show()

enter image description here