Repository: mwaskom/seaborn

Issue:
Barplot - cannot override width
**Version:** 
0.11.1

**OS:**
Ubuntu

**Description:**
When calling `barplot(..., width=width)` a `TypeError` is raised from `matplotlib`:
`TypeError: bar() got multiple values for argument 'width'`

I think `barplot()` should either:
- raise before reaching `matplotlib` explaining why `width` cannot be overridden if there's a good reason
- allow overriding and pass the new value to `matplotlib`

This goes for the other `kwargs` accepted by `matplotlib` as well, of course.

Discussion:
codecov[bot]: # [Codecov](https://codecov.io/gh/mwaskom/seaborn/pull/2860?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Michael+Waskom) Report
> Merging [#2860](https://codecov.io/gh/mwaskom/seaborn/pull/2860?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Michael+Waskom) (6136338) into [master](https://codecov.io/gh/mwaskom/seaborn/commit/a48dc8f4df8d81ff8b50bdf26b6c094333f6ea8d?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Michael+Waskom) (a48dc8f) will **increase** coverage by `0.00%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/mwaskom/seaborn/pull/2860/graphs/tree.svg?width=650&height=150&src=pr&token=SLuzHnA9Bl&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Michael+Waskom)](https://codecov.io/gh/mwaskom/seaborn/pull/2860?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Michael+Waskom)

```diff
@@           Coverage Diff           @@
##           master    #2860   +/-   ##
=======================================
  Coverage   98.11%   98.12%           
=======================================
  Files          69       69           
  Lines       22247    22249    +2     
=======================================
+ Hits        21828    21831    +3     
+ Misses        419      418    -1     
```


| [Impacted Files](https://codecov.io/gh/mwaskom/seaborn/pull/2860?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Michael+Waskom) | Coverage Δ | |
|---|---|---|
| [seaborn/categorical.py](https://codecov.io/gh/mwaskom/seaborn/pull/2860/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Michael+Waskom#diff-c2VhYm9ybi9jYXRlZ29yaWNhbC5weQ==) | `98.62% <100.00%> (+0.07%)` | :arrow_up: |
| [tests/test\_categorical.py](https://codecov.io/gh/mwaskom/seaborn/pull/2860/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Michael+Waskom#diff-dGVzdHMvdGVzdF9jYXRlZ29yaWNhbC5weQ==) | `99.77% <100.00%> (+<0.01%)` | :arrow_up: |


Patch:
diff --git a/doc/releases/v0.12.0.txt b/doc/releases/v0.12.0.txt
index 77b3b5b6..4711ecaa 100644
--- a/doc/releases/v0.12.0.txt
+++ b/doc/releases/v0.12.0.txt
@@ -51,6 +51,8 @@ Other updates
 
 - |Enhancement| Example datasets are now stored in an OS-specific cache location (as determined by `appdirs`) rather than in the user's home directory. Users should feel free to remove `~/seaborn-data` if desired (:pr:`2773`).
 
+- |Enhancement| Added a `width` parameter to :func:`barplot` (:pr:`2860`).
+
 - |Enhancement| Error bars in :func:`regplot` now inherit the alpha value of the points they correspond to (:pr:`2540`).
 
 - |Enhancement| When using :func:`pairplot` with `corner=True` and `diag_kind=None`, the top left y axis label is no longer hidden (:pr:2850`).
diff --git a/seaborn/categorical.py b/seaborn/categorical.py
index d8d2b581..3b69c855 100644
--- a/seaborn/categorical.py
+++ b/seaborn/categorical.py
@@ -1576,8 +1576,8 @@ class _BarPlotter(_CategoricalStatPlotter):
 
     def __init__(self, x, y, hue, data, order, hue_order,
                  estimator, ci, n_boot, units, seed,
-                 orient, color, palette, saturation, errcolor,
-                 errwidth, capsize, dodge):
+                 orient, color, palette, saturation, width,
+                 errcolor, errwidth, capsize, dodge):
         """Initialize the plotter."""
         self.establish_variables(x, y, hue, data, orient,
                                  order, hue_order, units)
@@ -1585,6 +1585,7 @@ class _BarPlotter(_CategoricalStatPlotter):
         self.estimate_statistic(estimator, ci, n_boot, seed)
 
         self.dodge = dodge
+        self.width = width
 
         self.errcolor = errcolor
         self.errwidth = errwidth
@@ -2743,7 +2744,7 @@ swarmplot.__doc__ = dedent("""\
 def barplot(
     data=None, *, x=None, y=None, hue=None, order=None, hue_order=None,
     estimator=np.mean, ci=95, n_boot=1000, units=None, seed=None,
-    orient=None, color=None, palette=None, saturation=.75,
+    orient=None, color=None, palette=None, saturation=.75, width=.8,
     errcolor=".26", errwidth=None, capsize=None, dodge=True,
     ax=None,
     **kwargs,
@@ -2752,7 +2753,7 @@ def barplot(
     plotter = _BarPlotter(x, y, hue, data, order, hue_order,
                           estimator, ci, n_boot, units, seed,
                           orient, color, palette, saturation,
-                          errcolor, errwidth, capsize, dodge)
+                          width, errcolor, errwidth, capsize, dodge)
 
     if ax is None:
         ax = plt.gca()
@@ -2793,6 +2794,7 @@ barplot.__doc__ = dedent("""\
     {color}
     {palette}
     {saturation}
+    {width}
     errcolor : matplotlib color
         Color used for the error bar lines.
     {errwidth}
@@ -2910,7 +2912,7 @@ pointplot.__doc__ = dedent("""\
 
 def countplot(
     data=None, *, x=None, y=None, hue=None, order=None, hue_order=None,
-    orient=None, color=None, palette=None, saturation=.75,
+    orient=None, color=None, palette=None, saturation=.75, width=.8,
     dodge=True, ax=None, **kwargs
 ):
 
@@ -2936,7 +2938,7 @@ def countplot(
         x, y, hue, data, order, hue_order,
         estimator, ci, n_boot, units, seed,
         orient, color, palette, saturation,
-        errcolor, errwidth, capsize, dodge
+        width, errcolor, errwidth, capsize, dodge
     )
 
     plotter.value_label = "count"


Test patch:
diff --git a/tests/test_categorical.py b/tests/test_categorical.py
index fac45672..70554b3c 100644
--- a/tests/test_categorical.py
+++ b/tests/test_categorical.py
@@ -2203,26 +2203,27 @@ class TestBarPlotter(CategoricalFixture):
         estimator=np.mean, ci=95, n_boot=100, units=None, seed=None,
         order=None, hue_order=None,
         orient=None, color=None, palette=None,
-        saturation=.75, errcolor=".26", errwidth=None,
+        saturation=.75, width=0.8,
+        errcolor=".26", errwidth=None,
         capsize=None, dodge=True
     )
 
     def test_nested_width(self):
 
-        kws = self.default_kws.copy()
+        ax = cat.barplot(data=self.df, x="g", y="y", hue="h")
+        for bar in ax.patches:
+            assert bar.get_width() == pytest.approx(.8 / 2)
+        ax.clear()
 
-        p = cat._BarPlotter(**kws)
-        p.establish_variables("g", "y", hue="h", data=self.df)
-        assert p.nested_width == .8 / 2
-
-        p = cat._BarPlotter(**kws)
-        p.establish_variables("h", "y", "g", data=self.df)
-        assert p.nested_width == .8 / 3
+        ax = cat.barplot(data=self.df, x="g", y="y", hue="g", width=.5)
+        for bar in ax.patches:
+            assert bar.get_width() == pytest.approx(.5 / 3)
+        ax.clear()
 
-        kws["dodge"] = False
-        p = cat._BarPlotter(**kws)
-        p.establish_variables("h", "y", "g", data=self.df)
-        assert p.nested_width == .8
+        ax = cat.barplot(data=self.df, x="g", y="y", hue="g", dodge=False)
+        for bar in ax.patches:
+            assert bar.get_width() == pytest.approx(.8)
+        ax.clear()
 
     def test_draw_vertical_bars(self):