Skip to content

Commit

Permalink
Revert change to 1D wide data handling in categorical scatterplots
Browse files Browse the repository at this point in the history
  • Loading branch information
mwaskom committed Jun 2, 2022
1 parent dce3150 commit a01af81
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 24 deletions.
31 changes: 20 additions & 11 deletions seaborn/categorical.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ class _CategoricalPlotterNew(_RelationalPlotter):
semantics = "x", "y", "hue", "units"

wide_structure = {"x": "@columns", "y": "@values", "hue": "@columns"}
flat_structure = {"x": "@index", "y": "@values"}

# flat_structure = {"x": "@values", "y": "@values"}
flat_structure = {"y": "@values"}

_legend_func = "scatter"
_legend_attributes = ["color"]
Expand All @@ -69,6 +71,23 @@ def __init__(
# round of refactoring that moves the logic deeper, but this will keep things
# relatively sensible for now.

# For wide data, orient determines assignment to x/y differently from the
# wide_structure rules in _core. If we do decide to make orient part of the
# _core variable assignment, we'll want to figure out how to express that.
if self.input_format == "wide" and orient == "h":
self.plot_data = self.plot_data.rename(columns={"x": "y", "y": "x"})
orig_variables = set(self.variables)
orig_x = self.variables.pop("x", None)
orig_y = self.variables.pop("y", None)
orig_x_type = self.var_types.pop("x", None)
orig_y_type = self.var_types.pop("y", None)
if "x" in orig_variables:
self.variables["y"] = orig_x
self.var_types["y"] = orig_x_type
if "y" in orig_variables:
self.variables["x"] = orig_y
self.var_types["x"] = orig_y_type

# The concept of an "orientation" is important to the original categorical
# plots, but there's no provision for it in _core, so we need to do it here.
# Note that it could be useful for the other functions in at least two ways
Expand All @@ -87,16 +106,6 @@ def __init__(
if not self.has_xy_data:
return

# For wide data, orient determines assignment to x/y differently from the
# wide_structure rules in _core. If we do decide to make orient part of the
# _core variable assignment, we'll want to figure out how to express that.
if self.input_format == "wide" and self.orient == "h":
self.plot_data = self.plot_data.rename(columns={"x": "y", "y": "x"})
orig_x, orig_y = self.variables["x"], self.variables["y"]
self.variables.update({"x": orig_y, "y": orig_x})
orig_x_type, orig_y_type = self.var_types["x"], self.var_types["y"]
self.var_types.update({"x": orig_y_type, "y": orig_x_type})

# Categorical plots can be "univariate" in which case they get an anonymous
# category label on the opposite axis. Note: this duplicates code in the core
# scale_categorical function. We need to do it here because of the next line.
Expand Down
18 changes: 5 additions & 13 deletions seaborn/tests/test_categorical.py
Original file line number Diff line number Diff line change
Expand Up @@ -1723,22 +1723,14 @@ def test_flat(self, flat_series, orient):
ax = self.func(data=flat_series, orient=orient)
_draw_figure(ax.figure)

cat_idx = 0 if orient == "v" else 1
cat_idx = ["v", "h"].index(orient)
val_idx = int(not cat_idx)

axis_objs = ax.xaxis, ax.yaxis
cat_axis = axis_objs[cat_idx]

for i, label in enumerate(cat_axis.get_majorticklabels()):

points = ax.collections[i]
point_pos = points.get_offsets().T
val_pos = point_pos[val_idx]
cat_pos = point_pos[cat_idx]
points = ax.collections[0]
pos = points.get_offsets().T

key = int(label.get_text()) # because fixture has integer index
assert_array_equal(val_pos, flat_series[key])
assert_array_equal(cat_pos, i)
assert_array_equal(pos[cat_idx].round(), np.zeros(len(flat_series)))
assert_array_equal(pos[val_idx], flat_series)

@pytest.mark.parametrize(
"variables,orient",
Expand Down

0 comments on commit a01af81

Please sign in to comment.