-
Notifications
You must be signed in to change notification settings - Fork 568
Description
- Update this SO question
geom_bar uses arbitrary numbers as x axis (so making a bar plot where '3' has two values in the dataset does not mean that the bar is on "3" but it starts at 0.2). This fails when each facet has different values, they are not arranged in similar ways: 1,2,3 - 1,3,4 - 1,4,5 -> all have their bars at 0.2, 1.2, 1,3 (real x axis, not labels shown).
This means that that when the labels are removed from the subplots during faceting, you neither can see what the real labels are for each bar, nor have gaps where there are no values (second facet -> there should be a gap at '2'). It gets worse as the current faceting code removes the tick labels and reorganizes them for all facets and so they get the names of the position (which is 0.2, 1.2, 2.2, ...) and the grid is not anymore nicely under the bar.
Code to see the mess:
def _build_testing_df():
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]
})
df['facets'] = np.where(df.x > 4, 'over', 'under')
df['facets2'] = np.where((df.x % 2) == 0, 'even', 'uneven')
return df
@cleanup
def test_facet_grid_descrete():
df = _build_testing_df()
gg = ggplot(aes(x='a'), data=df)
assert_same_ggplot(gg + geom_bar() + facet_grid(x="facets", y="facets2"),
"faceting_grid_descrete")
@cleanup
def test_facet_wrap_descrete():
df = _build_testing_df()
gg = ggplot(aes(x='a'), data=df)
assert_same_ggplot(gg + geom_bar() + facet_wrap(x="facets"), "faceting_wrap_descrete")
A a short term measure, I will add a warning at draw()
time if faceting and geom_bar are used together.
Longterm I think this needs some more thought, as the current system is designed so that each facet does not know the properties of all the other facets but in this case we would need to compute the labels beforehand and use them at all individual facets. If we do that it's proably best to turn that around for all types. An Idea could be to add a new method to all geoms which would do the necessary data transforms, so faceting would be:
for geom in geoms:
geom.do_faceting_transforms(...)
[old facets code, but pass in the faceting "hints"/transforms from above]