Skip to content

Commit b2ede23

Browse files
wip
1 parent 444a394 commit b2ede23

File tree

1 file changed

+38
-33
lines changed
  • packages/python/plotly/plotly/express

1 file changed

+38
-33
lines changed

Diff for: packages/python/plotly/plotly/express/_core.py

+38-33
Original file line numberDiff line numberDiff line change
@@ -887,53 +887,35 @@ def build_dataframe(args, attrables, array_attrables, constructor):
887887
array_attrables : list
888888
argument names corresponding to iterables, such as `hover_data`, ...
889889
"""
890+
891+
# make copies of all the fields via dict() and list()
890892
for field in args:
891893
if field in array_attrables and args[field] is not None:
892894
args[field] = (
893895
dict(args[field])
894896
if isinstance(args[field], dict)
895897
else list(args[field])
896898
)
899+
897900
# Cast data_frame argument to DataFrame (it could be a numpy array, dict etc.)
898901
df_provided = args["data_frame"] is not None
899902
if df_provided and not isinstance(args["data_frame"], pd.DataFrame):
900903
args["data_frame"] = pd.DataFrame(args["data_frame"])
901904

902-
wide_traces = [go.Scatter, go.Bar, go.Violin, go.Box, go.Histogram]
903-
has_x = args.get("x", None) is not None
904-
has_y = args.get("y", None) is not None
905-
if not has_x and not has_y and df_provided and constructor in wide_traces:
906-
index_name = args["data_frame"].index.name or "index"
907-
id_vars = [index_name]
908-
# TODO multi-level index
909-
# TODO multi-level columns
910-
# TODO orientation
911-
912-
# TODO do we need to add everything to this candidate list basically? array_attrables?
913-
# TODO will we need to be able to glue in non-string values here, like arrays and stuff?
914-
# ...like maybe this needs to run after we've glued together the data frame?
915-
for candidate in ["color", "symbol", "line_dash", "facet_row", "facet_col"] + [
916-
"line_group",
917-
"animation_group",
918-
]:
919-
if args.get(candidate, None) not in [None, index_name, "value", "variable"]:
920-
id_vars.append(args[candidate])
921-
args["data_frame"] = args["data_frame"].reset_index().melt(id_vars=id_vars)
922-
if constructor in [go.Scatter, go.Bar]:
923-
args["x"] = index_name
924-
args["y"] = "value"
925-
args["color"] = args["color"] or "variable"
926-
if constructor in [go.Violin, go.Box]:
927-
args["x"] = "variable"
928-
args["y"] = "value"
929-
if constructor in [go.Histogram]:
930-
args["x"] = "value"
931-
args["color"] = args["color"] or "variable"
932-
933905
df_input = args["data_frame"]
934906

935-
# We start from an empty DataFrame
936-
df_output = pd.DataFrame()
907+
wide_mode = (
908+
df_provided
909+
and args.get("x", None) is None
910+
and args.get("y", None) is None
911+
and constructor in [go.Scatter, go.Bar, go.Violin, go.Box, go.Histogram]
912+
)
913+
wide_id_vars = set()
914+
915+
if wide_mode:
916+
df_output = df_input
917+
else:
918+
df_output = pd.DataFrame()
937919

938920
# Initialize set of column names
939921
# These are reserved names
@@ -1063,6 +1045,29 @@ def build_dataframe(args, attrables, array_attrables, constructor):
10631045
args[field_name] = str(col_name)
10641046
else:
10651047
args[field_name][i] = str(col_name)
1048+
wide_id_vars.add(str(col_name))
1049+
1050+
if wide_mode:
1051+
# TODO multi-level index
1052+
# TODO multi-level columns
1053+
index_name = df_output.index.name or "index"
1054+
wide_id_vars.add(index_name)
1055+
if index_name not in df_output.columns:
1056+
df_output = df_output.reset_index()
1057+
df_output = df_output.melt(id_vars=wide_id_vars)
1058+
orient_v = "v" == (args.get("orientation", None) or "v")
1059+
if "orientation" in args:
1060+
args["orientation"] = "v" if orient_v else "h"
1061+
if constructor in [go.Scatter, go.Bar]:
1062+
args["x" if orient_v else "y"] = index_name
1063+
args["y" if orient_v else "x"] = "value"
1064+
args["color"] = args["color"] or "variable"
1065+
if constructor in [go.Violin, go.Box]:
1066+
args["x" if orient_v else "y"] = "variable"
1067+
args["y" if orient_v else "x"] = "value"
1068+
if constructor in [go.Histogram]:
1069+
args["x" if orient_v else "y"] = "value"
1070+
args["color"] = args["color"] or "variable"
10661071

10671072
args["data_frame"] = df_output
10681073
return args

0 commit comments

Comments
 (0)