Skip to content

Commit 7e129b2

Browse files
align bar and histogram behaviours in wide mode with categorical values
1 parent b96f8c1 commit 7e129b2

File tree

2 files changed

+44
-5
lines changed

2 files changed

+44
-5
lines changed

packages/python/plotly/plotly/express/_core.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,13 +1114,13 @@ def build_dataframe(args, constructor):
11141114

11151115
if missing_bar_dim and constructor == go.Bar:
11161116
# now that we've populated df_output, we check to see if the non-missing
1117-
# dimensio is categorical: if so, then setting the missing dimension to a
1117+
# dimension is categorical: if so, then setting the missing dimension to a
11181118
# constant 1 is a less-insane thing to do than setting it to the index by
11191119
# default and we let the normal auto-orientation-code do its thing later
11201120
other_dim = "x" if missing_bar_dim == "y" else "y"
11211121
if not _is_continuous(df_output, args[other_dim]):
1122-
args[missing_bar_dim] = missing_bar_dim
1123-
constants[missing_bar_dim] = 1
1122+
args[missing_bar_dim] = "_count_"
1123+
constants["_count_"] = 1
11241124
else:
11251125
# on the other hand, if the non-missing dimension is continuous, then we
11261126
# can use this information to override the normal auto-orientation code
@@ -1146,14 +1146,24 @@ def build_dataframe(args, constructor):
11461146
df_output[var_name] = df_output[var_name].astype(str)
11471147
args["orientation"] = args.get("orientation", None) or "v"
11481148
orient_v = args["orientation"] == "v"
1149-
if constructor in [go.Scatter, go.Bar]:
1149+
if constructor == go.Scatter:
11501150
args["x" if orient_v else "y"] = index_name
11511151
args["y" if orient_v else "x"] = "_value_"
11521152
args["color"] = args["color"] or var_name
1153+
if constructor == go.Bar:
1154+
if _is_continuous(df_output, "_value_"):
1155+
args["x" if orient_v else "y"] = index_name
1156+
args["y" if orient_v else "x"] = "_value_"
1157+
args["color"] = args["color"] or var_name
1158+
else:
1159+
args["x" if orient_v else "y"] = "_value_"
1160+
args["y" if orient_v else "x"] = "_count_"
1161+
df_output["_count_"] = 1
1162+
args["color"] = args["color"] or var_name
11531163
if constructor in [go.Violin, go.Box]:
11541164
args["x" if orient_v else "y"] = var_name
11551165
args["y" if orient_v else "x"] = "_value_"
1156-
if constructor in [go.Histogram]:
1166+
if constructor == go.Histogram:
11571167
args["x" if orient_v else "y"] = "_value_"
11581168
args["color"] = args["color"] or var_name
11591169

packages/python/plotly/plotly/tests/test_core/test_px/test_px_wide.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,35 @@ def test_wide_mode_internal(trace_type, x, y, color, orientation):
120120
assert args_out == dict(x=y, y=x, color=color, orientation="h")
121121

122122

123+
@pytest.mark.parametrize(
124+
"orientation", [None, "v", "h"],
125+
)
126+
def test_wide_mode_internal_bar_exception(orientation):
127+
df_in = pd.DataFrame(dict(a=["q", "r", "s"], b=["t", "u", "v"]), index=[11, 12, 13])
128+
args_in = dict(data_frame=df_in, color=None, orientation=orientation)
129+
args_out = build_dataframe(args_in, go.Bar)
130+
df_out = args_out.pop("data_frame")
131+
assert_frame_equal(
132+
df_out.sort_index(axis=1),
133+
pd.DataFrame(
134+
dict(
135+
index=[11, 12, 13, 11, 12, 13],
136+
_column_=["a", "a", "a", "b", "b", "b"],
137+
_value_=["q", "r", "s", "t", "u", "v"],
138+
_count_=[1, 1, 1, 1, 1, 1],
139+
)
140+
).sort_index(axis=1),
141+
)
142+
if orientation is None or orientation == "v":
143+
assert args_out == dict(
144+
x="_value_", y="_count_", color="_column_", orientation="v"
145+
)
146+
else:
147+
assert args_out == dict(
148+
x="_count_", y="_value_", color="_column_", orientation="h"
149+
)
150+
151+
123152
def test_wide_mode_internal_special_cases():
124153
# given all of the above tests, and given that the melt() code is not sensitive
125154
# to the trace type, we can do all sorts of special-case testing just by focusing

0 commit comments

Comments
 (0)