Skip to content

Commit 477b88f

Browse files
authored
Merge pull request #4914 from MarcoGorelli/fix-timeline
fix: px.timeline was raising when x_start and/or x_end were already datetime for Polars / PyArrow
2 parents a5e628c + ba09922 commit 477b88f

File tree

2 files changed

+41
-10
lines changed

2 files changed

+41
-10
lines changed

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

+15-10
Original file line numberDiff line numberDiff line change
@@ -2118,16 +2118,21 @@ def process_dataframe_timeline(args):
21182118
if args["x_start"] is None or args["x_end"] is None:
21192119
raise ValueError("Both x_start and x_end are required")
21202120

2121-
try:
2122-
df: nw.DataFrame = args["data_frame"]
2123-
df = df.with_columns(
2124-
nw.col(args["x_start"]).str.to_datetime().alias(args["x_start"]),
2125-
nw.col(args["x_end"]).str.to_datetime().alias(args["x_end"]),
2126-
)
2127-
except Exception:
2128-
raise TypeError(
2129-
"Both x_start and x_end must refer to data convertible to datetimes."
2130-
)
2121+
df: nw.DataFrame = args["data_frame"]
2122+
schema = df.schema
2123+
to_convert_to_datetime = [
2124+
col
2125+
for col in [args["x_start"], args["x_end"]]
2126+
if schema[col] != nw.Datetime and schema[col] != nw.Date
2127+
]
2128+
2129+
if to_convert_to_datetime:
2130+
try:
2131+
df = df.with_columns(nw.col(to_convert_to_datetime).str.to_datetime())
2132+
except Exception as exc:
2133+
raise TypeError(
2134+
"Both x_start and x_end must refer to data convertible to datetimes."
2135+
) from exc
21312136

21322137
# note that we are not adding any columns to the data frame here, so no risk of overwrite
21332138
args["data_frame"] = df.with_columns(

packages/python/plotly/plotly/tests/test_optional/test_px/test_px_functions.py

+26
Original file line numberDiff line numberDiff line change
@@ -561,3 +561,29 @@ def test_timeline(constructor):
561561
msg = "Both x_start and x_end must refer to data convertible to datetimes."
562562
with pytest.raises(TypeError, match=msg):
563563
px.timeline(df, x_start="Start", x_end=["a", "b", "c"], y="Task", color="Task")
564+
565+
566+
@pytest.mark.parametrize(
567+
"datetime_columns",
568+
[
569+
["Start"],
570+
["Start", "Finish"],
571+
["Finish"],
572+
],
573+
)
574+
def test_timeline_cols_already_temporal(constructor, datetime_columns):
575+
# https://github.com/plotly/plotly.py/issues/4913
576+
data = {
577+
"Task": ["Job A", "Job B", "Job C"],
578+
"Start": ["2009-01-01", "2009-03-05", "2009-02-20"],
579+
"Finish": ["2009-02-28", "2009-04-15", "2009-05-30"],
580+
}
581+
df = (
582+
nw.from_native(constructor(data))
583+
.with_columns(nw.col(datetime_columns).str.to_datetime(format="%Y-%m-%d"))
584+
.to_native()
585+
)
586+
fig = px.timeline(df, x_start="Start", x_end="Finish", y="Task", color="Task")
587+
assert len(fig.data) == 3
588+
assert fig.layout.xaxis.type == "date"
589+
assert fig.layout.xaxis.title.text is None

0 commit comments

Comments
 (0)