yhat/ggplot — pull request #325 by arnfred (2014-06-12 12:59:53+00:00)
Title: Reworked bar plot

## Rework of bar plot

I realize that @EricChiang just added another pull request for something similar here: https://github.com/yhat/ggplot/pull/324 so in light of that I'm putting this up here so that we might merge the two. The differences as I can see between the two patches are:
- Eric's add position="dodge" (mine doesn't)
- Mine fix problem with bar plots and facets and add custom label order

### It is now possible to:

- Stack bars of different colors. In fact this is the default behaviour
when a color of fill is specified (like R's ggplot)
- Reorder columns in a bar plot by adding a label parameter as so:
geom_bar(labels=["blip","blop","dyt","båt"]) as discussed here:
https://github.com/yhat/ggplot/issues/315
- Show only a select few of the columns (as above, just don't include
all possible x-values)
- Use bar plots when faceting (although faceting overwrites the
x-labels for some reason: https://github.com/yhat/ggplot/issues/319)
This addresses https://github.com/yhat/ggplot/issues/196

### In order to do this I had to make a few changes.

- Most importantly I added a method '_calculate_global' to stats.py. It
is not required to implement it in subclasses but for stat_bin it
makes it possible to read in all labels ahead of time and then when we
are processing separate groups fill the labels not represented with
0's.
- I added a new stat class 'stat_bar' which for simple x/y bar plots
(not histograms) take advantage of '_calculate_global' to deliver
consistent bar plots when using facets or when stacking colors
- I changed geom_bar to use stat_bar per default and geom_histogram to
use stat_bin. This differentiates the bar plot and the histogram in a
way that makes intuitive sense (I would think at least)
- I disabled sorting the x-axis by default to preserve user specified
label orders. As far as I can see only geom_area needs the x-axis to
be ordered. I've added code to sort the x-axis inside geom_area.

Examples
![facet_colors](https://cloud.githubusercontent.com/assets/1090038/3257734/9b69bf06-f230-11e3-91cc-3d4f91761a0f.png)
```python
gg = ggplot(diamonds, aes(x = 'clarity', fill = 'cut', color='cut')) +\
stat_bin(binwidth=1200) + facet_wrap("color")
assert_same_ggplot(gg, "facet_colors")
```

![labels_manual](https://cloud.githubusercontent.com/assets/1090038/3257744/afc31ccc-f230-11e3-925c-33ec06cce9ae.png)
```python
df = pd.DataFrame({ "y" : [3.362, 1.2, 3.424, 2.574, 0.679],
"x" : ["BF","BF","Flann","FastMatch","FastMatch2"],
"c" : ["a", "b", "a", "a","a"]})
p = ggplot(df, aes(x = 'x', y = 'y', fill="c"))
gg2 = p + geom_bar(stat="bar", labels=["BF","Flann","FastMatch"])
assert_same_ggplot(gg2, "labels_manual")
```

![faceting_grid_discrete](https://cloud.githubusercontent.com/assets/1090038/3257764/fef401e4-f230-11e3-856b-205c9d74acfd.png)
```python
df = pd.DataFrame({
"x": np.arange(0, 10),
"y": np.arange(0, 10),
"z": np.arange(0, 10),
"a": [1,1,1,1,1,2,2,2,3,3],
"b": ["a","a","a","a","a","b","b","b","c","c"]
})
df['facets'] = np.where(df.x > 4, 'over', 'under')
df['facets2'] = np.where((df.x % 2) == 0, 'even', 'uneven')
df = _build_testing_df()
gg = ggplot(aes(x='a', y='y', fill='y'), data=df)
assert_same_ggplot(gg + geom_bar() + facet_grid(x="facets", y="facets2"),
"faceting_grid_discrete")
```
(from https://github.com/yhat/ggplot/issues/196 but modified to show color)