diff --git a/packages/python/plotly/plotly/express/_core.py b/packages/python/plotly/plotly/express/_core.py index 635bd870b9..d89794a5a4 100644 --- a/packages/python/plotly/plotly/express/_core.py +++ b/packages/python/plotly/plotly/express/_core.py @@ -291,10 +291,21 @@ def make_trace_kwargs(args, trace_spec, trace_data, mapping_labels, sizeref): x = x.astype(int) / 10 ** 9 # convert to unix epoch seconds x_is_date = True elif x.dtype.type == np.object_: - x = x.astype(np.float64) - + try: + x = x.astype(np.float64) + except ValueError: + raise ValueError( + "Could not convert value of 'x' ('%s') into a numeric type. " + "If 'x' contains stringified dates, please convert to a datetime column." + % args["x"] + ) if y.dtype.type == np.object_: - y = y.astype(np.float64) + try: + y = y.astype(np.float64) + except ValueError: + raise ValueError( + "Could not convert value of 'y' into a numeric type." + ) if attr_value == "lowess": # missing ='drop' is the default value for lowess but not for OLS (None) diff --git a/packages/python/plotly/plotly/tests/test_core/test_px/test_trendline.py b/packages/python/plotly/plotly/tests/test_core/test_px/test_trendline.py index 6c767f1068..e908d7dee1 100644 --- a/packages/python/plotly/plotly/tests/test_core/test_px/test_trendline.py +++ b/packages/python/plotly/plotly/tests/test_core/test_px/test_trendline.py @@ -94,6 +94,13 @@ def test_no_slope_ols_trendline(): @pytest.mark.parametrize("mode", ["ols", "lowess"]) def test_trendline_on_timeseries(mode): df = px.data.stocks() + + with pytest.raises(ValueError) as err_msg: + px.scatter(df, x="date", y="GOOG", trendline=mode) + assert "Could not convert value of 'x' ('date') into a numeric type." in str( + err_msg.value + ) + df["date"] = pd.to_datetime(df["date"]) fig = px.scatter(df, x="date", y="GOOG", trendline=mode) assert len(fig.data) == 2